[Mono-devel-list] Reading a PE Header
Zac Bowling
zac at zacbowling.com
Sat Apr 2 18:04:04 EST 2005
If anyone is interested, I've translated the headers in the WIN32 sdk
for the PE headers.
You can cast these to a byte array you read from wherever in an unsafe
block like this where i check to see if a file is managed or not in C#.
----
byte[] Data = new byte[4096];
//Read data into the byte array some how...
unsafe
{
fixed(byte *p_Data = Data)
{
bool m_IsManaged;
ImageDosHeader *idh = (ImageDosHeader *)p_Data;
IMAGE_NT_HEADERS32 *inhs =
(IMAGE_NT_HEADERS32 *)(idh->lfanew + p_Data);
MachineType m_MachineType = (MachineType)inhs->FileHeader.Machine;
if(inhs->OptionalHeader.Magic == 0x20b)
{
if(((IMAGE_NT_HEADERS64 *)inhs)->OptionalHeader.DataDirectory.Size>0)
m_IsManaged = true;
}
else
{
if(inhs->OptionalHeader.DataDirectory.Size > 0)
m_IsManaged = true;
}
}
}
----
thats it! Enjoy....
Zac Bowling
http://www.zacbowling.com
----
using System;
using System.IO;
namespace Win32PE
{
[StructLayout( LayoutKind.Explicit )]
public struct ImageDosHeader
{
[FieldOffset(0)]
public ushort magic; // WORD - Magic number
[FieldOffset(2)]
public ushort cblp; // WORD - Bytes on last page of file
[FieldOffset(4)]
public ushort cp; // WORD - Pages in file
[FieldOffset(6)]
public ushort crlc; // WORD - Relocations
[FieldOffset(8)]
public ushort cparhdr; // WORD - Size of header in paragraphs
[FieldOffset(10)]
public ushort minalloc; // WORD - Minimum extra paragraphs needed
[FieldOffset(12)]
public ushort maxalloc; // WORD - Maximum extra paragraphs needed
[FieldOffset(14)]
public ushort ss; // WORD - Initial (relative) SS value
[FieldOffset(16)]
public ushort sp; // WORD - Initial SP value
[FieldOffset(18)]
public ushort csum; // WORD - Checksum
[FieldOffset(20)]
public ushort ip; // WORD - Initial IP value
[FieldOffset(22)]
public ushort cs; // WORD - Initial (relative) CS value
[FieldOffset(24)]
public ushort lfarlc; // WORD - File address of relocation table
[FieldOffset(26)]
public ushort ovno; // WORD - Overlay number
//[FieldOffset(28)] // WORD[4] = 2x4 = 8
// public ushort[] e_res; // WORD[4] - Reserved words
[FieldOffset(36)]
public ushort oemid; // WORD - OEM identifier (for e_oeminfo)
[FieldOffset(38)]
public ushort oeminfo; // WORD - OEM information (e_oemid
specific)
//[FieldOffset(40)] // WORD[10] = 2x10 = 20
//public ushort[] d_res2; // WORD[10] - Reserved words
[FieldOffset(60)]
public int lfanew; // LONG - File address of new exe header
}
[StructLayout( LayoutKind.Explicit )]
public struct IMAGE_NT_HEADERS32
{
[FieldOffset(0)] public uint Signature;
[FieldOffset(4)] public IMAGE_FILE_HEADER FileHeader;
[FieldOffset(24)] public IMAGE_OPTIONAL_HEADER32 OptionalHeader;
}
[StructLayout( LayoutKind.Explicit )]
public struct IMAGE_NT_HEADERS64
{
[FieldOffset(0)] public uint Signature;
[FieldOffset(4)] public IMAGE_FILE_HEADER FileHeader;
[FieldOffset(24)] public IMAGE_OPTIONAL_HEADER64 OptionalHeader;
}
[StructLayout( LayoutKind.Explicit )]
public struct IMAGE_FILE_HEADER
{
[FieldOffset(0)] public ushort Machine;
[FieldOffset(2)] public ushort NumberOfSections;
[FieldOffset(4)] public uint TimeDateStamp;
[FieldOffset(8)] public uint PointerToSymbolTable;
[FieldOffset(12)] public uint NumberOfSymbols;
[FieldOffset(16)] public ushort SizeOfOptionalHeader;
[FieldOffset(18)] public ushort Characteristics;
}
[StructLayout( LayoutKind.Explicit )]
public struct IMAGE_OPTIONAL_HEADER32
{
public ushort Magic;
public byte MajorLinkerVersion;
public byte MinorLinkerVersion;
public uint SizeOfCode;
public uint SizeOfInitializedData;
public uint SizeOfUninitializedData;
public uint AddressOfEntryPoint;
public uint BaseOfCode;
public uint BaseOfData;
public uint ImageBase;
public uint SectionAlignment;
public uint FileAlignment;
public ushort MajorOperatingSystemVersion;
public ushort MinorOperatingSystemVersion;
public ushort MajorImageVersion;
public ushort MinorImageVersion;
public ushort MajorSubsystemVersion;
public ushort MinorSubsystemVersion;
public uint Win32VersionValue;
public uint SizeOfImage;
public uint SizeOfHeaders;
public uint CheckSum;
public ushort Subsystem;
public ushort DllCharacteristics;
public uint SizeOfStackReserve;
public uint SizeOfStackCommit;
public uint SizeOfHeapReserve;
public uint SizeOfHeapCommit;
public uint LoaderFlags;
public uint NumberOfRvaAndSizes;
public IMAGE_DATA_DIRECTORY[] DataDirectory;
}
[StructLayout( LayoutKind.Explicit )]
public struct IMAGE_OPTIONAL_HEADER64
{
public ushort Magic;
public byte MajorLinkerVersion;
public byte MinorLinkerVersion;
public uint SizeOfCode;
public uint SizeOfInitializedData;
public uint SizeOfUninitializedData;
public uint AddressOfEntryPoint;
public uint BaseOfCode;
public ulong ImageBase;
public uint SectionAlignment;
public uint FileAlignment;
public ushort MajorOperatingSystemVersion;
public ushort MinorOperatingSystemVersion;
public ushort MajorImageVersion;
public ushort MinorImageVersion;
public ushort MajorSubsystemVersion;
public ushort MinorSubsystemVersion;
public uint Win32VersionValue;
public uint SizeOfImage;
public uint SizeOfHeaders;
public uint CheckSum;
public ushort Subsystem;
public ushort DllCharacteristics;
public ulong SizeOfStackReserve;
public ulong SizeOfStackCommit;
public ulong SizeOfHeapReserve;
public ulong SizeOfHeapCommit;
public uint LoaderFlags;
public uint NumberOfRvaAndSizes;
public IMAGE_DATA_DIRECTORY[] DataDirectory;
}
[StructLayout( LayoutKind.Explicit )]
public struct IMAGE_DATA_DIRECTORY
{
public uint VirtualAddress;
public uint Size;
}
public enum MachineType
{
Native = 0,
I386 = 0x014c,
Itanium = 0x0200,
x64 = 0x8664
}
}
More information about the Mono-devel-list
mailing list