mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-23 13:16:48 +08:00
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:
+3
-7
@@ -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 {
|
||||
|
||||
+27
-14
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user