Merge branch 'master' into cs

This commit is contained in:
de4dot 2012-04-26 19:33:28 +02:00
commit 9754b01ba9
2 changed files with 68 additions and 39 deletions

View File

@ -71,6 +71,14 @@ namespace de4dot.PE {
init();
}
public SectionHeader findSection(string displayName) {
foreach (var section in sectionHeaders) {
if (section.displayName == displayName)
return section;
}
return null;
}
void seek(uint position) {
reader.BaseStream.Position = position;
}

View File

@ -36,17 +36,17 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
class PeHeader {
const int XOR_KEY = 0x7ABF931;
EncryptionVersion version;
byte[] headerData;
uint rvaDispl1;
uint rvaDispl2;
public EncryptionVersion EncryptionVersion {
get { return version; }
}
public PeHeader(MainType mainType, PeImage peImage) {
headerData = getPeHeaderData(peImage);
if (!mainType.IsOld && peImage.readUInt32(0x2008) != 0x48) {
rvaDispl1 = readUInt32(0x0FB0) ^ XOR_KEY;
rvaDispl2 = readUInt32(0x0FB4) ^ XOR_KEY;
}
uint headerOffset;
version = getHeaderOffsetAndVersion(peImage, out headerOffset);
headerData = peImage.offsetReadBytes(headerOffset, 0x1000);
}
public uint getMcKeyRva() {
@ -54,39 +54,50 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
}
public uint getRva1(int offset, uint xorKey) {
return (readUInt32(offset) ^ xorKey) - rvaDispl1;
return (readUInt32(offset) ^ xorKey);
}
public uint getRva2(int offset, uint xorKey) {
return (readUInt32(offset) ^ xorKey) - rvaDispl2;
return (readUInt32(offset) ^ xorKey);
}
public uint readUInt32(int offset) {
return BitConverter.ToUInt32(headerData, offset);
}
static byte[] getPeHeaderData(PeImage peImage) {
var data = new byte[0x1000];
static EncryptionVersion getHeaderOffsetAndVersion(PeImage peImage, out uint headerOffset) {
headerOffset = 0;
var firstSection = peImage.Sections[0];
readTo(peImage, data, 0, 0, firstSection.pointerToRawData);
var version = getVersion(peImage, headerOffset);
if (version != EncryptionVersion.Unknown)
return version;
foreach (var section in peImage.Sections) {
if (section.virtualAddress >= data.Length)
continue;
int offset = (int)section.virtualAddress;
readTo(peImage, data, offset, section.pointerToRawData, section.sizeOfRawData);
var section = peImage.findSection(".rsrc");
if (section == null)
return EncryptionVersion.Unknown;
headerOffset = section.pointerToRawData;
uint end = section.pointerToRawData + section.sizeOfRawData - 0x1000 + 1;
while (headerOffset < end) {
version = getVersion(peImage, headerOffset);
if (version != EncryptionVersion.Unknown)
return version;
headerOffset++;
}
return data;
return EncryptionVersion.Unknown;
}
static void readTo(PeImage peImage, byte[] data, int destOffset, uint imageOffset, uint maxLength) {
if (destOffset > data.Length)
return;
int len = Math.Min(data.Length - destOffset, (int)maxLength);
var newData = peImage.offsetReadBytes(imageOffset, len);
Array.Copy(newData, 0, data, destOffset, newData.Length);
static EncryptionVersion getVersion(PeImage peImage, uint headerOffset) {
uint m1lo = peImage.offsetReadUInt32(headerOffset + 0x900);
uint m1hi = peImage.offsetReadUInt32(headerOffset + 0x904);
foreach (var info in encryptionInfos_Rva900h) {
if (info.MagicLo == m1lo && info.MagicHi == m1hi)
return info.Version;
}
return EncryptionVersion.Unknown;
}
}
@ -118,6 +129,7 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
V2,
V3,
V4,
V5,
}
class EncryptionInfo {
@ -126,7 +138,7 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
public EncryptionVersion Version { get; set; }
}
static EncryptionInfo[] encryptionInfos_Rva900h = new EncryptionInfo[] {
static readonly EncryptionInfo[] encryptionInfos_Rva900h = new EncryptionInfo[] {
// PE header timestamp
// 462FA2D2 = Wed, 25 Apr 2007 18:49:54 (3.20)
new EncryptionInfo {
@ -176,9 +188,15 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
MagicHi = 0xF28EE0A3,
Version = EncryptionVersion.V4,
},
// 4F8E262C = Wed, 18 Apr 2012 02:25:48
new EncryptionInfo {
MagicLo = 0xBA983B87,
MagicHi = 0xF28EDDA3,
Version = EncryptionVersion.V5,
},
};
static EncryptionInfo[] encryptionInfos_McKey8C0h = new EncryptionInfo[] {
static readonly EncryptionInfo[] encryptionInfos_McKey8C0h = new EncryptionInfo[] {
// 462FA2D2 = Wed, 25 Apr 2007 18:49:54 (3.20)
new EncryptionInfo {
MagicLo = 0x6AA13B13,
@ -217,6 +235,12 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
MagicHi = 0xD72B8A1F,
Version = EncryptionVersion.V4,
},
// 4F8E262C = Wed, 18 Apr 2012 02:25:48
new EncryptionInfo {
MagicLo = 0xAA731B13,
MagicHi = 0xD723891F,
Version = EncryptionVersion.V5,
},
};
class MethodInfos {
@ -268,8 +292,9 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
}
EncryptionVersion getVersion() {
uint m1lo = peHeader.readUInt32(0x900);
uint m1hi = peHeader.readUInt32(0x904);
if (peHeader.EncryptionVersion != EncryptionVersion.Unknown)
return peHeader.EncryptionVersion;
uint m2lo = mcKey.readUInt32(0x8C0);
uint m2hi = mcKey.readUInt32(0x8C4);
@ -278,12 +303,7 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
return info.Version;
}
foreach (var info in encryptionInfos_Rva900h) {
if (info.MagicLo == m1lo && info.MagicHi == m1hi)
return info.Version;
}
Log.w("Could not detect MC version. Magic1: {0:X8} {1:X8}, Magic2: {2:X8} {3:X8}", m1lo, m1hi, m2lo, m2hi);
Log.w("Could not detect MC version. Magic2: {0:X8} {1:X8}", m2lo, m2hi);
return EncryptionVersion.Unknown;
}
@ -354,12 +374,14 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
static readonly int[] typeToTypesV2 = new int[] { -1, 3, 2, 1, 4, 5, 6, 7 };
static readonly int[] typeToTypesV3 = new int[] { -1, 1, 2, 3, 4, 5, 6, 7 };
static readonly int[] typeToTypesV4 = new int[] { -1, 2, 1, 3, 4, 5, 6, 7 };
static readonly int[] typeToTypesV5 = new int[] { -1, 4, 2, 3, 1, 5, 6, 7 };
void initializeDecrypter() {
switch (getVersion()) {
case EncryptionVersion.V1: decrypter = new Decrypter(this, typeToTypesV1); break;
case EncryptionVersion.V2: decrypter = new Decrypter(this, typeToTypesV2); break;
case EncryptionVersion.V3: decrypter = new Decrypter(this, typeToTypesV3); break;
case EncryptionVersion.V4: decrypter = new Decrypter(this, typeToTypesV4); break;
case EncryptionVersion.V5: decrypter = new Decrypter(this, typeToTypesV5); break;
case EncryptionVersion.Unknown:
default:
@ -375,15 +397,14 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
throw new ApplicationException("Invalid number of encrypted methods");
xorKey = (uint)numMethods;
uint rvaDispl = !mainType.IsOld && peImage.readUInt32(0x2008) != 0x48 ? 0x1000U : 0;
int numEncryptedDataInfos = ((int)structSize - 0xC) / ENCRYPTED_DATA_INFO_SIZE;
var encryptedDataInfos = new byte[numEncryptedDataInfos][];
uint offset = 8;
for (int i = 0; i < numMethods; i++, offset += structSize) {
uint methodBodyRva = readEncryptedUInt32(offset) - rvaDispl;
uint methodBodyRva = readEncryptedUInt32(offset);
uint totalSize = readEncryptedUInt32(offset + 4);
uint methodInstructionRva = readEncryptedUInt32(offset + 8) - rvaDispl;
uint methodInstructionRva = readEncryptedUInt32(offset + 8);
var decryptedData = new byte[totalSize];