From a7fdbd4206f719a466d6eade11f4126857fc0b9a Mon Sep 17 00:00:00 2001 From: de4dot Date: Thu, 20 Dec 2012 01:34:16 +0100 Subject: [PATCH] Support latest MaxtoCode version --- .../MaxtoCode/EncryptionInfos.cs | 6 +++++ .../MaxtoCode/MethodsDecrypter.cs | 23 +++++++++++++++++- .../deobfuscators/MaxtoCode/PeHeader.cs | 24 +++++++++++++++---- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/de4dot.code/deobfuscators/MaxtoCode/EncryptionInfos.cs b/de4dot.code/deobfuscators/MaxtoCode/EncryptionInfos.cs index e69b87a4..cf97f3aa 100644 --- a/de4dot.code/deobfuscators/MaxtoCode/EncryptionInfos.cs +++ b/de4dot.code/deobfuscators/MaxtoCode/EncryptionInfos.cs @@ -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[] { diff --git a/de4dot.code/deobfuscators/MaxtoCode/MethodsDecrypter.cs b/de4dot.code/deobfuscators/MaxtoCode/MethodsDecrypter.cs index acd9ea9c..0e8be110 100644 --- a/de4dot.code/deobfuscators/MaxtoCode/MethodsDecrypter.cs +++ b/de4dot.code/deobfuscators/MaxtoCode/MethodsDecrypter.cs @@ -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; } diff --git a/de4dot.code/deobfuscators/MaxtoCode/PeHeader.cs b/de4dot.code/deobfuscators/MaxtoCode/PeHeader.cs index 863180e0..c2432500 100644 --- a/de4dot.code/deobfuscators/MaxtoCode/PeHeader.cs +++ b/de4dot.code/deobfuscators/MaxtoCode/PeHeader.cs @@ -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) {