From 0bb947aebc2b4b82ba172e519b49abae40264161 Mon Sep 17 00:00:00 2001 From: de4dot Date: Fri, 30 Nov 2012 21:05:54 +0100 Subject: [PATCH] Fix Confuser code since main code got updated --- .../Confuser/ConstantsDecrypterBase.cs | 9 +- .../Confuser/ConstantsDecrypterV18.cs | 7 +- .../deobfuscators/Confuser/Deobfuscator.cs | 53 ++++++----- .../Confuser/JitMethodsDecrypter.cs | 87 +++++++------------ .../Confuser/MemoryMethodsDecrypter.cs | 31 ++++--- .../Confuser/MethodsDecrypterBase.cs | 34 ++++---- .../deobfuscators/Confuser/ProxyCallFixer.cs | 35 ++++---- .../deobfuscators/Confuser/x86Emulator.cs | 27 +++--- 8 files changed, 139 insertions(+), 144 deletions(-) diff --git a/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterBase.cs b/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterBase.cs index 40c1fef1..39c1b3cc 100644 --- a/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterBase.cs +++ b/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterBase.cs @@ -24,7 +24,6 @@ using dot10.IO; using dot10.DotNet; using dot10.DotNet.Emit; using de4dot.blocks; -using de4dot.PE; namespace de4dot.code.deobfuscators.Confuser { abstract class ConstantsDecrypterBase : IVersionProvider { @@ -32,8 +31,8 @@ namespace de4dot.code.deobfuscators.Confuser { protected byte[] fileData; protected ISimpleDeobfuscator simpleDeobfuscator; protected MethodDef nativeMethod; - MethodDefinitionAndDeclaringTypeDict methodToDecrypterInfo = new MethodDefinitionAndDeclaringTypeDict(); - FieldDefinitionAndDeclaringTypeDict fields = new FieldDefinitionAndDeclaringTypeDict(); + MethodDefAndDeclaringTypeDict methodToDecrypterInfo = new MethodDefAndDeclaringTypeDict(); + FieldDefAndDeclaringTypeDict fields = new FieldDefAndDeclaringTypeDict(); protected EmbeddedResource resource; protected IBinaryReader reader; @@ -441,8 +440,8 @@ namespace de4dot.code.deobfuscators.Confuser { } protected byte[] decryptConstant_v17_r73764_native(DecrypterInfo info, byte[] encrypted, uint offs, uint key1, byte[] key2) { - var x86Emu = new x86Emulator(new PeImage(fileData)); - return decrypt(encrypted, key1, (magic, i) => (byte)(x86Emu.emulate((uint)nativeMethod.RVA, magic) ^ key2[i % key2.Length])); + using (var x86Emu = new x86Emulator(fileData)) + return decrypt(encrypted, key1, (magic, i) => (byte)(x86Emu.emulate((uint)nativeMethod.RVA, magic) ^ key2[i % key2.Length])); } static byte[] decrypt(byte[] encrypted, uint key, Func decryptFunc) { diff --git a/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterV18.cs b/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterV18.cs index 6302e575..a5a6c404 100644 --- a/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterV18.cs +++ b/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterV18.cs @@ -26,7 +26,6 @@ using dot10.DotNet; using dot10.DotNet.MD; using dot10.DotNet.Emit; using de4dot.blocks; -using de4dot.PE; namespace de4dot.code.deobfuscators.Confuser { // Since v1.8 r75367 @@ -36,7 +35,7 @@ namespace de4dot.code.deobfuscators.Confuser { ISimpleDeobfuscator simpleDeobfuscator; FieldDef dictField, dataField; MethodDef installMethod; - MethodDefinitionAndDeclaringTypeDict decrypters = new MethodDefinitionAndDeclaringTypeDict(); + MethodDefAndDeclaringTypeDict decrypters = new MethodDefAndDeclaringTypeDict(); uint key0, key0d; MethodDef nativeMethod; EmbeddedResource resource; @@ -639,8 +638,8 @@ namespace de4dot.code.deobfuscators.Confuser { } byte[] decryptResource_v18_r75367_native(byte[] encrypted) { - var x86Emu = new x86Emulator(new PeImage(fileData)); - return decryptResource(encrypted, magic => (byte)x86Emu.emulate((uint)nativeMethod.RVA, magic)); + using (var x86Emu = new x86Emulator(fileData)) + return decryptResource(encrypted, magic => (byte)x86Emu.emulate((uint)nativeMethod.RVA, magic)); } byte[] decryptResource(byte[] encrypted, Func decryptFunc) { diff --git a/de4dot.code/deobfuscators/Confuser/Deobfuscator.cs b/de4dot.code/deobfuscators/Confuser/Deobfuscator.cs index 03b85f7e..f84211f9 100644 --- a/de4dot.code/deobfuscators/Confuser/Deobfuscator.cs +++ b/de4dot.code/deobfuscators/Confuser/Deobfuscator.cs @@ -23,7 +23,6 @@ using dot10.DotNet; using dot10.IO; using de4dot.blocks; using de4dot.blocks.cflow; -using de4dot.PE; namespace de4dot.code.deobfuscators.Confuser { public class DeobfuscatorInfo : DeobfuscatorInfoBase { @@ -267,29 +266,30 @@ namespace de4dot.code.deobfuscators.Confuser { public override bool getDecryptedModule(int count, ref byte[] newFileData, ref DumpedMethods dumpedMethods) { hasUnpacked = false; byte[] fileData = getFileData(); - var peImage = new PeImage(fileData); - if ((decryptState & DecryptState.CanDecryptMethods) != 0) { - bool decrypted = false; - if (jitMethodsDecrypter != null && jitMethodsDecrypter.Detected) { - jitMethodsDecrypter.initialize(); - if (!jitMethodsDecrypter.decrypt(peImage, fileData, ref dumpedMethods)) - return false; - decrypted = true; - } - else if (memoryMethodsDecrypter != null && memoryMethodsDecrypter.Detected) { - memoryMethodsDecrypter.initialize(); - if (!memoryMethodsDecrypter.decrypt(peImage, fileData)) - return false; - decrypted = true; - } + using (var peImage = new MyPEImage(fileData)) { + if ((decryptState & DecryptState.CanDecryptMethods) != 0) { + bool decrypted = false; + if (jitMethodsDecrypter != null && jitMethodsDecrypter.Detected) { + jitMethodsDecrypter.initialize(); + if (!jitMethodsDecrypter.decrypt(peImage, fileData, ref dumpedMethods)) + return false; + decrypted = true; + } + else if (memoryMethodsDecrypter != null && memoryMethodsDecrypter.Detected) { + memoryMethodsDecrypter.initialize(); + if (!memoryMethodsDecrypter.decrypt(peImage, fileData)) + return false; + decrypted = true; + } - if (decrypted) { - decryptState &= ~DecryptState.CanDecryptMethods; - decryptState |= DecryptState.CanUnpack; - newFileData = fileData; - ModuleBytes = newFileData; - return true; + if (decrypted) { + decryptState &= ~DecryptState.CanDecryptMethods; + decryptState |= DecryptState.CanUnpack; + newFileData = fileData; + ModuleBytes = newFileData; + return true; + } } } @@ -600,5 +600,14 @@ namespace de4dot.code.deobfuscators.Confuser { return null; return ((IStringDecrypter)jitMethodsDecrypter).ReadUserString(token); } + + protected override void Dispose(bool disposing) { + if (disposing) { + if (proxyCallFixer != null) + proxyCallFixer.Dispose(); + proxyCallFixer = null; + } + base.Dispose(disposing); + } } } diff --git a/de4dot.code/deobfuscators/Confuser/JitMethodsDecrypter.cs b/de4dot.code/deobfuscators/Confuser/JitMethodsDecrypter.cs index 8499eb7a..ddf0f9ac 100644 --- a/de4dot.code/deobfuscators/Confuser/JitMethodsDecrypter.cs +++ b/de4dot.code/deobfuscators/Confuser/JitMethodsDecrypter.cs @@ -25,7 +25,6 @@ using dot10.IO; using dot10.DotNet; using dot10.DotNet.Emit; using de4dot.blocks; -using de4dot.PE; namespace de4dot.code.deobfuscators.Confuser { class JitMethodsDecrypter : MethodsDecrypterBase, IStringDecrypter { @@ -449,7 +448,7 @@ namespace de4dot.code.deobfuscators.Confuser { return -1; } - public bool decrypt(PeImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) { + public bool decrypt(MyPEImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) { if (initMethod == null) return false; @@ -468,52 +467,38 @@ namespace de4dot.code.deobfuscators.Confuser { } } - bool decrypt_v17_r73404(PeImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) { + bool decrypt_v17_r73404(MyPEImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) { methodsData = decryptMethodsData_v17_r73404(peImage); dumpedMethods = decrypt_v17_r73404(peImage, fileData); return dumpedMethods != null; } - DumpedMethods decrypt_v17_r73404(PeImage peImage, byte[] fileData) { + DumpedMethods decrypt_v17_r73404(MyPEImage peImage, byte[] fileData) { var dumpedMethods = new DumpedMethods(); - var metadataTables = peImage.Cor20Header.createMetadataTables(); - var methodDef = metadataTables.getMetadataType(MetadataIndex.iMethodDef); - uint methodDefOffset = methodDef.fileOffset; - for (int i = 0; i < methodDef.rows; i++, methodDefOffset += methodDef.totalSize) { - uint bodyRva = peImage.offsetReadUInt32(methodDefOffset); - if (bodyRva == 0) + var methodDef = peImage.DotNetFile.MetaData.TablesStream.MethodTable; + for (uint rid = 1; rid <= methodDef.Rows; rid++) { + var dm = new DumpedMethod(); + peImage.readMethodTableRowTo(dm, rid); + + if (dm.mdRVA == 0) continue; - uint bodyOffset = peImage.rvaToOffset(bodyRva); + uint bodyOffset = peImage.rvaToOffset(dm.mdRVA); if (!isEncryptedMethod(fileData, (int)bodyOffset)) continue; - var dm = new DumpedMethod(); - dm.token = (uint)(0x06000001 + i); - dm.mdImplFlags = peImage.offsetReadUInt16(methodDefOffset + (uint)methodDef.fields[1].offset); - dm.mdFlags = peImage.offsetReadUInt16(methodDefOffset + (uint)methodDef.fields[2].offset); - dm.mdName = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[3].offset, methodDef.fields[3].size); - dm.mdSignature = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[4].offset, methodDef.fields[4].size); - dm.mdParamList = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[5].offset, methodDef.fields[5].size); - int key = BitConverter.ToInt32(fileData, (int)bodyOffset + 6); int mdOffs = BitConverter.ToInt32(fileData, (int)bodyOffset + 2) ^ key; int len = BitConverter.ToInt32(fileData, (int)bodyOffset + 11) ^ ~key; var codeData = decryptMethodData_v17_r73404(methodsData, mdOffs + 2, (uint)key, len); - byte[] code, extraSections; - var reader = new BinaryReader(new MemoryStream(codeData)); - var mbHeader = MethodBodyParser.parseMethodBody(reader, out code, out extraSections); - if (reader.BaseStream.Position != reader.BaseStream.Length) + var reader = MemoryImageStream.Create(codeData); + var mbHeader = MethodBodyParser.parseMethodBody(reader, out dm.code, out dm.extraSections); + if (reader.Position != reader.Length) throw new ApplicationException("Invalid method data"); - dm.mhFlags = mbHeader.flags; - dm.mhMaxStack = mbHeader.maxStack; - dm.code = code; - dm.extraSections = extraSections; - dm.mhCodeSize = (uint)dm.code.Length; - dm.mhLocalVarSigTok = mbHeader.localVarSigTok; + peImage.updateMethodHeaderInfo(dm, mbHeader); dumpedMethods.add(dm); } @@ -521,35 +506,35 @@ namespace de4dot.code.deobfuscators.Confuser { return dumpedMethods; } - bool decrypt_v17_r73477(PeImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) { + bool decrypt_v17_r73477(MyPEImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) { methodsData = decryptMethodsData_v17_r73404(peImage); dumpedMethods = decrypt_v17_r73477(peImage, fileData); return dumpedMethods != null; } - DumpedMethods decrypt_v17_r73477(PeImage peImage, byte[] fileData) { + DumpedMethods decrypt_v17_r73477(MyPEImage peImage, byte[] fileData) { return decrypt(peImage, fileData, new DecryptMethodData_v17_r73477()); } - bool decrypt_v17_r73479(PeImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) { + bool decrypt_v17_r73479(MyPEImage 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) { + DumpedMethods decrypt_v17_r73479(MyPEImage peImage, byte[] fileData) { return decrypt(peImage, fileData, new DecryptMethodData_v17_r73479()); } - bool decrypt_v18_r75402(PeImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) { - if (peImage.OptionalHeader.checkSum == 0) + bool decrypt_v18_r75402(MyPEImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) { + if (peImage.OptionalHeader.CheckSum == 0) return false; methodsData = decryptMethodsData_v17_r73404(peImage); dumpedMethods = decrypt_v18_r75402(peImage, fileData); return dumpedMethods != null; } - DumpedMethods decrypt_v18_r75402(PeImage peImage, byte[] fileData) { + DumpedMethods decrypt_v18_r75402(MyPEImage peImage, byte[] fileData) { return decrypt(peImage, fileData, new DecryptMethodData_v18_r75402(this)); } @@ -616,29 +601,21 @@ namespace de4dot.code.deobfuscators.Confuser { } } - DumpedMethods decrypt(PeImage peImage, byte[] fileData, DecryptMethodData decrypter) { + DumpedMethods decrypt(MyPEImage peImage, byte[] fileData, DecryptMethodData decrypter) { var dumpedMethods = new DumpedMethods(); - var metadataTables = peImage.Cor20Header.createMetadataTables(); - var methodDef = metadataTables.getMetadataType(MetadataIndex.iMethodDef); - uint methodDefOffset = methodDef.fileOffset; - for (int i = 0; i < methodDef.rows; i++, methodDefOffset += methodDef.totalSize) { - uint bodyRva = peImage.offsetReadUInt32(methodDefOffset); - if (bodyRva == 0) + var methodDef = peImage.DotNetFile.MetaData.TablesStream.MethodTable; + for (uint rid = 1; rid <= methodDef.Rows; rid++) { + var dm = new DumpedMethod(); + peImage.readMethodTableRowTo(dm, rid); + + if (dm.mdRVA == 0) continue; - uint bodyOffset = peImage.rvaToOffset(bodyRva); + uint bodyOffset = peImage.rvaToOffset(dm.mdRVA); if (!isEncryptedMethod(fileData, (int)bodyOffset)) continue; - var dm = new DumpedMethod(); - dm.token = (uint)(0x06000001 + i); - dm.mdImplFlags = peImage.offsetReadUInt16(methodDefOffset + (uint)methodDef.fields[1].offset); - dm.mdFlags = peImage.offsetReadUInt16(methodDefOffset + (uint)methodDef.fields[2].offset); - dm.mdName = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[3].offset, methodDef.fields[3].size); - dm.mdSignature = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[4].offset, methodDef.fields[4].size); - dm.mdParamList = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[5].offset, methodDef.fields[5].size); - int key = BitConverter.ToInt32(fileData, (int)bodyOffset + 6); int mdOffs = BitConverter.ToInt32(fileData, (int)bodyOffset + 2) ^ key; int len = BitConverter.ToInt32(fileData, (int)bodyOffset + 11) ^ ~key; @@ -657,7 +634,7 @@ namespace de4dot.code.deobfuscators.Confuser { uint options = methodData[methodDataIndexes.options]; int codeSize = (int)methodData[methodDataIndexes.codeSize]; - var codeDataReader = new BinaryReader(new MemoryStream(codeData)); + var codeDataReader = MemoryImageStream.Create(codeData); if (decrypter.isCodeFollowedByExtraSections(options)) { dm.code = codeDataReader.ReadBytes(codeSize); dm.extraSections = readExceptionHandlers(codeDataReader, numExceptions); @@ -666,7 +643,7 @@ namespace de4dot.code.deobfuscators.Confuser { dm.extraSections = readExceptionHandlers(codeDataReader, numExceptions); dm.code = codeDataReader.ReadBytes(codeSize); } - if (codeDataReader.BaseStream.Position != codeDataReader.BaseStream.Length) + if (codeDataReader.Position != codeDataReader.Length) throw new ApplicationException("Invalid method data"); if (dm.extraSections != null) dm.mhFlags |= 8; @@ -694,7 +671,7 @@ namespace de4dot.code.deobfuscators.Confuser { fileData[offset + 15] == 0x26; } - static byte[] readExceptionHandlers(BinaryReader reader, int numExceptions) { + static byte[] readExceptionHandlers(IBinaryReader reader, int numExceptions) { if (numExceptions == 0) return null; diff --git a/de4dot.code/deobfuscators/Confuser/MemoryMethodsDecrypter.cs b/de4dot.code/deobfuscators/Confuser/MemoryMethodsDecrypter.cs index d86c4e0e..33747202 100644 --- a/de4dot.code/deobfuscators/Confuser/MemoryMethodsDecrypter.cs +++ b/de4dot.code/deobfuscators/Confuser/MemoryMethodsDecrypter.cs @@ -22,7 +22,6 @@ using System.IO; using dot10.DotNet; using dot10.DotNet.Emit; using de4dot.blocks; -using de4dot.PE; namespace de4dot.code.deobfuscators.Confuser { class MemoryMethodsDecrypter : MethodsDecrypterBase { @@ -265,7 +264,7 @@ namespace de4dot.code.deobfuscators.Confuser { return false; } - public bool decrypt(PeImage peImage, byte[] fileData) { + public bool decrypt(MyPEImage peImage, byte[] fileData) { if (initMethod == null) return false; @@ -284,7 +283,7 @@ namespace de4dot.code.deobfuscators.Confuser { } } - bool decrypt_v14_r57884(PeImage peImage, byte[] fileData) { + bool decrypt_v14_r57884(MyPEImage peImage, byte[] fileData) { methodsData = decryptMethodsData_v14_r57884(peImage, false); var reader = new BinaryReader(new MemoryStream(methodsData)); @@ -302,12 +301,12 @@ namespace de4dot.code.deobfuscators.Confuser { return true; } - byte[] decryptMethodsData_v14_r57884(PeImage peImage, bool hasStrongNameInfo) { + byte[] decryptMethodsData_v14_r57884(MyPEImage peImage, bool hasStrongNameInfo) { var reader = peImage.Reader; - reader.BaseStream.Position = 0; - var md5SumData = reader.ReadBytes((int)peImage.OptionalHeader.checkSum ^ (int)key0); + reader.Position = 0; + var md5SumData = reader.ReadBytes((int)peImage.OptionalHeader.CheckSum ^ (int)key0); - int csOffs = (int)peImage.OptionalHeader.Offset + 0x40; + int csOffs = (int)peImage.OptionalHeader.StartOffset + 0x40; Array.Clear(md5SumData, csOffs, 4); var md5Sum = DeobUtils.md5Sum(md5SumData); ulong checkSum = reader.ReadUInt64() ^ lkey0; @@ -315,8 +314,8 @@ namespace de4dot.code.deobfuscators.Confuser { int sn = reader.ReadInt32(); int snLen = reader.ReadInt32(); if (sn != 0) { - if (peImage.rvaToOffset(peImage.Cor20Header.strongNameSignature.virtualAddress) != sn || - peImage.Cor20Header.strongNameSignature.size != snLen) + if (peImage.rvaToOffset((uint)peImage.Cor20Header.StrongNameSignature.VirtualAddress) != sn || + peImage.Cor20Header.StrongNameSignature.Size != snLen) throw new ApplicationException("Invalid sn and snLen"); Array.Clear(md5SumData, sn, snLen); } @@ -331,12 +330,12 @@ namespace de4dot.code.deobfuscators.Confuser { return decrypted; } - bool decrypt_v14_r58004(PeImage peImage, byte[] fileData) { + bool decrypt_v14_r58004(MyPEImage peImage, byte[] fileData) { methodsData = decryptMethodsData_v14_r57884(peImage, false); return decryptImage_v14_r58004(peImage, fileData); } - bool decryptImage_v14_r58004(PeImage peImage, byte[] fileData) { + bool decryptImage_v14_r58004(MyPEImage peImage, byte[] fileData) { var reader = new BinaryReader(new MemoryStream(methodsData)); reader.ReadInt16(); // sig var writer = new BinaryWriter(new MemoryStream(fileData)); @@ -355,25 +354,25 @@ namespace de4dot.code.deobfuscators.Confuser { return true; } - bool decrypt_v15_r59014(PeImage peImage, byte[] fileData) { + bool decrypt_v15_r59014(MyPEImage peImage, byte[] fileData) { methodsData = decryptMethodsData_v14_r57884(peImage, true); return decryptImage_v14_r58004(peImage, fileData); } - bool decrypt_v16_r71742(PeImage peImage, byte[] fileData) { + bool decrypt_v16_r71742(MyPEImage peImage, byte[] fileData) { methodsData = decryptMethodsData_v16_r71742(peImage, getEncryptedHeaderOffset_v16_r71742(peImage.Sections)); return decryptImage_v16_r71742(peImage, fileData); } - bool decrypt_v17_r73605(PeImage peImage, byte[] fileData) { - if (peImage.OptionalHeader.checkSum == 0) + bool decrypt_v17_r73605(MyPEImage peImage, byte[] fileData) { + if (peImage.OptionalHeader.CheckSum == 0) return false; methodsData = decryptMethodsData_v17_r73404(peImage); return decryptImage_v16_r71742(peImage, fileData); } - bool decryptImage_v16_r71742(PeImage peImage, byte[] fileData) { + bool decryptImage_v16_r71742(MyPEImage peImage, byte[] fileData) { var reader = new BinaryReader(new MemoryStream(methodsData)); reader.ReadInt16(); // sig int numInfos = reader.ReadInt32(); diff --git a/de4dot.code/deobfuscators/Confuser/MethodsDecrypterBase.cs b/de4dot.code/deobfuscators/Confuser/MethodsDecrypterBase.cs index 0af78987..400ecfd9 100644 --- a/de4dot.code/deobfuscators/Confuser/MethodsDecrypterBase.cs +++ b/de4dot.code/deobfuscators/Confuser/MethodsDecrypterBase.cs @@ -21,10 +21,10 @@ using System; using System.Collections.Generic; using System.IO; using System.Security.Cryptography; +using dot10.PE; using dot10.DotNet; using dot10.DotNet.Emit; using de4dot.blocks; -using de4dot.PE; namespace de4dot.code.deobfuscators.Confuser { abstract class MethodsDecrypterBase : IVersionProvider { @@ -318,16 +318,16 @@ namespace de4dot.code.deobfuscators.Confuser { return ConfuserUtils.findCallMethod(instrs, index, Code.Callvirt, "System.UInt64 System.IO.BinaryReader::ReadUInt64()"); } - protected byte[] decryptMethodsData_v17_r73404(PeImage peImage) { + protected byte[] decryptMethodsData_v17_r73404(MyPEImage 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; - if (peImage.rvaToOffset(mdRva) != peImage.Cor20Header.MetadataOffset) + protected byte[] decryptMethodsData_v16_r71742(MyPEImage peImage, uint encryptedHeaderOffset) { + uint mdRva = peImage.OptionalHeader.CheckSum ^ (uint)key0; + if ((RVA)mdRva != peImage.Cor20Header.MetaData.VirtualAddress) throw new ApplicationException("Invalid metadata rva"); var reader = peImage.Reader; - reader.BaseStream.Position = encryptedHeaderOffset; + reader.Position = encryptedHeaderOffset; ulong checkSum = reader.ReadUInt64() ^ lkey0; reader.ReadInt32(); // strong name RVA reader.ReadInt32(); // strong name len @@ -342,31 +342,31 @@ namespace de4dot.code.deobfuscators.Confuser { return decrypted; } - protected uint getEncryptedHeaderOffset_v16_r71742(IList sections) { + protected uint getEncryptedHeaderOffset_v16_r71742(IList sections) { for (int i = sections.Count - 1; i >= 0; i--) { var section = sections[i]; - if (section.displayName == ".confuse") - return section.pointerToRawData; + if (section.DisplayName == ".confuse") + return section.PointerToRawData; } throw new ApplicationException("Could not find encrypted section"); } - uint getEncryptedHeaderOffset_vXX(IList sections) { + uint getEncryptedHeaderOffset_vXX(IList sections) { for (int i = sections.Count - 1; i >= 0; i--) { var section = sections[i]; if (getSectionNameHash(section) == (uint)key1) - return section.pointerToRawData; + return section.PointerToRawData; } throw new ApplicationException("Could not find encrypted section"); } - static byte[] getStreamsBuffer(PeImage peImage) { + static byte[] getStreamsBuffer(MyPEImage peImage) { var memStream = new MemoryStream(); var writer = new BinaryWriter(memStream); var reader = peImage.Reader; - foreach (var mdStream in peImage.Cor20Header.metadata.Streams) { - reader.BaseStream.Position = mdStream.Offset; - writer.Write(reader.ReadBytes((int)mdStream.length)); + foreach (var mdStream in peImage.DotNetFile.MetaData.AllStreams) { + reader.Position = (long)mdStream.StartOffset; + writer.Write(reader.ReadBytes((int)(mdStream.EndOffset - mdStream.StartOffset))); } return memStream.ToArray(); } @@ -376,9 +376,9 @@ namespace de4dot.code.deobfuscators.Confuser { return BitConverter.ToUInt64(sum, 0) ^ BitConverter.ToUInt64(sum, 8); } - static uint getSectionNameHash(SectionHeader section) { + static uint getSectionNameHash(ImageSectionHeader section) { uint hash = 0; - foreach (var c in section.name) + foreach (var c in section.Name) hash += c; return hash; } diff --git a/de4dot.code/deobfuscators/Confuser/ProxyCallFixer.cs b/de4dot.code/deobfuscators/Confuser/ProxyCallFixer.cs index bc02d9e4..c30d9098 100644 --- a/de4dot.code/deobfuscators/Confuser/ProxyCallFixer.cs +++ b/de4dot.code/deobfuscators/Confuser/ProxyCallFixer.cs @@ -24,12 +24,11 @@ using System.Text; using dot10.DotNet; using dot10.DotNet.Emit; using de4dot.blocks; -using de4dot.PE; namespace de4dot.code.deobfuscators.Confuser { - class ProxyCallFixer : ProxyCallFixer2, IVersionProvider { - MethodDefinitionAndDeclaringTypeDict methodToInfo = new MethodDefinitionAndDeclaringTypeDict(); - FieldDefinitionAndDeclaringTypeDict> fieldToMethods = new FieldDefinitionAndDeclaringTypeDict>(); + class ProxyCallFixer : ProxyCallFixer2, IVersionProvider, IDisposable { + MethodDefAndDeclaringTypeDict methodToInfo = new MethodDefAndDeclaringTypeDict(); + FieldDefAndDeclaringTypeDict> fieldToMethods = new FieldDefAndDeclaringTypeDict>(); string ourAsm; ConfuserVersion version = ConfuserVersion.Unknown; byte[] fileData; @@ -160,7 +159,7 @@ namespace de4dot.code.deobfuscators.Confuser { protected override object checkCctor(TypeDef type, MethodDef cctor) { // Here if 1.2 r54564 (almost 1.3) or later - var fieldToInfo = new FieldDefinitionAndDeclaringTypeDict(); + var fieldToInfo = new FieldDefAndDeclaringTypeDict(); var instrs = cctor.Body.Instructions; for (int i = 0; i < instrs.Count - 1; i++) { @@ -192,7 +191,7 @@ namespace de4dot.code.deobfuscators.Confuser { protected override void getCallInfo(object context, FieldDef field, out IMethod calledMethod, out OpCode callOpcode) { var info = context as DelegateInitInfo; if (info == null) { - var fieldToInfo = context as FieldDefinitionAndDeclaringTypeDict; + var fieldToInfo = context as FieldDefAndDeclaringTypeDict; if (fieldToInfo != null) info = fieldToInfo.find(field); } @@ -373,7 +372,7 @@ namespace de4dot.code.deobfuscators.Confuser { bool isCallvirt; extract_v17_r73740(creatorInfo, nameInfo, out arg, out table, out isCallvirt); if (x86emu == null) - x86emu = new x86Emulator(new PeImage(fileData)); + x86emu = new x86Emulator(fileData); uint token = x86emu.emulate((uint)creatorInfo.nativeMethod.RVA, arg) | table; calledMethod = module.ResolveToken((int)token) as IMethod; @@ -387,7 +386,7 @@ namespace de4dot.code.deobfuscators.Confuser { void getCallInfo_v18_r75367_native(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) { getCallInfo_v18_r75367(info, creatorInfo, out calledMethod, out callOpcode, (creatorInfo2, magic) => { if (x86emu == null) - x86emu = new x86Emulator(new PeImage(fileData)); + x86emu = new x86Emulator(fileData); return x86emu.emulate((uint)creatorInfo2.nativeMethod.RVA, magic); }); } @@ -876,7 +875,7 @@ namespace de4dot.code.deobfuscators.Confuser { find2(); } - FieldDefinitionAndDeclaringTypeDict createDelegateInitInfos(MethodDef method) { + FieldDefAndDeclaringTypeDict createDelegateInitInfos(MethodDef method) { switch (version) { case ConfuserVersion.v10_r42915: case ConfuserVersion.v10_r42919: @@ -886,8 +885,8 @@ namespace de4dot.code.deobfuscators.Confuser { } } - FieldDefinitionAndDeclaringTypeDict createDelegateInitInfos_v10_r42915(MethodDef method) { - var infos = new FieldDefinitionAndDeclaringTypeDict(); + FieldDefAndDeclaringTypeDict createDelegateInitInfos_v10_r42915(MethodDef method) { + var infos = new FieldDefAndDeclaringTypeDict(); var instrs = method.Body.Instructions; for (int i = 0; i < instrs.Count - 2; i++) { var ldstr = instrs[i]; @@ -920,8 +919,8 @@ namespace de4dot.code.deobfuscators.Confuser { return infos; } - FieldDefinitionAndDeclaringTypeDict createDelegateInitInfos_v10_r48717(MethodDef method) { - var infos = new FieldDefinitionAndDeclaringTypeDict(); + FieldDefAndDeclaringTypeDict createDelegateInitInfos_v10_r48717(MethodDef method) { + var infos = new FieldDefAndDeclaringTypeDict(); var instrs = method.Body.Instructions; for (int i = 0; i < instrs.Count - 1; i++) { var ldtoken = instrs[i]; @@ -947,8 +946,8 @@ namespace de4dot.code.deobfuscators.Confuser { return infos; } - static FieldDefinitionAndDeclaringTypeDict> createFieldToMethodsDictionary(TypeDef type) { - var dict = new FieldDefinitionAndDeclaringTypeDict>(); + static FieldDefAndDeclaringTypeDict> createFieldToMethodsDictionary(TypeDef type) { + var dict = new FieldDefAndDeclaringTypeDict>(); foreach (var method in type.Methods) { if (!method.IsStatic || method.Body == null || method.Name == ".cctor") continue; @@ -1123,5 +1122,11 @@ namespace de4dot.code.deobfuscators.Confuser { default: throw new ApplicationException("Invalid version"); } } + + public void Dispose() { + if (x86emu != null) + x86emu.Dispose(); + x86emu = null; + } } } diff --git a/de4dot.code/deobfuscators/Confuser/x86Emulator.cs b/de4dot.code/deobfuscators/Confuser/x86Emulator.cs index 1941e83c..b8e401d3 100644 --- a/de4dot.code/deobfuscators/Confuser/x86Emulator.cs +++ b/de4dot.code/deobfuscators/Confuser/x86Emulator.cs @@ -20,10 +20,10 @@ using System; using System.Collections.Generic; using System.IO; -using de4dot.PE; +using dot10.IO; namespace de4dot.code.deobfuscators.Confuser { - class x86Emulator { + class x86Emulator : IDisposable { // Confuser 1.7 r73740 - r73822 static readonly byte[] prolog1 = new byte[] { 0x8B, 0x44, 0x24, 0x04, 0x53, 0x50, @@ -42,8 +42,8 @@ namespace de4dot.code.deobfuscators.Confuser { 0x5E, 0x5F, 0x5B, 0xC3, }; - PeImage peImage; - BinaryReader reader; + MyPEImage peImage; + IBinaryReader reader; uint[] args; int nextArgIndex; uint[] regs = new uint[8]; @@ -121,8 +121,8 @@ namespace de4dot.code.deobfuscators.Confuser { } } - public x86Emulator(PeImage peImage) { - this.peImage = peImage; + public x86Emulator(byte[] fileData) { + this.peImage = new MyPEImage(fileData); this.reader = peImage.Reader; } @@ -133,7 +133,7 @@ namespace de4dot.code.deobfuscators.Confuser { public uint emulate(uint rva, uint[] args) { initialize(args); - reader.BaseStream.Position = peImage.rvaToOffset(rva); + reader.Position = peImage.rvaToOffset(rva); byte[] prolog, epilog; if (isBytes(prolog1)) { prolog = prolog1; @@ -145,7 +145,7 @@ namespace de4dot.code.deobfuscators.Confuser { } else throw new ApplicationException(string.Format("Missing prolog @ RVA {0:X8}", rva)); - reader.BaseStream.Position += prolog.Length; + reader.Position += prolog.Length; while (!isBytes(epilog)) emulate(); @@ -161,7 +161,7 @@ namespace de4dot.code.deobfuscators.Confuser { } bool isBytes(IList bytes) { - long oldPos = reader.BaseStream.Position; + long oldPos = reader.Position; bool result = true; for (int i = 0; i < bytes.Count; i++) { if (bytes[i] != reader.ReadByte()) { @@ -169,7 +169,7 @@ namespace de4dot.code.deobfuscators.Confuser { break; } } - reader.BaseStream.Position = oldPos; + reader.Position = oldPos; return result; } @@ -303,5 +303,12 @@ namespace de4dot.code.deobfuscators.Confuser { if (mod != 3) throw new ApplicationException("Memory operand"); } + + public void Dispose() { + if (peImage != null) + peImage.Dispose(); + peImage = null; + reader = null; + } } }