[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