Support Confuser 1.6 r71742 methods decrypter

This commit is contained in:
de4dot 2012-08-02 11:12:20 +02:00
parent 8473253aa6
commit e1758ddbb0
4 changed files with 73 additions and 26 deletions

View File

@ -218,7 +218,7 @@ namespace de4dot.code.deobfuscators.Confuser {
} }
else if (memoryMethodsDecrypter != null && memoryMethodsDecrypter.Detected) { else if (memoryMethodsDecrypter != null && memoryMethodsDecrypter.Detected) {
memoryMethodsDecrypter.initialize(); memoryMethodsDecrypter.initialize();
if (!memoryMethodsDecrypter.decrypt(peImage, fileData, ref dumpedMethods)) if (!memoryMethodsDecrypter.decrypt(peImage, fileData))
return false; return false;
decrypted = true; decrypted = true;
} }

View File

@ -128,7 +128,7 @@ namespace de4dot.code.deobfuscators.Confuser {
simpleDeobfuscator.deobfuscate(initMethod); simpleDeobfuscator.deobfuscate(initMethod);
if (!findLKey0(initMethod, out lkey0)) if (!findLKey0(initMethod, out lkey0))
return false; return false;
if (!findKey0(initMethod, out key0)) if (!findKey0_v16_r71742(initMethod, out key0))
return false; return false;
if (!findKey1(initMethod, out key1)) if (!findKey1(initMethod, out key1))
return false; return false;
@ -329,7 +329,7 @@ namespace de4dot.code.deobfuscators.Confuser {
if (peImage.OptionalHeader.checkSum == 0) if (peImage.OptionalHeader.checkSum == 0)
return false; return false;
methodsData = decryptMethodsData(peImage); methodsData = decryptMethodsData_vXX(peImage);
dumpedMethods = decrypt(peImage, fileData); dumpedMethods = decrypt(peImage, fileData);
return dumpedMethods != null; return dumpedMethods != null;
} }

View File

