From 2a96ec9958c2c52df261d1d6b711e9d699f83f36 Mon Sep 17 00:00:00 2001 From: de4dot Date: Tue, 31 Jul 2012 17:17:16 +0200 Subject: [PATCH] Support Confuser 1.4 r58564 methods encrypter --- .../Confuser/MemoryMethodsDecrypter.cs | 47 ++++++++++++++++--- .../Confuser/MethodsDecrypterBase.cs | 39 ++++++++++++++- 2 files changed, 78 insertions(+), 8 deletions(-) diff --git a/de4dot.code/deobfuscators/Confuser/MemoryMethodsDecrypter.cs b/de4dot.code/deobfuscators/Confuser/MemoryMethodsDecrypter.cs index b6d05f69..60f01ec8 100644 --- a/de4dot.code/deobfuscators/Confuser/MemoryMethodsDecrypter.cs +++ b/de4dot.code/deobfuscators/Confuser/MemoryMethodsDecrypter.cs @@ -33,6 +33,7 @@ namespace de4dot.code.deobfuscators.Confuser { Unknown, v14_r57884, v14_r58004, + v14_r58564, vXX, } @@ -49,7 +50,8 @@ namespace de4dot.code.deobfuscators.Confuser { return false; if (type.Methods.Count != 3) return false; - if (DotNetUtils.getPInvokeMethod(type, "kernel32", "VirtualProtect") == null) + var virtProtect = DotNetUtils.getPInvokeMethod(type, "kernel32", "VirtualProtect"); + if (virtProtect == null) return false; if (!DotNetUtils.hasString(initMethod, "Broken file")) return false; @@ -59,6 +61,8 @@ namespace de4dot.code.deobfuscators.Confuser { if (!DotNetUtils.hasString(initMethod, "Module error")) version = ConfuserVersion.v14_r57884; + else if (virtProtect.IsPrivate) + version = ConfuserVersion.v14_r58564; else if (DotNetUtils.callsMethod(initMethod, "System.Void System.IO.FileStream::.ctor(System.String,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare)")) version = ConfuserVersion.v14_r58004; else @@ -76,6 +80,11 @@ namespace de4dot.code.deobfuscators.Confuser { case ConfuserVersion.v14_r58004: break; + case ConfuserVersion.v14_r58564: + if (!initializeKeys_v14_r58564()) + throw new ApplicationException("Could not find all decryption keys"); + break; + case ConfuserVersion.vXX: if (!initializeKeys_vXX()) throw new ApplicationException("Could not find all decryption keys"); @@ -86,6 +95,26 @@ namespace de4dot.code.deobfuscators.Confuser { } } + bool initializeKeys_v14_r58564() { + simpleDeobfuscator.deobfuscate(initMethod); + if (!findLKey0(initMethod, out lkey0)) + return false; + if (!findKey0_v14_r58564(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() { simpleDeobfuscator.deobfuscate(initMethod); if (!findLKey0(initMethod, out lkey0)) @@ -186,6 +215,7 @@ namespace de4dot.code.deobfuscators.Confuser { switch (version) { case ConfuserVersion.v14_r57884: return decrypt_v14_r57884(peImage, fileData, ref dumpedMethods); case ConfuserVersion.v14_r58004: return decrypt_v14_r58004(peImage, fileData, ref dumpedMethods); + case ConfuserVersion.v14_r58564: return decrypt_v14_r58004(peImage, fileData, ref dumpedMethods); case ConfuserVersion.vXX: return decrypt_vXX(peImage, fileData, ref dumpedMethods); default: throw new ApplicationException("Unknown version"); } @@ -212,7 +242,7 @@ namespace de4dot.code.deobfuscators.Confuser { byte[] decryptMethodsData_v14_r57884(PeImage peImage) { var reader = peImage.Reader; reader.BaseStream.Position = 0; - var md5SumData = reader.ReadBytes((int)peImage.OptionalHeader.checkSum); + var md5SumData = reader.ReadBytes((int)peImage.OptionalHeader.checkSum ^ (int)key0); int csOffs = (int)peImage.OptionalHeader.Offset + 0x40; md5SumData[csOffs] = 0; @@ -220,11 +250,11 @@ namespace de4dot.code.deobfuscators.Confuser { md5SumData[csOffs + 2] = 0; md5SumData[csOffs + 3] = 0; var md5Sum = DeobUtils.md5Sum(md5SumData); - ulong checkSum = reader.ReadUInt64(); + ulong checkSum = reader.ReadUInt64() ^ lkey0; if (checkSum != calcChecksum(md5SumData)) throw new ApplicationException("Invalid checksum. File has been modified."); - var iv = reader.ReadBytes(reader.ReadInt32()); - var encrypted = reader.ReadBytes(reader.ReadInt32()); + var iv = reader.ReadBytes(reader.ReadInt32() ^ (int)key2); + var encrypted = reader.ReadBytes(reader.ReadInt32() ^ (int)key3); var decrypted = decrypt(encrypted, iv, md5SumData); if (BitConverter.ToInt16(decrypted, 0) != 0x6FD6) throw new ApplicationException("Invalid magic"); @@ -233,16 +263,19 @@ namespace de4dot.code.deobfuscators.Confuser { bool decrypt_v14_r58004(PeImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) { methodsData = decryptMethodsData_v14_r57884(peImage); + return decryptImage_v14_r58004(peImage, fileData, ref dumpedMethods); + } + bool decryptImage_v14_r58004(PeImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) { var reader = new BinaryReader(new MemoryStream(methodsData)); reader.ReadInt16(); // sig var writer = new BinaryWriter(new MemoryStream(fileData)); int numInfos = reader.ReadInt32(); for (int i = 0; i < numInfos; i++) { - uint offs = reader.ReadUInt32(); + uint offs = reader.ReadUInt32() ^ key4; if (offs == 0) continue; - uint rva = reader.ReadUInt32(); + uint rva = reader.ReadUInt32() ^ key4; if (peImage.rvaToOffset(rva) != offs) throw new ApplicationException("Invalid offs & rva"); writer.BaseStream.Position = peImage.rvaToOffset(rva); diff --git a/de4dot.code/deobfuscators/Confuser/MethodsDecrypterBase.cs b/de4dot.code/deobfuscators/Confuser/MethodsDecrypterBase.cs index 1bfde7d2..957d91fa 100644 --- a/de4dot.code/deobfuscators/Confuser/MethodsDecrypterBase.cs +++ b/de4dot.code/deobfuscators/Confuser/MethodsDecrypterBase.cs @@ -74,8 +74,14 @@ namespace de4dot.code.deobfuscators.Confuser { if (instr.OpCode.Code != Code.Call) continue; var calledMethod = instr.Operand as MethodDefinition; - if (calledMethod == null || calledMethod.Body == null) + try { + // If the body is encrypted, this could throw + if (calledMethod == null || calledMethod.Body == null) + continue; + } + catch { continue; + } if (!DotNetUtils.isMethod(calledMethod, "System.Void", "()")) continue; if (!checkType(calledMethod.DeclaringType, calledMethod)) @@ -152,6 +158,37 @@ namespace de4dot.code.deobfuscators.Confuser { return false; } + protected static bool findKey0_v14_r58564(MethodDefinition method, out uint key) { + var instrs = method.Body.Instructions; + for (int i = 0; i + 5 < instrs.Count; i++) { + i = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Int32 System.IO.BinaryReader::ReadInt32()"); + if (i < 0) + break; + + int index = i + 1; + var ldci4_1 = instrs[index++]; + if (!DotNetUtils.isLdcI4(ldci4_1)) + continue; + if (instrs[index++].OpCode.Code != Code.Xor) + continue; + if (!DotNetUtils.isStloc(instrs[index++])) + continue; + if (!DotNetUtils.isLdloc(instrs[index++])) + continue; + var ldci4_2 = instrs[index++]; + if (!DotNetUtils.isLdcI4(ldci4_2)) + continue; + if (DotNetUtils.getLdcI4Value(ldci4_2) != 0) + continue; + + key = (uint)DotNetUtils.getLdcI4Value(ldci4_1); + return true; + } + + key = 0; + return false; + } + protected static bool findKey1(MethodDefinition method, out uint key) { var instrs = method.Body.Instructions; for (int index = 0; index < instrs.Count; index++) {