From 82dd08b348f49b3d7f3d9a85cb228f763bfbfae4 Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 3 Aug 2012 23:30:31 +0200 Subject: [PATCH] Support Confuser 1.7 r73479 methods encrypter --- .../Confuser/JitMethodsDecrypter.cs | 63 +++++++++++++++++-- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/de4dot.code/deobfuscators/Confuser/JitMethodsDecrypter.cs b/de4dot.code/deobfuscators/Confuser/JitMethodsDecrypter.cs index a061e5a3..17f7908f 100644 --- a/de4dot.code/deobfuscators/Confuser/JitMethodsDecrypter.cs +++ b/de4dot.code/deobfuscators/Confuser/JitMethodsDecrypter.cs @@ -39,6 +39,7 @@ namespace de4dot.code.deobfuscators.Confuser { Unknown, v17_r73404, v17_r73477, + v17_r73479, vXX, } @@ -62,18 +63,27 @@ namespace de4dot.code.deobfuscators.Confuser { if (type == null) return false; + compileMethod = findCompileMethod(type); + if (compileMethod == null) + return false; + var theVersion = ConfuserVersion.Unknown; switch (type.NestedTypes.Count) { case 35: theVersion = ConfuserVersion.v17_r73404; break; - case 38: theVersion = ConfuserVersion.v17_r73477; break; + + case 38: + switch (countInt32s(compileMethod, 0xFF)) { + case 2: theVersion = ConfuserVersion.v17_r73477; break; + case 4: theVersion = ConfuserVersion.v17_r73479; break; + default: return false; + } + break; + case 27: theVersion = ConfuserVersion.vXX; break; default: return false; } - compileMethod = findCompileMethod(type); - if (compileMethod == null) - return false; - if (theVersion == ConfuserVersion.vXX || theVersion == ConfuserVersion.v17_r73477) { + if (theVersion >= ConfuserVersion.v17_r73477) { hookConstructStr = findHookConstructStr(type); if (hookConstructStr == null) return false; @@ -86,6 +96,17 @@ namespace de4dot.code.deobfuscators.Confuser { return true; } + static int countInt32s(MethodDefinition method, int val) { + int count = 0; + foreach (var instr in method.Body.Instructions) { + if (!DotNetUtils.isLdcI4(instr)) + continue; + if (DotNetUtils.getLdcI4Value(instr) == val) + count++; + } + return count; + } + static MethodDefinition findCompileMethod(TypeDefinition type) { foreach (var method in type.Methods) { if (!method.IsStatic || method.Body == null) @@ -145,6 +166,7 @@ namespace de4dot.code.deobfuscators.Confuser { switch (version) { case ConfuserVersion.v17_r73404: return initializeKeys_v17_r73404(); case ConfuserVersion.v17_r73477: return initializeKeys_v17_r73404(); + case ConfuserVersion.v17_r73479: return initializeKeys_v17_r73404(); case ConfuserVersion.vXX: return initializeKeys_vXX(); default: throw new ApplicationException("Invalid version"); } @@ -245,6 +267,7 @@ namespace de4dot.code.deobfuscators.Confuser { switch (version) { case ConfuserVersion.v17_r73404: return true; case ConfuserVersion.v17_r73477: return initializeMethodDataIndexes_v17_r73477(compileMethod); + case ConfuserVersion.v17_r73479: return initializeMethodDataIndexes_v17_r73477(compileMethod); case ConfuserVersion.vXX: return initializeMethodDataIndexes_v17_r73477(compileMethod); default: throw new ApplicationException("Invalid version"); } @@ -384,6 +407,7 @@ namespace de4dot.code.deobfuscators.Confuser { switch (version) { case ConfuserVersion.v17_r73404: return decrypt_v17_r73404(peImage, fileData, ref dumpedMethods); case ConfuserVersion.v17_r73477: return decrypt_v17_r73477(peImage, fileData, ref dumpedMethods); + case ConfuserVersion.v17_r73479: return decrypt_v17_r73479(peImage, fileData, ref dumpedMethods); case ConfuserVersion.vXX: return decrypt_vXX(peImage, fileData, ref dumpedMethods); default: throw new ApplicationException("Unknown version"); } @@ -452,6 +476,16 @@ namespace de4dot.code.deobfuscators.Confuser { return decrypt(peImage, fileData, new DecryptMethodData_v17_r73477()); } + bool decrypt_v17_r73479(PeImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) { + methodsData = decryptMethodsData_v17_r73404(peImage); + dumpedMethods = decrypt_v17_r73479(peImage, fileData); + return dumpedMethods != null; + } + + DumpedMethods decrypt_v17_r73479(PeImage peImage, byte[] fileData) { + return decrypt(peImage, fileData, new DecryptMethodData_v17_r73479()); + } + bool decrypt_vXX(PeImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) { if (peImage.OptionalHeader.checkSum == 0) return false; @@ -487,6 +521,23 @@ namespace de4dot.code.deobfuscators.Confuser { } } + class DecryptMethodData_v17_r73479 : DecryptMethodData { + public override void decrypt(byte[] fileData, int offset, uint k1, int size, out uint[] methodData, out byte[] codeData) { + var data = new byte[size]; + Array.Copy(fileData, offset, data, 0, data.Length); + uint k = k1; + for (int i = 0; i < data.Length; i++) { + data[i] ^= (byte)k; + k = (k * data[i] + k1) % 0xFF; + } + + methodData = new uint[5]; + Buffer.BlockCopy(data, 0, methodData, 0, 20); + codeData = new byte[size - 20]; + Array.Copy(data, 20, codeData, 0, codeData.Length); + } + } + class DecryptMethodData_vXX : DecryptMethodData { JitMethodsDecrypter jitDecrypter; @@ -545,6 +596,8 @@ namespace de4dot.code.deobfuscators.Confuser { int maxStack = (int)methodData[methodDataIndexes.maxStack]; dm.mhMaxStack = (ushort)maxStack; dm.mhLocalVarSigTok = methodData[methodDataIndexes.localVarSigTok]; + if (dm.mhLocalVarSigTok != 0 && (dm.mhLocalVarSigTok >> 24) != 0x11) + throw new ApplicationException("Invalid local var sig token"); int numExceptions = (int)methodData[methodDataIndexes.ehs]; uint options = methodData[methodDataIndexes.options]; int codeSize = (int)methodData[methodDataIndexes.codeSize];