public static Extract IsBlockaPE(byte[] block)
{
Extract extracted_struct = new Extract();
if (BitConverter.ToInt16(block, 0) != 0x5A4D)
return null;
var headerOffset = BitConverter.ToInt32(block, 0x3C);
if (headerOffset > 3000)
{
// bad probably
return null;
}
if (BitConverter.ToInt32(block, headerOffset) != 0x00004550)
return null;
var pos = headerOffset + 6;
extracted_struct.NumberOfSections = BitConverter.ToInt16(block, pos); pos += 2;
extracted_struct.SectionPosOffsets = new List<MiniSection>();
//pos += 2;
extracted_struct.TimeStamp = BitConverter.ToUInt32(block, pos); pos += 4;
pos += 8;
extracted_struct.secOff = BitConverter.ToUInt16(block, pos); pos += 2;
pos += 2;
var magic = BitConverter.ToUInt16(block, pos); pos += 2;
extracted_struct.Is64 = magic == 0x20b;
if (extracted_struct.Is64)
{
pos += 22;
extracted_struct.ImageBaseOffset = pos;
extracted_struct.ImageBase = BitConverter.ToUInt64(block, pos); pos += 8;
}
else
{
pos += 26;
extracted_struct.ImageBaseOffset = pos;
extracted_struct.ImageBase = BitConverter.ToUInt32(block, pos); pos += 4;
}
extracted_struct.SectionAlignment = BitConverter.ToUInt32(block, pos); pos += 4;
extracted_struct.FileAlignment = BitConverter.ToUInt32(block, pos); pos += 4;
pos += 16;
extracted_struct.SizeOfImage = BitConverter.ToUInt32(block, pos); pos += 4;
extracted_struct.SizeOfHeaders = BitConverter.ToUInt32(block, pos); pos += 4;
// checksum
pos += 4;
// subsys/characteristics
pos += 4;
// SizeOf/Stack/Heap/Reserve/Commit
if (extracted_struct.Is64)
pos += 32;
else
pos += 16;
// LoaderFlags
pos += 4;
// NumberOfRvaAndSizes
pos += 4;
// 16 DataDirectory entries, each is 8 bytes 4byte VA, 4byte Size
// we care about #6 since it's where we will find the GUID
pos += 6 * 8;
extracted_struct.DebugDirPos = BitConverter.ToUInt32(block, pos); pos += 4;
extracted_struct.DebugDirSize = BitConverter.ToUInt32(block, pos); pos += 4;
var CurrEnd = extracted_struct.SizeOfHeaders;
/// implicit section for header
extracted_struct.SectionPosOffsets.Add(new MiniSection { VirtualSize = 0x1000, RawFileSize = 0x400, RawFilePointer = 0, VirtualOffset = 0, Name = "PEHeader" });
// get to sections
pos = headerOffset + (extracted_struct.Is64 ? 0x108 : 0xF8);
for (int i = 0; i < extracted_struct.NumberOfSections; i++)
{
/*var rawStr = BitConverter.ToString(block, pos, 8); */
var rawStr = new String(
new char[8] { (char) block[pos], (char) block[pos + 1], (char) block[pos + 2], (char) block[pos + 3],
(char) block[pos + 4], (char) block[pos + 5], (char) block[pos + 6], (char) block[pos + 7] }); pos += 8;
var secStr = new string(rawStr.Where(c => char.IsLetterOrDigit(c) || char.IsPunctuation(c)).ToArray());
var Size = BitConverter.ToUInt32(block, pos); pos += 4;
var Pos = BitConverter.ToUInt32(block, pos); pos += 4;
var rawSize = BitConverter.ToUInt32(block, pos); pos += 4;
var rawPos = BitConverter.ToUInt32(block, pos); pos += 4;
var currSecNfo = new MiniSection { VirtualSize = Size, VirtualOffset = Pos, RawFileSize = rawSize, RawFilePointer = rawPos, Name = secStr };
extracted_struct.SectionPosOffsets.Add(currSecNfo);
if (Verbose > 2)
Write($" section [{secStr}] ");
if (secStr.StartsWith(@".reloc", StringComparison.Ordinal))
{
extracted_struct.RelocSize = Size;
extracted_struct.RelocPos = Pos;
}
pos += 0x10;
}
return extracted_struct;
}