Support latest MaxtoCode version

This commit is contained in:
de4dot 2012-12-20 01:34:16 +01:00
parent 35849b0f9b
commit a7fdbd4206
3 changed files with 48 additions and 5 deletions

View File

@ -81,6 +81,12 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
MagicHi = 0xF28EDDA3,
Version = EncryptionVersion.V5,
},
// 50A0963C = Mon, 12 Nov 2012 06:25:00
new EncryptionInfo {
MagicLo = 0xBA683B87,
MagicHi = 0xF28ECDA3,
Version = EncryptionVersion.V6,
},
};
public static readonly EncryptionInfo[] McKey8C0h = new EncryptionInfo[] {

View File

@ -50,6 +50,7 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
readonly Decrypt[] decryptHandlersV5a;
readonly Decrypt[] decryptHandlersV5b;
readonly Decrypt[] decryptHandlersV5c;
readonly Decrypt[] decryptHandlersV6a;
public class DecryptedMethodInfo {
public uint bodyRva;
@ -74,6 +75,7 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
decryptHandlersV5a = new Decrypt[] { decrypt4a, decrypt2a, decrypt3a, decrypt1a, decrypt5, decrypt6, decrypt7 };
decryptHandlersV5b = new Decrypt[] { decrypt4b, decrypt2b, decrypt3b, decrypt1b, decrypt6, decrypt7, decrypt5 };
decryptHandlersV5c = new Decrypt[] { decrypt4c, decrypt2c, decrypt3c, decrypt1c, decrypt6, decrypt7, decrypt5 };
decryptHandlersV6a = new Decrypt[] { decrypt4d, decrypt2d, decrypt3d, decrypt1d, decrypt6, decrypt7, decrypt5 };
structSize = getStructSize(mcKey);
@ -173,6 +175,9 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
decrypters.Add(new Decrypter(decryptHandlersV5b));
decrypters.Add(new Decrypter(decryptHandlersV5c));
break;
case EncryptionVersion.V6:
decrypters.Add(new Decrypter(decryptHandlersV6a));
break;
case EncryptionVersion.Unknown:
default:
@ -287,6 +292,10 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
return decrypt1(encrypted, 6, 0, 0x1000);
}
byte[] decrypt1d(byte[] encrypted) {
return decrypt1(encrypted, 5, 5, 0x500);
}
byte[] decrypt1(byte[] encrypted, int keyStart, int keyReset, int keyEnd) {
var decrypted = new byte[encrypted.Length];
for (int i = 0, ki = keyStart; i < decrypted.Length; i++) {
@ -309,6 +318,10 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
return decrypt2(encrypted, 0x00FA + 0x24);
}
byte[] decrypt2d(byte[] encrypted) {
return decrypt2(encrypted, 0x00FA + 7);
}
byte[] decrypt2(byte[] encrypted, int offset) {
if ((encrypted.Length & 7) != 0)
throw new ApplicationException("Invalid encryption #2 length");
@ -344,6 +357,10 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
return decrypt3(encrypted, 0x015E + 0x28);
}
byte[] decrypt3d(byte[] encrypted) {
return decrypt3(encrypted, 0x015E + 8);
}
static readonly byte[] decrypt3Shifts = new byte[16] { 5, 11, 14, 21, 6, 20, 17, 29, 4, 10, 3, 2, 7, 1, 26, 18 };
byte[] decrypt3(byte[] encrypted, int offset) {
if ((encrypted.Length & 7) != 0)
@ -385,6 +402,10 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
return decrypt4(encrypted, 5, 0, 0x2000);
}
byte[] decrypt4d(byte[] encrypted) {
return decrypt4(encrypted, 0x0B, 0x0B, 0x1000);
}
byte[] decrypt4(byte[] encrypted, int keyStart, int keyReset, int keyEnd) {
var decrypted = new byte[encrypted.Length / 3 * 2 + 1];
@ -398,7 +419,7 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
decrypted[j++] = (byte)(((encrypted[i + 1] ^ k2) << 4) + ((encrypted[i + 2] ^ k3) & 0x0F));
i += 3;
ki += 4;
if (ki == keyEnd)
if (ki >= keyEnd)
ki = keyReset;
}

View File

@ -27,13 +27,13 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
V3,
V4,
V5,
V6,
}
class PeHeader {
const int XOR_KEY = 0x7ABF931;
EncryptionVersion version;
byte[] headerData;
uint xorKey;
public EncryptionVersion EncryptionVersion {
get { return version; }
@ -42,15 +42,31 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
public PeHeader(MainType mainType, MyPEImage peImage) {
uint headerOffset;
version = getHeaderOffsetAndVersion(peImage, out headerOffset);
switch (version) {
case EncryptionVersion.V1:
case EncryptionVersion.V2:
case EncryptionVersion.V3:
case EncryptionVersion.V4:
case EncryptionVersion.V5:
default:
xorKey = 0x7ABF931;
break;
case EncryptionVersion.V6:
xorKey = 0x7ABA931;
break;
}
headerData = peImage.offsetReadBytes(headerOffset, 0x1000);
}
public uint getMcKeyRva() {
return getRva(0x0FFC, XOR_KEY);
return getRva(0x0FFC, xorKey);
}
public uint getRva(int offset, uint xorKey) {
return (readUInt32(offset) ^ xorKey);
return readUInt32(offset) ^ xorKey;
}
public uint readUInt32(int offset) {