GT-2926 remove special case matching for zlib headers in DMG filesystem

(#583).

Some pre-mac appstore DMGs contained zlib compressed payloads.  The
naive check for zlib enabled the DMG file system to catch those cases,
at the expense of false positives for other zlib content.

This commit stops the DMG file system from claiming zlib formatted
files.

Also fix unreleased filehandle in DmgDecryptorStream
This commit is contained in:
dev747368
2019-06-13 18:11:39 -04:00
parent 8dfffdd5db
commit b6c8c6be2b
2 changed files with 30 additions and 21 deletions
@@ -21,7 +21,6 @@ import java.io.IOException;
import generic.jar.ResourceFile;
import ghidra.app.util.bin.ByteProvider;
import ghidra.file.formats.xar.XARUtil;
import ghidra.file.formats.zlib.ZLIB;
import ghidra.formats.gfilesystem.*;
import ghidra.formats.gfilesystem.factory.GFileSystemFactoryWithFile;
import ghidra.formats.gfilesystem.factory.GFileSystemProbeFull;
@@ -46,7 +45,7 @@ public class DmgClientFileSystemFactory
@Override
public boolean probe(FSRL containerFSRL, ByteProvider byteProvider, File containerFile,
FileSystemService fsService, TaskMonitor taskMonitor)
throws IOException, CancelledException {
throws IOException, CancelledException {
if (!isDmgPresent()) {
return false;
@@ -56,9 +55,6 @@ public class DmgClientFileSystemFactory
if (XARUtil.isXAR(byteProvider)) {
return false;
}
if (ZLIB.isZLIB(byteProvider)) {
return true;
}
return isEncrypted(containerFile);
}
@@ -84,7 +80,7 @@ public class DmgClientFileSystemFactory
@Override
public DmgClientFileSystem create(FSRL containerFSRL, FSRLRoot targetFSRL, File containerFile,
FileSystemService fsService, TaskMonitor monitor)
throws IOException, CancelledException {
throws IOException, CancelledException {
String dmgName = containerFSRL.getName();
@@ -103,7 +99,7 @@ public class DmgClientFileSystemFactory
fsService.getDerivedFile(containerFSRL, "decrypted " + containerName, (srcFile) -> {
monitor.initialize(srcFile.length());
return new DmgDecryptorStream(containerName, dmgName, srcFile);
} , monitor);
}, monitor);
decrypted_dmg_file = fce.file;
}
else {
@@ -15,15 +15,15 @@
*/
package ghidra.file.formats.ios.dmg;
import java.io.*;
import java.util.Arrays;
import ghidra.app.util.bin.*;
import ghidra.file.crypto.*;
import ghidra.file.formats.ios.generic.iOS_AesCrypto;
import ghidra.file.formats.ios.generic.iOS_Sha1Crypto;
import ghidra.util.exception.CryptoException;
import java.io.*;
import java.util.Arrays;
/**
* An {@link InputStream} that decrypts a DMG file on the fly.
* <p>
@@ -76,19 +76,32 @@ public class DmgDecryptorStream extends InputStream {
public DmgDecryptorStream(String containerName, String dmgName, ByteProvider provider)
throws IOException {
try {
CryptoKey cryptoKey = CryptoKeyFactory.getCryptoKey(containerName, dmgName);
if (cryptoKey.key.length != 36) {
throw new CryptoException("Invalid key length.");
}
if (cryptoKey.iv.length != 0) {
throw new CryptoException("Invalid initialization vector (IV) length.");
}
aes_key = Arrays.copyOfRange(cryptoKey.key, 0, 16);
sha1_key = Arrays.copyOfRange(cryptoKey.key, 16, 16 + 20);
}
catch (IOException e) {
// Release the provider before this exception finishes since the #close() method can't
// be called later to release it.
try {
provider.close();
}
catch (IOException ioe) {
// ignore
}
throw e;
}
this.provider = provider;
CryptoKey cryptoKey = CryptoKeyFactory.getCryptoKey(containerName, dmgName);
if (cryptoKey.key.length != 36) {
throw new CryptoException("Invalid key length.");
}
if (cryptoKey.iv.length != 0) {
throw new CryptoException("Invalid initialization vector (IV) length.");
}
aes_key = Arrays.copyOfRange(cryptoKey.key, 0, 16);
sha1_key = Arrays.copyOfRange(cryptoKey.key, 16, 16 + 20);
sha1 = new iOS_Sha1Crypto(sha1_key);
BinaryReader reader = new BinaryReader(provider, false);