Fix Confuser code since main code got updated

This commit is contained in:
de4dot 2012-11-30 21:05:54 +01:00
parent c3608908c5
commit 0bb947aebc
8 changed files with 139 additions and 144 deletions

View File

@ -24,7 +24,6 @@ using dot10.IO;
using dot10.DotNet; using dot10.DotNet;
using dot10.DotNet.Emit; using dot10.DotNet.Emit;
using de4dot.blocks; using de4dot.blocks;
using de4dot.PE;
namespace de4dot.code.deobfuscators.Confuser { namespace de4dot.code.deobfuscators.Confuser {
abstract class ConstantsDecrypterBase : IVersionProvider { abstract class ConstantsDecrypterBase : IVersionProvider {
@ -32,8 +31,8 @@ namespace de4dot.code.deobfuscators.Confuser {
protected byte[] fileData; protected byte[] fileData;
protected ISimpleDeobfuscator simpleDeobfuscator; protected ISimpleDeobfuscator simpleDeobfuscator;
protected MethodDef nativeMethod; protected MethodDef nativeMethod;
MethodDefinitionAndDeclaringTypeDict<DecrypterInfo> methodToDecrypterInfo = new MethodDefinitionAndDeclaringTypeDict<DecrypterInfo>(); MethodDefAndDeclaringTypeDict<DecrypterInfo> methodToDecrypterInfo = new MethodDefAndDeclaringTypeDict<DecrypterInfo>();
FieldDefinitionAndDeclaringTypeDict<bool> fields = new FieldDefinitionAndDeclaringTypeDict<bool>(); FieldDefAndDeclaringTypeDict<bool> fields = new FieldDefAndDeclaringTypeDict<bool>();
protected EmbeddedResource resource; protected EmbeddedResource resource;
protected IBinaryReader reader; 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) { protected byte[] decryptConstant_v17_r73764_native(DecrypterInfo info, byte[] encrypted, uint offs, uint key1, byte[] key2) {
var x86Emu = new x86Emulator(new PeImage(fileData)); using (var x86Emu = new x86Emulator(fileData))
return decrypt(encrypted, key1, (magic, i) => (byte)(x86Emu.emulate((uint)nativeMethod.RVA, magic) ^ key2[i % key2.Length])); 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<uint, int, byte> decryptFunc) { static byte[] decrypt(byte[] encrypted, uint key, Func<uint, int, byte> decryptFunc) {

View File

@ -26,7 +26,6 @@ using dot10.DotNet;
using dot10.DotNet.MD; using dot10.DotNet.MD;
using dot10.DotNet.Emit; using dot10.DotNet.Emit;
using de4dot.blocks; using de4dot.blocks;
using de4dot.PE;
namespace de4dot.code.deobfuscators.Confuser { namespace de4dot.code.deobfuscators.Confuser {
// Since v1.8 r75367 // Since v1.8 r75367
@ -36,7 +35,7 @@ namespace de4dot.code.deobfuscators.Confuser {
ISimpleDeobfuscator simpleDeobfuscator; ISimpleDeobfuscator simpleDeobfuscator;
FieldDef dictField, dataField; FieldDef dictField, dataField;
MethodDef installMethod; MethodDef installMethod;
MethodDefinitionAndDeclaringTypeDict<DecrypterInfo> decrypters = new MethodDefinitionAndDeclaringTypeDict<DecrypterInfo>(); MethodDefAndDeclaringTypeDict<DecrypterInfo> decrypters = new MethodDefAndDeclaringTypeDict<DecrypterInfo>();
uint key0, key0d; uint key0, key0d;
MethodDef nativeMethod; MethodDef nativeMethod;
EmbeddedResource resource; EmbeddedResource resource;
@ -639,8 +638,8 @@ namespace de4dot.code.deobfuscators.Confuser {
} }
byte[] decryptResource_v18_r75367_native(byte[] encrypted) { byte[] decryptResource_v18_r75367_native(byte[] encrypted) {
var x86Emu = new x86Emulator(new PeImage(fileData)); using (var x86Emu = new x86Emulator(fileData))
return decryptResource(encrypted, magic => (byte)x86Emu.emulate((uint)nativeMethod.RVA, magic)); return decryptResource(encrypted, magic => (byte)x86Emu.emulate((uint)nativeMethod.RVA, magic));
} }
byte[] decryptResource(byte[] encrypted, Func<uint, byte> decryptFunc) { byte[] decryptResource(byte[] encrypted, Func<uint, byte> decryptFunc) {

View File

@ -23,7 +23,6 @@ using dot10.DotNet;
using dot10.IO; using dot10.IO;
using de4dot.blocks; using de4dot.blocks;
using de4dot.blocks.cflow; using de4dot.blocks.cflow;
using de4dot.PE;
namespace de4dot.code.deobfuscators.Confuser { namespace de4dot.code.deobfuscators.Confuser {
public class DeobfuscatorInfo : DeobfuscatorInfoBase { 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) { public override bool getDecryptedModule(int count, ref byte[] newFileData, ref DumpedMethods dumpedMethods) {
hasUnpacked = false; hasUnpacked = false;
byte[] fileData = getFileData(); byte[] fileData = getFileData();
var peImage = new PeImage(fileData);
if ((decryptState & DecryptState.CanDecryptMethods) != 0) { using (var peImage = new MyPEImage(fileData)) {
bool decrypted = false; if ((decryptState & DecryptState.CanDecryptMethods) != 0) {
if (jitMethodsDecrypter != null && jitMethodsDecrypter.Detected) { bool decrypted = false;
jitMethodsDecrypter.initialize(); if (jitMethodsDecrypter != null && jitMethodsDecrypter.Detected) {
if (!jitMethodsDecrypter.decrypt(peImage, fileData, ref dumpedMethods)) jitMethodsDecrypter.initialize();
return false; if (!jitMethodsDecrypter.decrypt(peImage, fileData, ref dumpedMethods))
decrypted = true; return false;
} decrypted = true;
else if (memoryMethodsDecrypter != null && memoryMethodsDecrypter.Detected) { }
memoryMethodsDecrypter.initialize(); else if (memoryMethodsDecrypter != null && memoryMethodsDecrypter.Detected) {
if (!memoryMethodsDecrypter.decrypt(peImage, fileData)) memoryMethodsDecrypter.initialize();
return false; if (!memoryMethodsDecrypter.decrypt(peImage, fileData))
decrypted = true; return false;
} decrypted = true;
}
if (decrypted) { if (decrypted) {
decryptState &= ~DecryptState.CanDecryptMethods; decryptState &= ~DecryptState.CanDecryptMethods;
decryptState |= DecryptState.CanUnpack; decryptState |= DecryptState.CanUnpack;
newFileData = fileData; newFileData = fileData;
ModuleBytes = newFileData; ModuleBytes = newFileData;
return true; return true;
}
} }
} }
@ -600,5 +600,14 @@ namespace de4dot.code.deobfuscators.Confuser {
return null; return null;
return ((IStringDecrypter)jitMethodsDecrypter).ReadUserString(token); return ((IStringDecrypter)jitMethodsDecrypter).ReadUserString(token);
} }
protected override void Dispose(bool disposing) {
if (disposing) {
if (proxyCallFixer != null)
proxyCallFixer.Dispose();
proxyCallFixer = null;
}
base.Dispose(disposing);
}
} }
} }

View File

@ -25,7 +25,6 @@ using dot10.IO;
using dot10.DotNet; using dot10.DotNet;
using dot10.DotNet.Emit; using dot10.DotNet.Emit;
using de4dot.blocks; using de4dot.blocks;
using de4dot.PE;
namespace de4dot.code.deobfuscators.Confuser { namespace de4dot.code.deobfuscators.Confuser {
class JitMethodsDecrypter : MethodsDecrypterBase, IStringDecrypter { class JitMethodsDecrypter : MethodsDecrypterBase, IStringDecrypter {
@ -449,7 +448,7 @@ namespace de4dot.code.deobfuscators.Confuser {
return -1; 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) if (initMethod == null)
return false; 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); methodsData = decryptMethodsData_v17_r73404(peImage);
dumpedMethods = decrypt_v17_r73404(peImage, fileData); dumpedMethods = decrypt_v17_r73404(peImage, fileData);
return dumpedMethods != null; return dumpedMethods != null;
} }
DumpedMethods decrypt_v17_r73404(PeImage peImage, byte[] fileData) { DumpedMethods decrypt_v17_r73404(MyPEImage peImage, byte[] fileData) {
var dumpedMethods = new DumpedMethods(); var dumpedMethods = new DumpedMethods();
var metadataTables = peImage.Cor20Header.createMetadataTables(); var methodDef = peImage.DotNetFile.MetaData.TablesStream.MethodTable;
var methodDef = metadataTables.getMetadataType(MetadataIndex.iMethodDef); for (uint rid = 1; rid <= methodDef.Rows; rid++) {
uint methodDefOffset = methodDef.fileOffset; var dm = new DumpedMethod();
for (int i = 0; i < methodDef.rows; i++, methodDefOffset += methodDef.totalSize) { peImage.readMethodTableRowTo(dm, rid);
uint bodyRva = peImage.offsetReadUInt32(methodDefOffset);
if (bodyRva == 0) if (dm.mdRVA == 0)
continue; continue;
uint bodyOffset = peImage.rvaToOffset(bodyRva); uint bodyOffset = peImage.rvaToOffset(dm.mdRVA);
if (!isEncryptedMethod(fileData, (int)bodyOffset)) if (!isEncryptedMethod(fileData, (int)bodyOffset))
continue; 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 key = BitConverter.ToInt32(fileData, (int)bodyOffset + 6);
int mdOffs = BitConverter.ToInt32(fileData, (int)bodyOffset + 2) ^ key; int mdOffs = BitConverter.ToInt32(fileData, (int)bodyOffset + 2) ^ key;
int len = BitConverter.ToInt32(fileData, (int)bodyOffset + 11) ^ ~key; int len = BitConverter.ToInt32(fileData, (int)bodyOffset + 11) ^ ~key;
var codeData = decryptMethodData_v17_r73404(methodsData, mdOffs + 2, (uint)key, len); var codeData = decryptMethodData_v17_r73404(methodsData, mdOffs + 2, (uint)key, len);
byte[] code, extraSections; var reader = MemoryImageStream.Create(codeData);
var reader = new BinaryReader(new MemoryStream(codeData)); var mbHeader = MethodBodyParser.parseMethodBody(reader, out dm.code, out dm.extraSections);
var mbHeader = MethodBodyParser.parseMethodBody(reader, out code, out extraSections); if (reader.Position != reader.Length)
if (reader.BaseStream.Position != reader.BaseStream.Length)
throw new ApplicationException("Invalid method data"); throw new ApplicationException("Invalid method data");
dm.mhFlags = mbHeader.flags; peImage.updateMethodHeaderInfo(dm, mbHeader);
dm.mhMaxStack = mbHeader.maxStack;
dm.code = code;
dm.extraSections = extraSections;
dm.mhCodeSize = (uint)dm.code.Length;
dm.mhLocalVarSigTok = mbHeader.localVarSigTok;
dumpedMethods.add(dm); dumpedMethods.add(dm);
} }
@ -521,35 +506,35 @@ namespace de4dot.code.deobfuscators.Confuser {
return dumpedMethods; 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); methodsData = decryptMethodsData_v17_r73404(peImage);
dumpedMethods = decrypt_v17_r73477(peImage, fileData); dumpedMethods = decrypt_v17_r73477(peImage, fileData);
return dumpedMethods != null; 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()); 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); methodsData = decryptMethodsData_v17_r73404(peImage);
dumpedMethods = decrypt_v17_r73479(peImage, fileData); dumpedMethods = decrypt_v17_r73479(peImage, fileData);
return dumpedMethods != null; 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()); return decrypt(peImage, fileData, new DecryptMethodData_v17_r73479());
} }
bool decrypt_v18_r75402(PeImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) { bool decrypt_v18_r75402(MyPEImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) {
if (peImage.OptionalHeader.checkSum == 0) if (peImage.OptionalHeader.CheckSum == 0)
return false; return false;
methodsData = decryptMethodsData_v17_r73404(peImage); methodsData = decryptMethodsData_v17_r73404(peImage);
dumpedMethods = decrypt_v18_r75402(peImage, fileData); dumpedMethods = decrypt_v18_r75402(peImage, fileData);
return dumpedMethods != null; 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)); 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 dumpedMethods = new DumpedMethods();
var metadataTables = peImage.Cor20Header.createMetadataTables(); var methodDef = peImage.DotNetFile.MetaData.TablesStream.MethodTable;
var methodDef = metadataTables.getMetadataType(MetadataIndex.iMethodDef); for (uint rid = 1; rid <= methodDef.Rows; rid++) {
uint methodDefOffset = methodDef.fileOffset; var dm = new DumpedMethod();
for (int i = 0; i < methodDef.rows; i++, methodDefOffset += methodDef.totalSize) { peImage.readMethodTableRowTo(dm, rid);
uint bodyRva = peImage.offsetReadUInt32(methodDefOffset);
if (bodyRva == 0) if (dm.mdRVA == 0)
continue; continue;
uint bodyOffset = peImage.rvaToOffset(bodyRva); uint bodyOffset = peImage.rvaToOffset(dm.mdRVA);
if (!isEncryptedMethod(fileData, (int)bodyOffset)) if (!isEncryptedMethod(fileData, (int)bodyOffset))
continue; 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 key = BitConverter.ToInt32(fileData, (int)bodyOffset + 6);
int mdOffs = BitConverter.ToInt32(fileData, (int)bodyOffset + 2) ^ key; int mdOffs = BitConverter.ToInt32(fileData, (int)bodyOffset + 2) ^ key;
int len = BitConverter.ToInt32(fileData, (int)bodyOffset + 11) ^ ~key; int len = BitConverter.ToInt32(fileData, (int)bodyOffset + 11) ^ ~key;
@ -657,7 +634,7 @@ namespace de4dot.code.deobfuscators.Confuser {
uint options = methodData[methodDataIndexes.options]; uint options = methodData[methodDataIndexes.options];
int codeSize = (int)methodData[methodDataIndexes.codeSize]; int codeSize = (int)methodData[methodDataIndexes.codeSize];
var codeDataReader = new BinaryReader(new MemoryStream(codeData)); var codeDataReader = MemoryImageStream.Create(codeData);
if (decrypter.isCodeFollowedByExtraSections(options)) { if (decrypter.isCodeFollowedByExtraSections(options)) {
dm.code = codeDataReader.ReadBytes(codeSize); dm.code = codeDataReader.ReadBytes(codeSize);
dm.extraSections = readExceptionHandlers(codeDataReader, numExceptions); dm.extraSections = readExceptionHandlers(codeDataReader, numExceptions);
@ -666,7 +643,7 @@ namespace de4dot.code.deobfuscators.Confuser {
dm.extraSections = readExceptionHandlers(codeDataReader, numExceptions); dm.extraSections = readExceptionHandlers(codeDataReader, numExceptions);
dm.code = codeDataReader.ReadBytes(codeSize); dm.code = codeDataReader.ReadBytes(codeSize);
} }
if (codeDataReader.BaseStream.Position != codeDataReader.BaseStream.Length) if (codeDataReader.Position != codeDataReader.Length)
throw new ApplicationException("Invalid method data"); throw new ApplicationException("Invalid method data");
if (dm.extraSections != null) if (dm.extraSections != null)
dm.mhFlags |= 8; dm.mhFlags |= 8;
@ -694,7 +671,7 @@ namespace de4dot.code.deobfuscators.Confuser {
fileData[offset + 15] == 0x26; fileData[offset + 15] == 0x26;
} }
static byte[] readExceptionHandlers(BinaryReader reader, int numExceptions) { static byte[] readExceptionHandlers(IBinaryReader reader, int numExceptions) {
if (numExceptions == 0) if (numExceptions == 0)
return null; return null;

View File

@ -22,7 +22,6 @@ using System.IO;
using dot10.DotNet; using dot10.DotNet;
using dot10.DotNet.Emit; using dot10.DotNet.Emit;
using de4dot.blocks; using de4dot.blocks;
using de4dot.PE;
namespace de4dot.code.deobfuscators.Confuser { namespace de4dot.code.deobfuscators.Confuser {
class MemoryMethodsDecrypter : MethodsDecrypterBase { class MemoryMethodsDecrypter : MethodsDecrypterBase {
@ -265,7 +264,7 @@ namespace de4dot.code.deobfuscators.Confuser {
return false; return false;
} }
public bool decrypt(PeImage peImage, byte[] fileData) { public bool decrypt(MyPEImage peImage, byte[] fileData) {
if (initMethod == null) if (initMethod == null)
return false; 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); methodsData = decryptMethodsData_v14_r57884(peImage, false);
var reader = new BinaryReader(new MemoryStream(methodsData)); var reader = new BinaryReader(new MemoryStream(methodsData));
@ -302,12 +301,12 @@ namespace de4dot.code.deobfuscators.Confuser {
return true; return true;
} }
byte[] decryptMethodsData_v14_r57884(PeImage peImage, bool hasStrongNameInfo) { byte[] decryptMethodsData_v14_r57884(MyPEImage peImage, bool hasStrongNameInfo) {
var reader = peImage.Reader; var reader = peImage.Reader;
reader.BaseStream.Position = 0; reader.Position = 0;
var md5SumData = reader.ReadBytes((int)peImage.OptionalHeader.checkSum ^ (int)key0); 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); Array.Clear(md5SumData, csOffs, 4);
var md5Sum = DeobUtils.md5Sum(md5SumData); var md5Sum = DeobUtils.md5Sum(md5SumData);
ulong checkSum = reader.ReadUInt64() ^ lkey0; ulong checkSum = reader.ReadUInt64() ^ lkey0;
@ -315,8 +314,8 @@ namespace de4dot.code.deobfuscators.Confuser {
int sn = reader.ReadInt32(); int sn = reader.ReadInt32();
int snLen = reader.ReadInt32(); int snLen = reader.ReadInt32();
if (sn != 0) { if (sn != 0) {
if (peImage.rvaToOffset(peImage.Cor20Header.strongNameSignature.virtualAddress) != sn || if (peImage.rvaToOffset((uint)peImage.Cor20Header.StrongNameSignature.VirtualAddress) != sn ||
peImage.Cor20Header.strongNameSignature.size != snLen) peImage.Cor20Header.StrongNameSignature.Size != snLen)
throw new ApplicationException("Invalid sn and snLen"); throw new ApplicationException("Invalid sn and snLen");
Array.Clear(md5SumData, sn, snLen); Array.Clear(md5SumData, sn, snLen);
} }
@ -331,12 +330,12 @@ namespace de4dot.code.deobfuscators.Confuser {
return decrypted; return decrypted;
} }
bool decrypt_v14_r58004(PeImage peImage, byte[] fileData) { bool decrypt_v14_r58004(MyPEImage peImage, byte[] fileData) {
methodsData = decryptMethodsData_v14_r57884(peImage, false); methodsData = decryptMethodsData_v14_r57884(peImage, false);
return decryptImage_v14_r58004(peImage, fileData); 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)); 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));
@ -355,25 +354,25 @@ namespace de4dot.code.deobfuscators.Confuser {
return true; return true;
} }
bool decrypt_v15_r59014(PeImage peImage, byte[] fileData) { bool decrypt_v15_r59014(MyPEImage peImage, byte[] fileData) {
methodsData = decryptMethodsData_v14_r57884(peImage, true); methodsData = decryptMethodsData_v14_r57884(peImage, true);
return decryptImage_v14_r58004(peImage, fileData); 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)); methodsData = decryptMethodsData_v16_r71742(peImage, getEncryptedHeaderOffset_v16_r71742(peImage.Sections));
return decryptImage_v16_r71742(peImage, fileData); return decryptImage_v16_r71742(peImage, fileData);
} }
bool decrypt_v17_r73605(PeImage peImage, byte[] fileData) { bool decrypt_v17_r73605(MyPEImage peImage, byte[] fileData) {
if (peImage.OptionalHeader.checkSum == 0) if (peImage.OptionalHeader.CheckSum == 0)
return false; return false;
methodsData = decryptMethodsData_v17_r73404(peImage); methodsData = decryptMethodsData_v17_r73404(peImage);
return decryptImage_v16_r71742(peImage, fileData); 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)); var reader = new BinaryReader(new MemoryStream(methodsData));
reader.ReadInt16(); // sig reader.ReadInt16(); // sig
int numInfos = reader.ReadInt32(); int numInfos = reader.ReadInt32();

View File

@ -21,10 +21,10 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Security.Cryptography; using System.Security.Cryptography;
using dot10.PE;
using dot10.DotNet; using dot10.DotNet;
using dot10.DotNet.Emit; using dot10.DotNet.Emit;
using de4dot.blocks; using de4dot.blocks;
using de4dot.PE;
namespace de4dot.code.deobfuscators.Confuser { namespace de4dot.code.deobfuscators.Confuser {
abstract class MethodsDecrypterBase : IVersionProvider { 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()"); 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)); return decryptMethodsData_v16_r71742(peImage, getEncryptedHeaderOffset_vXX(peImage.Sections));
} }
protected byte[] decryptMethodsData_v16_r71742(PeImage peImage, uint encryptedHeaderOffset) { protected byte[] decryptMethodsData_v16_r71742(MyPEImage 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 ((RVA)mdRva != peImage.Cor20Header.MetaData.VirtualAddress)
throw new ApplicationException("Invalid metadata rva"); throw new ApplicationException("Invalid metadata rva");
var reader = peImage.Reader; var reader = peImage.Reader;
reader.BaseStream.Position = encryptedHeaderOffset; reader.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
@ -342,31 +342,31 @@ namespace de4dot.code.deobfuscators.Confuser {
return decrypted; return decrypted;
} }
protected uint getEncryptedHeaderOffset_v16_r71742(IList<SectionHeader> sections) { protected uint getEncryptedHeaderOffset_v16_r71742(IList<ImageSectionHeader> 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 (section.displayName == ".confuse") if (section.DisplayName == ".confuse")
return section.pointerToRawData; return section.PointerToRawData;
} }
throw new ApplicationException("Could not find encrypted section"); throw new ApplicationException("Could not find encrypted section");
} }
uint getEncryptedHeaderOffset_vXX(IList<SectionHeader> sections) { uint getEncryptedHeaderOffset_vXX(IList<ImageSectionHeader> 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)
return section.pointerToRawData; return section.PointerToRawData;
} }
throw new ApplicationException("Could not find encrypted section"); throw new ApplicationException("Could not find encrypted section");
} }
static byte[] getStreamsBuffer(PeImage peImage) { static byte[] getStreamsBuffer(MyPEImage peImage) {
var memStream = new MemoryStream(); var memStream = new MemoryStream();
var writer = new BinaryWriter(memStream); var writer = new BinaryWriter(memStream);
var reader = peImage.Reader; var reader = peImage.Reader;
foreach (var mdStream in peImage.Cor20Header.metadata.Streams) { foreach (var mdStream in peImage.DotNetFile.MetaData.AllStreams) {
reader.BaseStream.Position = mdStream.Offset; reader.Position = (long)mdStream.StartOffset;
writer.Write(reader.ReadBytes((int)mdStream.length)); writer.Write(reader.ReadBytes((int)(mdStream.EndOffset - mdStream.StartOffset)));
} }
return memStream.ToArray(); return memStream.ToArray();
} }
@ -376,9 +376,9 @@ namespace de4dot.code.deobfuscators.Confuser {
return BitConverter.ToUInt64(sum, 0) ^ BitConverter.ToUInt64(sum, 8); return BitConverter.ToUInt64(sum, 0) ^ BitConverter.ToUInt64(sum, 8);
} }
static uint getSectionNameHash(SectionHeader section) { static uint getSectionNameHash(ImageSectionHeader section) {
uint hash = 0; uint hash = 0;
foreach (var c in section.name) foreach (var c in section.Name)
hash += c; hash += c;
return hash; return hash;
} }

View File

@ -24,12 +24,11 @@ using System.Text;
using dot10.DotNet; using dot10.DotNet;
using dot10.DotNet.Emit; using dot10.DotNet.Emit;
using de4dot.blocks; using de4dot.blocks;
using de4dot.PE;
namespace de4dot.code.deobfuscators.Confuser { namespace de4dot.code.deobfuscators.Confuser {
class ProxyCallFixer : ProxyCallFixer2, IVersionProvider { class ProxyCallFixer : ProxyCallFixer2, IVersionProvider, IDisposable {
MethodDefinitionAndDeclaringTypeDict<ProxyCreatorInfo> methodToInfo = new MethodDefinitionAndDeclaringTypeDict<ProxyCreatorInfo>(); MethodDefAndDeclaringTypeDict<ProxyCreatorInfo> methodToInfo = new MethodDefAndDeclaringTypeDict<ProxyCreatorInfo>();
FieldDefinitionAndDeclaringTypeDict<List<MethodDef>> fieldToMethods = new FieldDefinitionAndDeclaringTypeDict<List<MethodDef>>(); FieldDefAndDeclaringTypeDict<List<MethodDef>> fieldToMethods = new FieldDefAndDeclaringTypeDict<List<MethodDef>>();
string ourAsm; string ourAsm;
ConfuserVersion version = ConfuserVersion.Unknown; ConfuserVersion version = ConfuserVersion.Unknown;
byte[] fileData; byte[] fileData;
@ -160,7 +159,7 @@ namespace de4dot.code.deobfuscators.Confuser {
protected override object checkCctor(TypeDef type, MethodDef cctor) { protected override object checkCctor(TypeDef type, MethodDef cctor) {
// Here if 1.2 r54564 (almost 1.3) or later // Here if 1.2 r54564 (almost 1.3) or later
var fieldToInfo = new FieldDefinitionAndDeclaringTypeDict<DelegateInitInfo>(); var fieldToInfo = new FieldDefAndDeclaringTypeDict<DelegateInitInfo>();
var instrs = cctor.Body.Instructions; var instrs = cctor.Body.Instructions;
for (int i = 0; i < instrs.Count - 1; i++) { 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) { protected override void getCallInfo(object context, FieldDef field, out IMethod calledMethod, out OpCode callOpcode) {
var info = context as DelegateInitInfo; var info = context as DelegateInitInfo;
if (info == null) { if (info == null) {
var fieldToInfo = context as FieldDefinitionAndDeclaringTypeDict<DelegateInitInfo>; var fieldToInfo = context as FieldDefAndDeclaringTypeDict<DelegateInitInfo>;
if (fieldToInfo != null) if (fieldToInfo != null)
info = fieldToInfo.find(field); info = fieldToInfo.find(field);
} }
@ -373,7 +372,7 @@ namespace de4dot.code.deobfuscators.Confuser {
bool isCallvirt; bool isCallvirt;
extract_v17_r73740(creatorInfo, nameInfo, out arg, out table, out isCallvirt); extract_v17_r73740(creatorInfo, nameInfo, out arg, out table, out isCallvirt);
if (x86emu == null) if (x86emu == null)
x86emu = new x86Emulator(new PeImage(fileData)); x86emu = new x86Emulator(fileData);
uint token = x86emu.emulate((uint)creatorInfo.nativeMethod.RVA, arg) | table; uint token = x86emu.emulate((uint)creatorInfo.nativeMethod.RVA, arg) | table;
calledMethod = module.ResolveToken((int)token) as IMethod; 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) { 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) => { getCallInfo_v18_r75367(info, creatorInfo, out calledMethod, out callOpcode, (creatorInfo2, magic) => {
if (x86emu == null) if (x86emu == null)
x86emu = new x86Emulator(new PeImage(fileData)); x86emu = new x86Emulator(fileData);
return x86emu.emulate((uint)creatorInfo2.nativeMethod.RVA, magic); return x86emu.emulate((uint)creatorInfo2.nativeMethod.RVA, magic);
}); });
} }
@ -876,7 +875,7 @@ namespace de4dot.code.deobfuscators.Confuser {
find2(); find2();
} }
FieldDefinitionAndDeclaringTypeDict<DelegateInitInfo> createDelegateInitInfos(MethodDef method) { FieldDefAndDeclaringTypeDict<DelegateInitInfo> createDelegateInitInfos(MethodDef method) {
switch (version) { switch (version) {
case ConfuserVersion.v10_r42915: case ConfuserVersion.v10_r42915:
case ConfuserVersion.v10_r42919: case ConfuserVersion.v10_r42919:
@ -886,8 +885,8 @@ namespace de4dot.code.deobfuscators.Confuser {
} }
} }
FieldDefinitionAndDeclaringTypeDict<DelegateInitInfo> createDelegateInitInfos_v10_r42915(MethodDef method) { FieldDefAndDeclaringTypeDict<DelegateInitInfo> createDelegateInitInfos_v10_r42915(MethodDef method) {
var infos = new FieldDefinitionAndDeclaringTypeDict<DelegateInitInfo>(); var infos = new FieldDefAndDeclaringTypeDict<DelegateInitInfo>();
var instrs = method.Body.Instructions; var instrs = method.Body.Instructions;
for (int i = 0; i < instrs.Count - 2; i++) { for (int i = 0; i < instrs.Count - 2; i++) {
var ldstr = instrs[i]; var ldstr = instrs[i];
@ -920,8 +919,8 @@ namespace de4dot.code.deobfuscators.Confuser {
return infos; return infos;
} }
FieldDefinitionAndDeclaringTypeDict<DelegateInitInfo> createDelegateInitInfos_v10_r48717(MethodDef method) { FieldDefAndDeclaringTypeDict<DelegateInitInfo> createDelegateInitInfos_v10_r48717(MethodDef method) {
var infos = new FieldDefinitionAndDeclaringTypeDict<DelegateInitInfo>(); var infos = new FieldDefAndDeclaringTypeDict<DelegateInitInfo>();
var instrs = method.Body.Instructions; var instrs = method.Body.Instructions;
for (int i = 0; i < instrs.Count - 1; i++) { for (int i = 0; i < instrs.Count - 1; i++) {
var ldtoken = instrs[i]; var ldtoken = instrs[i];
@ -947,8 +946,8 @@ namespace de4dot.code.deobfuscators.Confuser {
return infos; return infos;
} }
static FieldDefinitionAndDeclaringTypeDict<List<MethodDef>> createFieldToMethodsDictionary(TypeDef type) { static FieldDefAndDeclaringTypeDict<List<MethodDef>> createFieldToMethodsDictionary(TypeDef type) {
var dict = new FieldDefinitionAndDeclaringTypeDict<List<MethodDef>>(); var dict = new FieldDefAndDeclaringTypeDict<List<MethodDef>>();
foreach (var method in type.Methods) { foreach (var method in type.Methods) {
if (!method.IsStatic || method.Body == null || method.Name == ".cctor") if (!method.IsStatic || method.Body == null || method.Name == ".cctor")
continue; continue;
@ -1123,5 +1122,11 @@ namespace de4dot.code.deobfuscators.Confuser {
default: throw new ApplicationException("Invalid version"); default: throw new ApplicationException("Invalid version");
} }
} }
public void Dispose() {
if (x86emu != null)
x86emu.Dispose();
x86emu = null;
}
} }
} }

View File

@ -20,10 +20,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using de4dot.PE; using dot10.IO;
namespace de4dot.code.deobfuscators.Confuser { namespace de4dot.code.deobfuscators.Confuser {
class x86Emulator { class x86Emulator : IDisposable {
// Confuser 1.7 r73740 - r73822 // Confuser 1.7 r73740 - r73822
static readonly byte[] prolog1 = new byte[] { static readonly byte[] prolog1 = new byte[] {
0x8B, 0x44, 0x24, 0x04, 0x53, 0x50, 0x8B, 0x44, 0x24, 0x04, 0x53, 0x50,
@ -42,8 +42,8 @@ namespace de4dot.code.deobfuscators.Confuser {
0x5E, 0x5F, 0x5B, 0xC3, 0x5E, 0x5F, 0x5B, 0xC3,
}; };
PeImage peImage; MyPEImage peImage;
BinaryReader reader; IBinaryReader reader;
uint[] args; uint[] args;
int nextArgIndex; int nextArgIndex;
uint[] regs = new uint[8]; uint[] regs = new uint[8];
@ -121,8 +121,8 @@ namespace de4dot.code.deobfuscators.Confuser {
} }
} }
public x86Emulator(PeImage peImage) { public x86Emulator(byte[] fileData) {
this.peImage = peImage; this.peImage = new MyPEImage(fileData);
this.reader = peImage.Reader; this.reader = peImage.Reader;
} }
@ -133,7 +133,7 @@ namespace de4dot.code.deobfuscators.Confuser {
public uint emulate(uint rva, uint[] args) { public uint emulate(uint rva, uint[] args) {
initialize(args); initialize(args);
reader.BaseStream.Position = peImage.rvaToOffset(rva); reader.Position = peImage.rvaToOffset(rva);
byte[] prolog, epilog; byte[] prolog, epilog;
if (isBytes(prolog1)) { if (isBytes(prolog1)) {
prolog = prolog1; prolog = prolog1;
@ -145,7 +145,7 @@ namespace de4dot.code.deobfuscators.Confuser {
} }
else else
throw new ApplicationException(string.Format("Missing prolog @ RVA {0:X8}", rva)); throw new ApplicationException(string.Format("Missing prolog @ RVA {0:X8}", rva));
reader.BaseStream.Position += prolog.Length; reader.Position += prolog.Length;
while (!isBytes(epilog)) while (!isBytes(epilog))
emulate(); emulate();
@ -161,7 +161,7 @@ namespace de4dot.code.deobfuscators.Confuser {
} }
bool isBytes(IList<byte> bytes) { bool isBytes(IList<byte> bytes) {
long oldPos = reader.BaseStream.Position; long oldPos = reader.Position;
bool result = true; bool result = true;
for (int i = 0; i < bytes.Count; i++) { for (int i = 0; i < bytes.Count; i++) {
if (bytes[i] != reader.ReadByte()) { if (bytes[i] != reader.ReadByte()) {
@ -169,7 +169,7 @@ namespace de4dot.code.deobfuscators.Confuser {
break; break;
} }
} }
reader.BaseStream.Position = oldPos; reader.Position = oldPos;
return result; return result;
} }
@ -303,5 +303,12 @@ namespace de4dot.code.deobfuscators.Confuser {
if (mod != 3) if (mod != 3)
throw new ApplicationException("Memory operand"); throw new ApplicationException("Memory operand");
} }
public void Dispose() {
if (peImage != null)
peImage.Dispose();
peImage = null;
reader = null;
}
} }
} }