Our first struct will be:
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi, Pack = 1)] public struct MSDOS20Section { [FieldOffset(0x0)] [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x4)] public string Signature; [FieldOffset(0x4)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x37)] byte[] MSDOSEXEHeader; [FieldOffset(0x3C)] [MarshalAs(UnmanagedType.I4)] public Int32 OffsetToPEHeader; [FieldOffset(0x40)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x40)] byte[] MSDOSStub; }
Notice the attributes on the struct and fields? The attribute on the struct sets the type of layout which will be used when marshaling, character set, and the pack size. Because we have set the LayoutKind to be Explicit, we
Speaking of clean, we should override ToString on each of our structs to make dumping them to the console window as we build them out. Eventually we will want a better/sexy output that included colors and such, but for now we just need the information out to match the dissection results. Our initial output is an underwhelming:
Signature: MZ? OffsetToPEHeader: 80 Press return to exit
That is good for now, we will conquer the COFF header next.