Support some older MC version

This commit is contained in:
de4dot 2012-02-22 12:14:15 +01:00
parent 435d3303c3
commit 59ee55105d
2 changed files with 36 additions and 15 deletions

View File

@ -35,10 +35,10 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
uint rvaDispl1; uint rvaDispl1;
uint rvaDispl2; uint rvaDispl2;
public PeHeader(PeImage peImage) { public PeHeader(MainType mainType, PeImage peImage) {
headerData = getPeHeaderData(peImage); headerData = getPeHeaderData(peImage);
if (peImage.readUInt32(0x2008) != 0x48) { if (!mainType.IsOld && peImage.readUInt32(0x2008) != 0x48) {
rvaDispl1 = readUInt32(0x0FB0) ^ XOR_KEY; rvaDispl1 = readUInt32(0x0FB0) ^ XOR_KEY;
rvaDispl2 = readUInt32(0x0FB4) ^ XOR_KEY; rvaDispl2 = readUInt32(0x0FB4) ^ XOR_KEY;
} }
@ -98,10 +98,6 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
this.data = peImage.readBytes(peHeader.getMcHeaderRva(), 0x2000); this.data = peImage.readBytes(peHeader.getMcHeaderRva(), 0x2000);
} }
public bool hasMagic(int offset, uint magic1, uint magic2) {
return readUInt32(offset) == magic1 && readUInt32(offset + 4) == magic2;
}
public byte readByte(int offset) { public byte readByte(int offset) {
return data[offset]; return data[offset];
} }
@ -129,6 +125,12 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
static EncryptionInfo[] encryptionInfos_Rva900h = new EncryptionInfo[] { static EncryptionInfo[] encryptionInfos_Rva900h = new EncryptionInfo[] {
// PE header timestamp // PE header timestamp
// 482384FB = Thu, 08 May 2008 22:55:55 (3.36)
new EncryptionInfo {
MagicLo = 0xAA98B387,
MagicHi = 0x1E8EECA3,
Version = EncryptionVersion.V1,
},
// 4C622357 = Wed, 11 Aug 2010 04:13:11 // 4C622357 = Wed, 11 Aug 2010 04:13:11
// 4C6220EC = Wed, 11 Aug 2010 04:02:52 // 4C6220EC = Wed, 11 Aug 2010 04:02:52
// 4A5EEC64 = Thu, 16 Jul 2009 09:01:24 // 4A5EEC64 = Thu, 16 Jul 2009 09:01:24
@ -162,6 +164,12 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
}; };
static EncryptionInfo[] encryptionInfos_McHeader8C0h = new EncryptionInfo[] { static EncryptionInfo[] encryptionInfos_McHeader8C0h = new EncryptionInfo[] {
// 482384FB = Thu, 08 May 2008 22:55:55 (3.36)
new EncryptionInfo {
MagicLo = 0x6A713B13,
MagicHi = 0xD72B891F,
Version = EncryptionVersion.V1,
},
// 4DFA3D5D = Thu, 16 Jun 2011 17:29:01 // 4DFA3D5D = Thu, 16 Jun 2011 17:29:01
// 4DC2FE0C = Thu, 05 May 2011 19:44:12 // 4DC2FE0C = Thu, 05 May 2011 19:44:12
// 4DC2FC75 = Thu, 05 May 2011 19:37:25 // 4DC2FC75 = Thu, 05 May 2011 19:37:25
@ -185,6 +193,7 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
}; };
class MethodInfos { class MethodInfos {
MainType mainType;
PeImage peImage; PeImage peImage;
PeHeader peHeader; PeHeader peHeader;
McHeader mcHeader; McHeader mcHeader;
@ -206,7 +215,8 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
} }
} }
public MethodInfos(PeImage peImage, PeHeader peHeader, McHeader mcHeader) { public MethodInfos(MainType mainType, PeImage peImage, PeHeader peHeader, McHeader mcHeader) {
this.mainType = mainType;
this.peImage = peImage; this.peImage = peImage;
this.peHeader = peHeader; this.peHeader = peHeader;
this.mcHeader = mcHeader; this.mcHeader = mcHeader;
@ -221,8 +231,10 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
} }
static uint getStructSize(McHeader mcHeader) { static uint getStructSize(McHeader mcHeader) {
uint magicLo = mcHeader.readUInt32(0x8C0);
uint magicHi = mcHeader.readUInt32(0x8C4);
foreach (var info in encryptionInfos_McHeader8C0h) { foreach (var info in encryptionInfos_McHeader8C0h) {
if (mcHeader.hasMagic(0x08C0, info.MagicLo, info.MagicHi)) if (magicLo == info.MagicLo && magicHi == info.MagicHi)
return 0xC + 6 * ENCRYPTED_DATA_INFO_SIZE; return 0xC + 6 * ENCRYPTED_DATA_INFO_SIZE;
} }
return 0xC + 3 * ENCRYPTED_DATA_INFO_SIZE; return 0xC + 3 * ENCRYPTED_DATA_INFO_SIZE;
@ -352,7 +364,7 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
throw new ApplicationException("Invalid number of encrypted methods"); throw new ApplicationException("Invalid number of encrypted methods");
xorKey = (uint)numMethods; xorKey = (uint)numMethods;
uint rvaDispl = peImage.readUInt32(0x2008) != 0x48 ? 0x1000U : 0; uint rvaDispl = !mainType.IsOld && peImage.readUInt32(0x2008) != 0x48 ? 0x1000U : 0;
int numEncryptedDataInfos = ((int)structSize - 0xC) / ENCRYPTED_DATA_INFO_SIZE; int numEncryptedDataInfos = ((int)structSize - 0xC) / ENCRYPTED_DATA_INFO_SIZE;
var encryptedDataInfos = new byte[numEncryptedDataInfos][]; var encryptedDataInfos = new byte[numEncryptedDataInfos][];
@ -521,7 +533,7 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
public bool decrypt(byte[] fileData, ref Dictionary<uint, DumpedMethod> dumpedMethods) { public bool decrypt(byte[] fileData, ref Dictionary<uint, DumpedMethod> dumpedMethods) {
var peImage = new PeImage(fileData); var peImage = new PeImage(fileData);
var peHeader = new PeHeader(peImage); var peHeader = new PeHeader(mainType, peImage);
var mcHeader = new McHeader(peImage, peHeader); var mcHeader = new McHeader(peImage, peHeader);
dumpedMethods = decryptMethods(peImage, peHeader, mcHeader); dumpedMethods = decryptMethods(peImage, peHeader, mcHeader);
@ -536,7 +548,7 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
Dictionary<uint, DumpedMethod> decryptMethods(PeImage peImage, PeHeader peHeader, McHeader mcHeader) { Dictionary<uint, DumpedMethod> decryptMethods(PeImage peImage, PeHeader peHeader, McHeader mcHeader) {
var dumpedMethods = new Dictionary<uint, DumpedMethod>(); var dumpedMethods = new Dictionary<uint, DumpedMethod>();
var methodInfos = new MethodInfos(peImage, peHeader, mcHeader); var methodInfos = new MethodInfos(mainType, peImage, peHeader, mcHeader);
methodInfos.initializeInfos(); methodInfos.initializeInfos();
var metadataTables = peImage.Cor20Header.createMetadataTables(); var metadataTables = peImage.Cor20Header.createMetadataTables();

View File

@ -27,6 +27,11 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
ModuleDefinition module; ModuleDefinition module;
TypeDefinition mcType; TypeDefinition mcType;
ModuleReference mcModule1, mcModule2; ModuleReference mcModule1, mcModule2;
bool isOld;
public bool IsOld {
get { return isOld; }
}
public TypeDefinition Type { public TypeDefinition Type {
get { return mcType; } get { return mcType; }
@ -88,12 +93,14 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
continue; continue;
ModuleReference module1, module2; ModuleReference module1, module2;
if (!checkType(method.DeclaringType, out module1, out module2)) bool isOldTmp;
if (!checkType(method.DeclaringType, out module1, out module2, out isOldTmp))
return; return;
mcType = method.DeclaringType; mcType = method.DeclaringType;
mcModule1 = module1; mcModule1 = module1;
mcModule2 = module2; mcModule2 = module2;
isOld = isOldTmp;
break; break;
} }
} }
@ -110,8 +117,9 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
return null; return null;
} }
static bool checkType(TypeDefinition type, out ModuleReference module1, out ModuleReference module2) { static bool checkType(TypeDefinition type, out ModuleReference module1, out ModuleReference module2, out bool isOld) {
module1 = module2 = null; module1 = module2 = null;
isOld = false;
if (DotNetUtils.getMethod(type, "Startup") == null) if (DotNetUtils.getMethod(type, "Startup") == null)
return false; return false;
@ -122,8 +130,9 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
return false; return false;
if (getPinvokeList(pinvokes, "MainDLL") == null) if (getPinvokeList(pinvokes, "MainDLL") == null)
return false; return false;
if (getPinvokeList(pinvokes, "GetModuleBase") == null)
return false; // Newer versions (3.4+ ???) also have GetModuleBase()
isOld = getPinvokeList(pinvokes, "GetModuleBase") == null;
module1 = pinvokeList[0].PInvokeInfo.Module; module1 = pinvokeList[0].PInvokeInfo.Module;
module2 = pinvokeList[1].PInvokeInfo.Module; module2 = pinvokeList[1].PInvokeInfo.Module;