@ -35,6 +35,7 @@ namespace de4dot.code.deobfuscators.Confuser {
v14_r58004, v14_r58004,
v14_r58564, v14_r58564,
v15a_r59014, v15a_r59014,
v16_r71742,
vXX, vXX,
} }
@ -74,6 +75,8 @@ namespace de4dot.code.deobfuscators.Confuser {
} }
else if (callsFileStreamCtor) else if (callsFileStreamCtor)
version = ConfuserVersion.v14_r58004; version = ConfuserVersion.v14_r58004;
else if (DotNetUtils.callsMethod(initMethod, "System.Int32 System.Object::GetHashCode()"))
version = ConfuserVersion.v16_r71742;
else else
version = ConfuserVersion.vXX; version = ConfuserVersion.vXX;
@ -109,6 +112,11 @@ namespace de4dot.code.deobfuscators.Confuser {
throw new ApplicationException("Could not find all decryption keys"); throw new ApplicationException("Could not find all decryption keys");
break; break;
case ConfuserVersion.v16_r71742:
if (!initializeKeys_v16_r71742())
throw new ApplicationException("Could not find all decryption keys");
break;
case ConfuserVersion.vXX: case ConfuserVersion.vXX:
if (!initializeKeys_vXX()) if (!initializeKeys_vXX())
throw new ApplicationException("Could not find all decryption keys"); throw new ApplicationException("Could not find all decryption keys");
@ -139,11 +147,31 @@ namespace de4dot.code.deobfuscators.Confuser {
return true; return true;
} }
bool initializeKeys_v16_r71742() {
simpleDeobfuscator.deobfuscate(initMethod);
if (!findLKey0(initMethod, out lkey0))
return false;
if (!findKey0_v16_r71742(initMethod, out key0))
return false;
if (!findKey2Key3(initMethod, out key2, out key3))
return false;
if (!findKey4(initMethod, out key4))
return false;
if (!findKey5(initMethod, out key5))
return false;
simpleDeobfuscator.deobfuscate(decryptMethod);
if (!findKey6(decryptMethod, out key6))
return false;
return true;
}
bool initializeKeys_vXX() { bool initializeKeys_vXX() {
simpleDeobfuscator.deobfuscate(initMethod); simpleDeobfuscator.deobfuscate(initMethod);
if (!findLKey0(initMethod, out lkey0)) if (!findLKey0(initMethod, out lkey0))
return false; return false;
if (!findKey0(initMethod, out key0)) if (!findKey0_v16_r71742(initMethod, out key0))
return false; return false;
if (!findKey1(initMethod, out key1)) if (!findKey1(initMethod, out key1))
return false; return false;
@ -232,21 +260,22 @@ namespace de4dot.code.deobfuscators.Confuser {
return false; return false;
} }
public bool decrypt(PeImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) { public bool decrypt(PeImage peImage, byte[] fileData) {
if (initMethod == null) if (initMethod == null)
return false; return false;
switch (version) { switch (version) {
case ConfuserVersion.v14_r57884: return decrypt_v14_r57884(peImage, fileData, ref dumpedMethods); case ConfuserVersion.v14_r57884: return decrypt_v14_r57884(peImage, fileData);
case ConfuserVersion.v14_r58004: return decrypt_v14_r58004(peImage, fileData, ref dumpedMethods); case ConfuserVersion.v14_r58004: return decrypt_v14_r58004(peImage, fileData);
case ConfuserVersion.v14_r58564: return decrypt_v14_r58004(peImage, fileData, ref dumpedMethods); case ConfuserVersion.v14_r58564: return decrypt_v14_r58004(peImage, fileData);
case ConfuserVersion.v15a_r59014:return decrypt_v15a_r59014(peImage, fileData, ref dumpedMethods); case ConfuserVersion.v15a_r59014:return decrypt_v15a_r59014(peImage, fileData);
case ConfuserVersion.vXX: return decrypt_vXX(peImage, fileData, ref dumpedMethods); case ConfuserVersion.v16_r71742: return decrypt_v16_r71742(peImage, fileData);
case ConfuserVersion.vXX: return decrypt_vXX(peImage, fileData);
default: throw new ApplicationException("Unknown version"); default: throw new ApplicationException("Unknown version");
} }
} }
bool decrypt_v14_r57884(PeImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) { bool decrypt_v14_r57884(PeImage peImage, byte[] fileData) {
methodsData = decryptMethodsData_v14_r57884(peImage, false); methodsData = decryptMethodsData_v14_r57884(peImage, false);
var reader = new BinaryReader(new MemoryStream(methodsData)); var reader = new BinaryReader(new MemoryStream(methodsData));
@ -293,12 +322,12 @@ namespace de4dot.code.deobfuscators.Confuser {
return decrypted; return decrypted;
} }
bool decrypt_v14_r58004(PeImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) { bool decrypt_v14_r58004(PeImage peImage, byte[] fileData) {
methodsData = decryptMethodsData_v14_r57884(peImage, false); methodsData = decryptMethodsData_v14_r57884(peImage, false);
return decryptImage_v14_r58004(peImage, fileData, ref dumpedMethods); return decryptImage_v14_r58004(peImage, fileData);
} }
bool decryptImage_v14_r58004(PeImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) { bool decryptImage_v14_r58004(PeImage peImage, byte[] fileData) {
var reader = new BinaryReader(new MemoryStream(methodsData)); var reader = new BinaryReader(new MemoryStream(methodsData));
reader.ReadInt16(); // sig reader.ReadInt16(); // sig
var writer = new BinaryWriter(new MemoryStream(fileData)); var writer = new BinaryWriter(new MemoryStream(fileData));
@ -317,20 +346,25 @@ namespace de4dot.code.deobfuscators.Confuser {
return true; return true;
} }
bool decrypt_v15a_r59014(PeImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) { bool decrypt_v15a_r59014(PeImage peImage, byte[] fileData) {
methodsData = decryptMethodsData_v14_r57884(peImage, true); methodsData = decryptMethodsData_v14_r57884(peImage, true);
return decryptImage_v14_r58004(peImage, fileData, ref dumpedMethods); return decryptImage_v14_r58004(peImage, fileData);
} }
bool decrypt_vXX(PeImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) { bool decrypt_v16_r71742(PeImage peImage, byte[] fileData) {
if (peImage.OptionalHeader.checkSum == 0) methodsData = decryptMethodsData_v16_r71742(peImage, getEncryptedHeaderOffset_v16_r71742(peImage.Sections));
return false; return decryptImage_v16_r71742(peImage, fileData);
methodsData = decryptMethodsData(peImage);
return decrypt_vXX(peImage, fileData);
} }
bool decrypt_vXX(PeImage peImage, byte[] fileData) { bool decrypt_vXX(PeImage peImage, byte[] fileData) {
if (peImage.OptionalHeader.checkSum == 0)
return false;
methodsData = decryptMethodsData_vXX(peImage);
return decryptImage_v16_r71742(peImage, fileData);
}
bool decryptImage_v16_r71742(PeImage peImage, byte[] fileData) {
var reader = new BinaryReader(new MemoryStream(methodsData)); var reader = new BinaryReader(new MemoryStream(methodsData));
reader.ReadInt16(); // sig reader.ReadInt16(); // sig
int numInfos = reader.ReadInt32(); int numInfos = reader.ReadInt32();

View File

@ -128,7 +128,7 @@ namespace de4dot.code.deobfuscators.Confuser {
return false; return false;
} }
protected static bool findKey0(MethodDefinition method, out uint key) { protected static bool findKey0_v16_r71742(MethodDefinition method, out uint key) {
var instrs = method.Body.Instructions; var instrs = method.Body.Instructions;
for (int i = 0; i + 5 < instrs.Count; i++) { for (int i = 0; i + 5 < instrs.Count; i++) {
i = findCallvirtReadUInt32(instrs, i); i = findCallvirtReadUInt32(instrs, i);
@ -316,12 +316,16 @@ namespace de4dot.code.deobfuscators.Confuser {
return ConfuserUtils.findCallMethod(instrs, index, Code.Callvirt, "System.UInt64 System.IO.BinaryReader::ReadUInt64()"); return ConfuserUtils.findCallMethod(instrs, index, Code.Callvirt, "System.UInt64 System.IO.BinaryReader::ReadUInt64()");
} }
protected byte[] decryptMethodsData(PeImage peImage) { protected byte[] decryptMethodsData_vXX(PeImage peImage) {
return decryptMethodsData_v16_r71742(peImage, getEncryptedHeaderOffset_vXX(peImage.Sections));
}
protected byte[] decryptMethodsData_v16_r71742(PeImage peImage, uint encryptedHeaderOffset) {
uint mdRva = peImage.OptionalHeader.checkSum ^ (uint)key0; uint mdRva = peImage.OptionalHeader.checkSum ^ (uint)key0;
if (peImage.rvaToOffset(mdRva) != peImage.Cor20Header.MetadataOffset) if (peImage.rvaToOffset(mdRva) != peImage.Cor20Header.MetadataOffset)
throw new ApplicationException("Invalid metadata rva"); throw new ApplicationException("Invalid metadata rva");
var reader = peImage.Reader; var reader = peImage.Reader;
reader.BaseStream.Position = getEncryptedHeaderOffset(peImage.Sections); reader.BaseStream.Position = encryptedHeaderOffset;
ulong checkSum = reader.ReadUInt64() ^ lkey0; ulong checkSum = reader.ReadUInt64() ^ lkey0;
reader.ReadInt32(); // strong name RVA reader.ReadInt32(); // strong name RVA
reader.ReadInt32(); // strong name len reader.ReadInt32(); // strong name len
@ -336,7 +340,16 @@ namespace de4dot.code.deobfuscators.Confuser {
return decrypted; return decrypted;
} }
uint getEncryptedHeaderOffset(IList<SectionHeader> sections) { protected uint getEncryptedHeaderOffset_v16_r71742(IList<SectionHeader> sections) {
for (int i = sections.Count - 1; i >= 0; i--) {
var section = sections[i];
if (section.displayName == ".confuse")
return section.pointerToRawData;
}
throw new ApplicationException("Could not find encrypted section");
}
uint getEncryptedHeaderOffset_vXX(IList<SectionHeader> sections) {
for (int i = sections.Count - 1; i >= 0; i--) { for (int i = sections.Count - 1; i >= 0; i--) {
var section = sections[i]; var section = sections[i];
if (getSectionNameHash(section) == (uint)key1) if (getSectionNameHash(section) == (uint)key1)