de4dot-cex/de4dot.code/deobfuscators/MaxtoCode/PeHeader.cs

112 lines
2.8 KiB
C#
Raw Normal View History

2012-07-21 00:15:40 +08:00
/*
2013-01-02 00:03:16 +08:00
Copyright (C) 2011-2013 de4dot@gmail.com
2012-07-21 00:15:40 +08:00
This file is part of de4dot.
de4dot is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
de4dot is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
namespace de4dot.code.deobfuscators.MaxtoCode {
enum EncryptionVersion {
Unknown,
V1,
V2,
V3,
V4,
V5,
2012-12-20 08:34:16 +08:00
V6,
2012-07-21 00:15:40 +08:00
}
class PeHeader {
EncryptionVersion version;
byte[] headerData;
2012-12-20 08:34:16 +08:00
uint xorKey;
2012-07-21 00:15:40 +08:00
public EncryptionVersion EncryptionVersion {
get { return version; }
}
public PeHeader(MainType mainType, MyPEImage peImage) {
2012-07-21 00:15:40 +08:00
uint headerOffset;
2013-01-19 20:03:57 +08:00
version = GetHeaderOffsetAndVersion(peImage, out headerOffset);
2012-12-20 08:34:16 +08:00
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;
}
2013-01-19 20:03:57 +08:00
headerData = peImage.OffsetReadBytes(headerOffset, 0x1000);
2012-07-21 00:15:40 +08:00
}
2013-01-19 20:03:57 +08:00
public uint GetMcKeyRva() {
return GetRva(0x0FFC, xorKey);
2012-07-21 00:15:40 +08:00
}
2013-01-19 20:03:57 +08:00
public uint GetRva(int offset, uint xorKey) {
return ReadUInt32(offset) ^ xorKey;
2012-07-21 00:15:40 +08:00
}
2013-01-19 20:03:57 +08:00
public uint ReadUInt32(int offset) {
2012-07-21 00:15:40 +08:00
return BitConverter.ToUInt32(headerData, offset);
}
2013-01-19 20:03:57 +08:00
static EncryptionVersion GetHeaderOffsetAndVersion(MyPEImage peImage, out uint headerOffset) {
2012-07-21 00:15:40 +08:00
headerOffset = 0;
2013-01-19 20:03:57 +08:00
var version = GetVersion(peImage, headerOffset);
2012-07-21 00:15:40 +08:00
if (version != EncryptionVersion.Unknown)
return version;
2013-01-19 20:03:57 +08:00
var section = peImage.FindSection(".rsrc");
2012-07-21 00:15:40 +08:00
if (section == null)
return EncryptionVersion.Unknown;
headerOffset = section.PointerToRawData;
uint end = section.PointerToRawData + section.SizeOfRawData - 0x1000 + 1;
2012-07-21 00:15:40 +08:00
while (headerOffset < end) {
2013-01-19 20:03:57 +08:00
version = GetVersion(peImage, headerOffset);
2012-07-21 00:15:40 +08:00
if (version != EncryptionVersion.Unknown)
return version;
headerOffset++;
}
return EncryptionVersion.Unknown;
}
2013-01-19 20:03:57 +08:00
static EncryptionVersion GetVersion(MyPEImage peImage, uint headerOffset) {
uint m1lo = peImage.OffsetReadUInt32(headerOffset + 0x900);
uint m1hi = peImage.OffsetReadUInt32(headerOffset + 0x904);
2012-07-21 00:15:40 +08:00
foreach (var info in EncryptionInfos.Rva900h) {
if (info.MagicLo == m1lo && info.MagicHi == m1hi)
return info.Version;
}
return EncryptionVersion.Unknown;
}
}
}