Skip to content

Instantly share code, notes, and snippets.

@Warpten
Created November 12, 2014 05:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Warpten/3a17f7cb5e1f2eb76b0f to your computer and use it in GitHub Desktop.
Save Warpten/3a17f7cb5e1f2eb76b0f to your computer and use it in GitHub Desktop.
IMAGE_FILE_HEADER
-> NumberOfSections : 0x00000008 (8)
-> TimeDateStamp : 0x54503811 (1414543377)
-> PointerToSymbolTable : 0x00000000 (0)
-> NumberOfSymbols : 0x00000000 (0)
-> SizeOfOptionalHeader : 0x000000E0 (224)
IMAGE_OPTIONAL_HEADER32
-> MajorLinkerVersion : 0x0000000A (10)
-> MinorLinkerVersion : 0x00000000 (0)
-> SizeOfCode : 0x0095A000 (9805824)
-> SizeOfInitializedData : 0x003B6200 (3891712)
-> SizeOfUninitializedData : 0x00000000 (0)
-> AddressOfEntryPoint : 0x0000F742 (63298)
-> BaseOfCode : 0x00001000 (4096)
-> BaseOfData : 0x0095B000 (9809920)
-> ImageBase : 0x00400000 (4194304)
-> SectionAlignment : 0x00001000 (4096)
-> FileAlignment : 0x00000200 (512)
-> MajorOperatingSystemVersion : 0x00000005 (5)
-> MinorOperatingSystemVersion : 0x00000001 (1)
-> MajorImageVersion : 0x00000000 (0)
-> MinorImageVersion : 0x00000000 (0)
-> MajorSubsystemVersion : 0x00000005 (5)
-> MinorSubsystemVersion : 0x00000001 (1)
-> Win32VersionValue : 0x00000000 (0)
-> SizeOfImage : 0x01071000 (17240064)
-> SizeOfHeaders : 0x00000400 (1024)
-> CheckSum : 0x00D1EFD4 (13758420)
-> SizeOfStackReserve : 0x00040000 (262144)
-> SizeOfStackCommit : 0x00008000 (32768)
-> SizeOfHeapReserve : 0x00100000 (1048576)
-> SizeOfHeapCommit : 0x00001000 (4096)
-> LoaderFlags : 0x00000000 (0)
-> NumberOfRvaAndSizes : 0x00000010 (16)
IMAGE_DATA_DIRECTORY[]
IMAGE_DATA_DIRECTORY
-> VirtualAddress : 0x00B566F0 (11888368)
-> Size : 0x00000069 (105)
IMAGE_DATA_DIRECTORY
-> VirtualAddress : 0x00B53778 (11876216)
-> Size : 0x0000017C (380)
IMAGE_DATA_DIRECTORY
-> VirtualAddress : 0x00F76000 (16211968)
-> Size : 0x00057B64 (359268)
IMAGE_DATA_DIRECTORY
-> VirtualAddress : 0x00000000 (0)
-> Size : 0x00000000 (0)
IMAGE_DATA_DIRECTORY
-> VirtualAddress : 0x00D10600 (13698560)
-> Size : 0x00001630 (5680)
IMAGE_DATA_DIRECTORY
-> VirtualAddress : 0x00FCE000 (16572416)
-> Size : 0x0007DA80 (514688)
IMAGE_DATA_DIRECTORY
-> VirtualAddress : 0x0095EF00 (9826048)
-> Size : 0x0000001C (28)
IMAGE_DATA_DIRECTORY
-> VirtualAddress : 0x00000000 (0)
-> Size : 0x00000000 (0)
IMAGE_DATA_DIRECTORY
-> VirtualAddress : 0x00000000 (0)
-> Size : 0x00000000 (0)
IMAGE_DATA_DIRECTORY
-> VirtualAddress : 0x00B37788 (11761544)
-> Size : 0x00000018 (24)
IMAGE_DATA_DIRECTORY
-> VirtualAddress : 0x00B37740 (11761472)
-> Size : 0x00000040 (64)
IMAGE_DATA_DIRECTORY
-> VirtualAddress : 0x00000000 (0)
-> Size : 0x00000000 (0)
IMAGE_DATA_DIRECTORY
-> VirtualAddress : 0x0095B000 (9809920)
-> Size : 0x00000898 (2200)
IMAGE_DATA_DIRECTORY
-> VirtualAddress : 0x00B52FFC (11874300)
-> Size : 0x00000040 (64)
IMAGE_DATA_DIRECTORY
-> VirtualAddress : 0x00000000 (0)
-> Size : 0x00000000 (0)
IMAGE_DATA_DIRECTORY
-> VirtualAddress : 0x00000000 (0)
-> Size : 0x00000000 (0)
IMAGE_SECTION_HEADER
-> Name : .text
-> PhysicalAddress : 0x00959F04 (9805572)
-> VirtualSize : 0x00001000 (4096)
-> VirtualAddress : 0x0095A000 (9805824)
-> SizeOfRawData : 0x00000400 (1024)
-> PointerToRawData : 0x00000000 (0)
-> PointerToRelocations : 0x00000000 (0)
-> PointerToLinenumbers : 0x00000000 (0)
-> NumberOfRelocations : 0x00000020 (32)
-> NumberOfLinenumbers : 0x00006000 (24576)
-> Characteristics : 0x6164722E (1633972782)
IMAGE_SECTION_HEADER
-> Name : .rdata
-> PhysicalAddress : 0x001FB759 (2078553)
-> VirtualSize : 0x0095B000 (9809920)
-> VirtualAddress : 0x001FB800 (2078720)
-> SizeOfRawData : 0x0095A400 (9806848)
-> PointerToRawData : 0x00000000 (0)
-> PointerToRelocations : 0x00000000 (0)
-> PointerToLinenumbers : 0x00000000 (0)
-> NumberOfRelocations : 0x00000040 (64)
-> NumberOfLinenumbers : 0x00004000 (16384)
-> Characteristics : 0x7461642E (1952539694)
IMAGE_SECTION_HEADER
-> Name : .data
-> PhysicalAddress : 0x0041B600 (4306432)
-> VirtualSize : 0x00B57000 (11890688)
-> VirtualAddress : 0x000C0400 (787456)
-> SizeOfRawData : 0x00B55C00 (11885568)
-> PointerToRawData : 0x00000000 (0)
-> PointerToRelocations : 0x00000000 (0)
-> PointerToLinenumbers : 0x00000000 (0)
-> NumberOfRelocations : 0x00000040 (64)
-> NumberOfLinenumbers : 0x0000C000 (49152)
-> Characteristics : 0x736C742E (1936487470)
IMAGE_SECTION_HEADER
-> Name : .tls
-> PhysicalAddress : 0x00000025 (37)
-> VirtualSize : 0x00F73000 (16199680)
-> VirtualAddress : 0x00000200 (512)
-> SizeOfRawData : 0x00C16000 (12673024)
-> PointerToRawData : 0x00000000 (0)
-> PointerToRelocations : 0x00000000 (0)
-> PointerToLinenumbers : 0x00000000 (0)
-> NumberOfRelocations : 0x00000040 (64)
-> NumberOfLinenumbers : 0x0000C000 (49152)
-> Characteristics : 0x6168732E (1634235182)
IMAGE_SECTION_HEADER
-> Name : .shared
-> PhysicalAddress : 0x00000004 (4)
-> VirtualSize : 0x00F74000 (16203776)
-> VirtualAddress : 0x00000200 (512)
-> SizeOfRawData : 0x00C16200 (12673536)
-> PointerToRawData : 0x00000000 (0)
-> PointerToRelocations : 0x00000000 (0)
-> PointerToLinenumbers : 0x00000000 (0)
-> NumberOfRelocations : 0x00000040 (64)
-> NumberOfLinenumbers : 0x0000D000 (53248)
-> Characteristics : 0x646F722E (1685025326)
IMAGE_SECTION_HEADER
-> Name : .rodata
-> PhysicalAddress : 0x00000240 (576)
-> VirtualSize : 0x00F75000 (16207872)
-> VirtualAddress : 0x00000400 (1024)
-> SizeOfRawData : 0x00C16400 (12674048)
-> PointerToRawData : 0x00000000 (0)
-> PointerToRelocations : 0x00000000 (0)
-> PointerToLinenumbers : 0x00000000 (0)
-> NumberOfRelocations : 0x00000040 (64)
-> NumberOfLinenumbers : 0x00004000 (16384)
-> Characteristics : 0x7273722E (1920168494)
IMAGE_SECTION_HEADER
-> Name : .rsrc
-> PhysicalAddress : 0x00057B64 (359268)
-> VirtualSize : 0x00F76000 (16211968)
-> VirtualAddress : 0x00057C00 (359424)
-> SizeOfRawData : 0x00C16800 (12675072)
-> PointerToRawData : 0x00000000 (0)
-> PointerToRelocations : 0x00000000 (0)
-> PointerToLinenumbers : 0x00000000 (0)
-> NumberOfRelocations : 0x00000040 (64)
-> NumberOfLinenumbers : 0x00004000 (16384)
-> Characteristics : 0x6C65722E (1818587694)
IMAGE_SECTION_HEADER
-> Name : .reloc
-> PhysicalAddress : 0x000A2018 (663576)
-> VirtualSize : 0x00FCE000 (16572416)
-> VirtualAddress : 0x000A2200 (664064)
-> SizeOfRawData : 0x00C6E400 (13034496)
-> PointerToRawData : 0x00000000 (0)
-> PointerToRelocations : 0x00000000 (0)
-> PointerToLinenumbers : 0x00000000 (0)
-> NumberOfRelocations : 0x00000040 (64)
-> NumberOfLinenumbers : 0x00004200 (16896)
-> Characteristics : 0x00000000 (0)
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using System.IO;
using System.Text;
using System.Linq;
using OpcodeBruter;
namespace x86
{
// Reads in the header information of the Portable Executable format.
// Provides information such as the date the assembly was compiled.
public class PeHeaderReader
{
private const UInt16 IMAGE_FILE_32BIT_MACHINE = 0x0100;
#region File Header Structures
public struct IMAGE_DOS_HEADER // DOS .EXE header
{
public UInt16 e_magic; // Magic number
public UInt16 e_cblp; // Bytes on last page of file
public UInt16 e_cp; // Pages in file
public UInt16 e_crlc; // Relocations
public UInt16 e_cparhdr; // Size of header in paragraphs
public UInt16 e_minalloc; // Minimum extra paragraphs needed
public UInt16 e_maxalloc; // Maximum extra paragraphs needed
public UInt16 e_ss; // Initial (relative) SS value
public UInt16 e_sp; // Initial SP value
public UInt16 e_csum; // Checksum
public UInt16 e_ip; // Initial IP value
public UInt16 e_cs; // Initial (relative) CS value
public UInt16 e_lfarlc; // File address of relocation table
public UInt16 e_ovno; // Overlay number
public UInt16 e_res_0; // Reserved words
public UInt16 e_res_1; // Reserved words
public UInt16 e_res_2; // Reserved words
public UInt16 e_res_3; // Reserved words
public UInt16 e_oemid; // OEM identifier (for e_oeminfo)
public UInt16 e_oeminfo; // OEM information; e_oemid specific
public UInt16 e_res2_0; // Reserved words
public UInt16 e_res2_1; // Reserved words
public UInt16 e_res2_2; // Reserved words
public UInt16 e_res2_3; // Reserved words
public UInt16 e_res2_4; // Reserved words
public UInt16 e_res2_5; // Reserved words
public UInt16 e_res2_6; // Reserved words
public UInt16 e_res2_7; // Reserved words
public UInt16 e_res2_8; // Reserved words
public UInt16 e_res2_9; // Reserved words
public UInt32 e_lfanew; // File address of new exe header
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct IMAGE_OPTIONAL_HEADER32
{
public IMAGE_OPTIONAL_HEADER_MAGIC Magic;
public Byte MajorLinkerVersion;
public Byte MinorLinkerVersion;
public UInt32 SizeOfCode;
public UInt32 SizeOfInitializedData;
public UInt32 SizeOfUninitializedData;
public UInt32 AddressOfEntryPoint;
public UInt32 BaseOfCode;
public UInt32 BaseOfData;
public UInt32 ImageBase;
public UInt32 SectionAlignment;
public UInt32 FileAlignment;
public UInt16 MajorOperatingSystemVersion;
public UInt16 MinorOperatingSystemVersion;
public UInt16 MajorImageVersion;
public UInt16 MinorImageVersion;
public UInt16 MajorSubsystemVersion;
public UInt16 MinorSubsystemVersion;
public UInt32 Win32VersionValue;
public UInt32 SizeOfImage;
public UInt32 SizeOfHeaders;
public UInt32 CheckSum;
public IMAGE_OPTIONAL_HEADER_SUBSYSTEM Subsystem;
public IMAGE_OPTIONAL_HEADER_DLL_CHARACTERISTICS DllCharacteristics;
public UInt32 SizeOfStackReserve;
public UInt32 SizeOfStackCommit;
public UInt32 SizeOfHeapReserve;
public UInt32 SizeOfHeapCommit;
public UInt32 LoaderFlags;
public UInt32 NumberOfRvaAndSizes;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public IMAGE_DATA_DIRECTORY[] DataDirectory;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct IMAGE_OPTIONAL_HEADER64
{
public IMAGE_OPTIONAL_HEADER_MAGIC Magic;
public Byte MajorLinkerVersion;
public Byte MinorLinkerVersion;
public UInt32 SizeOfCode;
public UInt32 SizeOfInitializedData;
public UInt32 SizeOfUninitializedData;
public UInt32 AddressOfEntryPoint;
public UInt32 BaseOfCode;
public UInt64 ImageBase;
public UInt32 SectionAlignment;
public UInt32 FileAlignment;
public UInt16 MajorOperatingSystemVersion;
public UInt16 MinorOperatingSystemVersion;
public UInt16 MajorImageVersion;
public UInt16 MinorImageVersion;
public UInt16 MajorSubsystemVersion;
public UInt16 MinorSubsystemVersion;
public UInt32 Win32VersionValue;
public UInt32 SizeOfImage;
public UInt32 SizeOfHeaders;
public UInt32 CheckSum;
public IMAGE_OPTIONAL_HEADER_SUBSYSTEM Subsystem;
public IMAGE_OPTIONAL_HEADER_DLL_CHARACTERISTICS DllCharacteristics;
public UInt64 SizeOfStackReserve;
public UInt64 SizeOfStackCommit;
public UInt64 SizeOfHeapReserve;
public UInt64 SizeOfHeapCommit;
public UInt32 LoaderFlags;
public UInt32 NumberOfRvaAndSizes;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public IMAGE_DATA_DIRECTORY[] DataDirectory;
}
public struct IMAGE_NT_HEADERS
{
public UInt32 Signature;
public IMAGE_FILE_HEADER FileHeader;
// public IMAGE_OPTIONAL_HEADER OptionalHeaders; // 32 or 64
}
public struct IMAGE_FILE_HEADER
{
public IMAGE_FILE_HEADER_MACHINE_TYPES Machine;
public UInt16 NumberOfSections;
public UInt32 TimeDateStamp;
public UInt32 PointerToSymbolTable;
public UInt32 NumberOfSymbols;
public UInt16 SizeOfOptionalHeader;
public IMAGE_FILE_HEADER_CHARACTERISTICS Characteristics;
}
public struct IMAGE_DATA_DIRECTORY
{
public UInt32 VirtualAddress;
public UInt32 Size;
}
public struct IMAGE_SECTION_HEADER
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public Byte[] Name;
public UInt32 PhysicalAddress; // Misc.
public UInt32 VirtualSize; // Misc.
public UInt32 VirtualAddress;
public UInt32 SizeOfRawData;
public UInt32 PointerToRawData;
public UInt32 PointerToRelocations;
public UInt32 PointerToLinenumbers;
public UInt16 NumberOfRelocations;
public UInt16 NumberOfLinenumbers;
public UInt32 Characteristics;
public string NameString { get { return Encoding.UTF8.GetString(Name); } }
}
#endregion File Header Structures
#region Private Fields
public IMAGE_DOS_HEADER DosHeader { get; private set; }
public IMAGE_NT_HEADERS NtHeader { get; private set; }
public IMAGE_FILE_HEADER FileHeader { get { return NtHeader.FileHeader; } }
public IMAGE_OPTIONAL_HEADER32 OptionalHeader32 { get; private set; }
public IMAGE_OPTIONAL_HEADER64 OptionalHeader64 { get; private set; }
public List<IMAGE_SECTION_HEADER> SectionHeaders { get; private set; }
private BinaryReader Reader;
private Emulator Environment;
#endregion Private Fields
#region Public fields
public IMAGE_SECTION_HEADER RDATA { get {
return SectionHeaders.First(i => i.NameString.Contains(".rdata"));
}
}
public IMAGE_SECTION_HEADER RODATA { get {
return SectionHeaders.First(i => i.NameString.Contains(".rodata"));
}
}
public IMAGE_SECTION_HEADER DATA { get {
return SectionHeaders.First(i => i.NameString.Contains(".data"));
}
}
public IMAGE_SECTION_HEADER TEXT { get {
return SectionHeaders.First(i => i.NameString.Contains(".text"));
}
}
#endregion
#region Public Methods
public PeHeaderReader(string filePath, Emulator emulator)
{
Environment = emulator;
SectionHeaders = new List<IMAGE_SECTION_HEADER>();
// Read in the DLL or EXE and get the timestamp
Reader = new BinaryReader(new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read));
DosHeader = FromBinaryReader<IMAGE_DOS_HEADER>(Reader);
// Seek to New Exe Header
Reader.BaseStream.Seek(DosHeader.e_lfanew, SeekOrigin.Begin);
NtHeader = FromBinaryReader<IMAGE_NT_HEADERS>(Reader);
if (NtHeader.Signature != 0x00004550) // PE\0\0
return;
if (NtHeader.FileHeader.SizeOfOptionalHeader != 0)
{
if (this.Is32BitHeader)
OptionalHeader32 = FromBinaryReader<IMAGE_OPTIONAL_HEADER32>(Reader);
else
OptionalHeader64 = FromBinaryReader<IMAGE_OPTIONAL_HEADER64>(Reader);
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms680313(v=vs.85).aspx
ParseFileHeader(NtHeader.FileHeader);
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms680339(v=vs.85).aspx
ParseOptionalHeader();
}
// Reads in a block from a file and converts it to the struct
// type specified by the template parameter
public static T FromBinaryReader<T>(BinaryReader reader)
{
// Read in a byte array
byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
// Pin the managed memory while, copy it out the data, then unpin it
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
handle.Free();
return theStructure;
}
#endregion Public Methods
#region Properties
// Gets if the file header is 32 bit or not
public bool Is32BitHeader
{
get
{
return (IMAGE_FILE_32BIT_MACHINE & (ushort)NtHeader.FileHeader.Characteristics) == IMAGE_FILE_32BIT_MACHINE;
}
}
// Gets the timestamp from the file header
public DateTime TimeStamp
{
get
{
// Timestamp is a date offset from 1970
DateTime returnValue = new DateTime(1970, 1, 1, 0, 0, 0);
// Add in the number of seconds since 1970/1/1
returnValue = returnValue.AddSeconds(NtHeader.FileHeader.TimeDateStamp);
// Adjust to local timezone
returnValue += TimeZone.CurrentTimeZone.GetUtcOffset(returnValue);
return returnValue;
}
}
#endregion Properties
private void ParseFileHeader(IMAGE_FILE_HEADER fileHeader)
{
LogStructure(fileHeader);
}
private void ParseOptionalHeader()
{
if (this.Is32BitHeader)
ParseOptionalHeader(OptionalHeader32);
else
ParseOptionalHeader(OptionalHeader64);
}
private void ParseOptionalHeader(IMAGE_OPTIONAL_HEADER32 optHeader)
{
LogStructure(optHeader);
for (uint i = 0; i < optHeader.NumberOfRvaAndSizes; ++i)
ParseDataDirectory(optHeader.DataDirectory[i], i);
for (uint i = 0; i < FileHeader.NumberOfSections; ++i)
ParseImageSectionHeader();
}
private void ParseOptionalHeader(IMAGE_OPTIONAL_HEADER64 optHeader)
{
LogStructure(optHeader);
for (uint i = 0; i < optHeader.NumberOfRvaAndSizes; ++i)
ParseDataDirectory(optHeader.DataDirectory[i], i);
for (uint i = 0; i < FileHeader.NumberOfSections; ++i)
ParseImageSectionHeader();
}
private void ParseDataDirectory(IMAGE_DATA_DIRECTORY directory, uint position)
{
LogStructure(directory);
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms680341(v=vs.85).aspx
private void ParseImageSectionHeader()
{
var header = FromBinaryReader<IMAGE_SECTION_HEADER>(Reader);
SectionHeaders.Add(header);
LogStructure(header);
Reader.BaseStream.Seek(-4, SeekOrigin.Current); // The fuck? Why is this needed?
}
private void LogStructure(object obj)
{
if (!Program.Debug)
return;
Console.WriteLine(obj.GetType().Name);
foreach (var field in obj.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance))
{
if (field.GetCustomAttribute(typeof(MarshalAsAttribute), false) != null)
{
if (field.FieldType.GetElementType().IsPrimitive)
Console.WriteLine("-> {0}: {1}", field.Name.PadRight(40), Encoding.UTF8.GetString((byte[])field.GetValue(obj)));
else
LogStructure(field.GetValue(obj));
}
else if (field.FieldType.IsPrimitive)
Console.WriteLine("-> {0}: 0x{1:X8} ({1})", field.Name.PadRight(40), field.GetValue(obj));
else foreach (var subField in field.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance))
Console.WriteLine("-> {0}: 0x{1:X8} ({1})", String.Format("{0}.{1}", field.Name, subField.Name).PadRight(40), subField.GetValue(field));
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment