実行可能ファイル全体を簡単に読み取ることができます。または、サイズを定義することで読み取りたいバイト数を簡単に読み取ることができますが、最初から次の「MZ」まで読み取りたい場合はどうなりますか? 2つのファイルがバインドされていて、サイズがわからないまま前半だけを取得したい場合。
mz binary stuff 1 - 私が欲しいもの mz binary stuff 2
0x77、0x90 == MZ
IMAGE_SECTION_HEADER ( pinvoke ) 構造ごとに SizeOfRawData を取得し、 IMAGE_NT_HEADERS32/64構造から SizeOfHeaders を追加する必要があります。
まず、PE/PE+ ファイルからIMAGE_DOS_HEADER構造を取得する必要があります。
その後、e_lfanew フィールドはIMAGE_NT_HEADERS32/64構造を指します。(Magic == 0x10b の場合 -> PE。Magic == 0x20b の場合 -> PE+ ファイル)
IMAGE_FILE_HEADER構造体から取得できる sectionHeadersCount の数。
UInt32 startAddress = IMAGE_DOS_HEADER.e_lfanew + 4 + Marshal.SizeOf(typeof(IMAGE_FILE_HEADER)) + [IMAGE_FILE_HEADER][6].SizeOfOptionalHeader
for(UInt32 loop = 0;loop < sectionHeadersCount;loop++)
{
IMAGE_SECTION_HEADER section = /*Map offset to IMAGE_SECTION_HEADER structure Method*/(startAddress);
startAddress += Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER));//Offset to next section
}
// Example of Mapping function:
public T PtrToStructure<T>(UInt32 offset) where T : struct
{
Byte[] bytes = this.ReadBytes(offset, (UInt32)Marshal.SizeOf(typeof(T)));
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
try
{
T result = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
return result;
} finally
{
handle.Free();
}
}