for (int i = 0; i < coffHeader.Value.NumberOfSections; i++) { SectionTable? sectionTable = inputFile. ReadStructure<SectionTable>(); Console.WriteLine( sectionTable.ToString()); sectionTables.Add(sectionTable.Value.Name, sectionTable); }
Here is the struct:
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi, Pack = 1)] public struct SectionTable { [FieldOffset(0x0)] [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x8)] public string Name; [FieldOffset(0x8)] [MarshalAs(UnmanagedType.U4)] UInt32 VirtualSize; [FieldOffset(0xC)] [MarshalAs(UnmanagedType.U4)] UInt32 VirtualAddress; [FieldOffset(0x10)] [MarshalAs(UnmanagedType.U4)] UInt32 SizeOfRawData; [FieldOffset(0x14)] [MarshalAs(UnmanagedType.U4)] UInt32 PointerToRawData; [FieldOffset(0x18)] [MarshalAs(UnmanagedType.U4)] UInt32 PointerToRelocations; [FieldOffset(0x1C)] [MarshalAs(UnmanagedType.U4)] UInt32 PointerToLinenumbers; [FieldOffset(0x20)] [MarshalAs(UnmanagedType.U2)] UInt16 NumberOfRelocations; [FieldOffset(0x22)] [MarshalAs(UnmanagedType.U2)] UInt16 NumberOfLinenumbers; [FieldOffset(0x24)] [MarshalAs(UnmanagedType.U4)] UInt32 Characteristics; public override string ToString() { StringBuilder returnValue = new StringBuilder(); returnValue.AppendFormat("Name: {0}", Name); returnValue.AppendLine(); returnValue.AppendFormat("VirtualSize: {0}", VirtualSize); returnValue.AppendLine(); returnValue.AppendFormat("VirtualAddress: 0x{0:X}", VirtualAddress); returnValue.AppendLine(); returnValue.AppendFormat("SizeOfRawData: {0}", SizeOfRawData); returnValue.AppendLine(); returnValue.AppendFormat("PointerToRawData: 0x{0:X}", PointerToRawData); returnValue.AppendLine(); returnValue.AppendFormat("PointerToRelocations: 0x{0:X}", PointerToRelocations); returnValue.AppendLine(); returnValue.AppendFormat("PointerToLinenumbers: 0x{0:X}", PointerToLinenumbers); returnValue.AppendLine(); returnValue.AppendFormat("NumberOfRelocations: {0}", NumberOfRelocations); returnValue.AppendLine(); returnValue.AppendFormat("NumberOfLinenumbers: {0}", NumberOfLinenumbers); returnValue.AppendLine(); returnValue.AppendFormat("Characteristics: 0x{0:X}", Characteristics); returnValue.AppendLine(); returnValue.AppendFormat("Characteristics (decoded): {0}", DecodeCharacteristics(Characteristics)); returnValue.AppendLine(); return returnValue.ToString(); } private string DecodeCharacteristics(uint characteristics) { List<string> setCharacteristics = new List<string>(); if ((characteristics == 0x00000000)) { // 0x00000000 Reserved for future use. setCharacteristics.Add("Reserved flag set"); } if ((characteristics & 0x00000001) != 0) { // 0x00000001 Reserved for future use. setCharacteristics.Add("Reserved flag set"); } if ((characteristics & 0x00000002) != 0) { // 0x00000002 Reserved for future use. setCharacteristics.Add("Reserved flag set"); } if ((characteristics & 0x00000004) != 0) { // 0x00000004 Reserved for future use. setCharacteristics.Add("Reserved flag set"); } if ((characteristics & 0x00000008) != 0) { //IMAGE_SCN_TYPE_NO_PAD 0x00000008 The section should not // be padded to the next boundary.This flag is // obsolete and is replaced by // IMAGE_SCN_ALIGN_1BYTES.This is valid only for // object files. setCharacteristics.Add("IMAGE_SCN_TYPE_NO_PAD"); } if ((characteristics & 0x00000010) != 0) { // 0x00000010 Reserved for future use. setCharacteristics.Add("Reserved flag set"); } if ((characteristics & 0x00000020) != 0) { //IMAGE_SCN_CNT_CODE 0x00000020 The section contains // executable code. setCharacteristics.Add("IMAGE_SCN_CNT_CODE"); } if ((characteristics & 0x00000040) != 0) { //IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 The section // contains initialized data. setCharacteristics.Add("IMAGE_SCN_CNT_INITIALIZED_DATA"); } if ((characteristics & 0x00000080) != 0) { //IMAGE_SCN_CNT_UNINITIALIZED_ DATA 0x00000080 The section // contains uninitialized data. setCharacteristics.Add("IMAGE_SCN_CNT_UNINITIALIZED_DATA"); } if ((characteristics & 0x00000100) != 0) { //IMAGE_SCN_LNK_OTHER 0x00000100 Reserved for future use. setCharacteristics.Add("IMAGE_SCN_LNK_OTHER"); } if ((characteristics & 0x00000200) != 0) { //IMAGE_SCN_LNK_INFO 0x00000200 The section contains // comments or other information.The.drectve // section has this type.This is valid for object // files only. setCharacteristics.Add("IMAGE_SCN_LNK_INFO"); } if ((characteristics & 0x00000400) != 0) { // 0x00000400 Reserved for future use. setCharacteristics.Add("Reserved flag set"); } if ((characteristics & 0x00000800) != 0) { //IMAGE_SCN_LNK_REMOVE 0x00000800 The section will not // become part of the image.This is valid only // for object files. setCharacteristics.Add("IMAGE_SCN_LNK_REMOVE"); } if ((characteristics & 0x00001000) != 0) { //IMAGE_SCN_LNK_COMDAT 0x00001000 The section contains // COMDAT data.For more information, see section // 5.5.6, “COMDAT Sections(Object Only).” This is // valid only for object files. setCharacteristics.Add("IMAGE_SCN_LNK_COMDAT"); } if ((characteristics & 0x00008000) != 0) { //IMAGE_SCN_GPREL 0x00008000 The section contains data // referenced through the global pointer(GP). setCharacteristics.Add("IMAGE_SCN_GPREL"); } if ((characteristics & 0x00020000) != 0) { //IMAGE_SCN_MEM_PURGEABLE 0x00020000 Reserved for future use. setCharacteristics.Add("IMAGE_SCN_MEM_PURGEABLE"); } if ((characteristics & 0x00020000) != 0) { //IMAGE_SCN_MEM_16BIT 0x00020000 Reserved for future use. setCharacteristics.Add("IMAGE_SCN_MEM_16BIT"); } if ((characteristics & 0x00040000) != 0) { //IMAGE_SCN_MEM_LOCKED 0x00040000 Reserved for future use. setCharacteristics.Add("IMAGE_SCN_MEM_LOCKED"); } if ((characteristics & 0x00080000) != 0) { //IMAGE_SCN_MEM_PRELOAD 0x00080000 Reserved for future // use. setCharacteristics.Add("IMAGE_SCN_MEM_PRELOAD"); } if ((characteristics & 0x00100000) != 0) { //IMAGE_SCN_ALIGN_1BYTES 0x00100000 Align data on a 1 - // byte boundary.Valid only for object files. setCharacteristics.Add("IMAGE_SCN_ALIGN_1BYTES"); } if ((characteristics & 0x00200000) != 0) { //IMAGE_SCN_ALIGN_2BYTES 0x00200000 Align data on a 2 - // byte boundary.Valid only for object files. setCharacteristics.Add("IMAGE_SCN_ALIGN_2BYTES"); } if ((characteristics & 0x00300000) != 0) { //IMAGE_SCN_ALIGN_4BYTES 0x00300000 Align data on a 4 - // byte boundary.Valid only for object files. setCharacteristics.Add("IMAGE_SCN_ALIGN_4BYTES"); } if ((characteristics & 0x00400000) != 0) { //IMAGE_SCN_ALIGN_8BYTES 0x00400000 Align data on an 8 - // byte boundary.Valid only for object files. setCharacteristics.Add("IMAGE_SCN_ALIGN_8BYTES"); } if ((characteristics & 0x00500000) != 0) { //IMAGE_SCN_ALIGN_16BYTES 0x00500000 Align data on a 16 - // byte boundary.Valid only for object files. setCharacteristics.Add("IMAGE_SCN_ALIGN_16BYTES"); } if ((characteristics & 0x00600000) != 0) { //IMAGE_SCN_ALIGN_32BYTES 0x00600000 Align data on a 32 - // byte boundary.Valid only for object files. setCharacteristics.Add("IMAGE_SCN_ALIGN_32BYTES"); } if ((characteristics & 0x00700000) != 0) { //IMAGE_SCN_ALIGN_64BYTES 0x00700000 Align data on a 64 - // byte boundary.Valid only for object files. setCharacteristics.Add("IMAGE_SCN_ALIGN_64BYTES"); } if ((characteristics & 0x00800000) != 0) { //IMAGE_SCN_ALIGN_128BYTES 0x00800000 Align data on a // 128 - byte boundary.Valid only for object // files. setCharacteristics.Add("IMAGE_SCN_ALIGN_128BYTES"); } if ((characteristics & 0x00900000) != 0) { //IMAGE_SCN_ALIGN_256BYTES 0x00900000 Align data on a // 256 - byte boundary.Valid only for object // files. setCharacteristics.Add("IMAGE_SCN_ALIGN_256BYTES"); } if ((characteristics & 0x00A00000) != 0) { //IMAGE_SCN_ALIGN_512BYTES 0x00A00000 Align data on a // 512 - byte boundary.Valid only for object // files. setCharacteristics.Add("IMAGE_SCN_ALIGN_512BYTES"); } if ((characteristics & 0x00B00000) != 0) { //IMAGE_SCN_ALIGN_1024BYTES 0x00B00000 Align data on a // 1024 - byte boundary.Valid only for object // files. setCharacteristics.Add("IMAGE_SCN_ALIGN_1024BYTES"); } if ((characteristics & 0x00C00000) != 0) { //IMAGE_SCN_ALIGN_2048BYTES 0x00C00000 Align data on a // 2048 - byte boundary.Valid only for object // files. setCharacteristics.Add("IMAGE_SCN_ALIGN_2048BYTES"); } if ((characteristics & 0x00D00000) != 0) { //IMAGE_SCN_ALIGN_4096BYTES 0x00D00000 Align data on a // 4096 - byte boundary.Valid only for object // files. setCharacteristics.Add("IMAGE_SCN_ALIGN_4096BYTES"); } if ((characteristics & 0x00E00000) != 0) { //IMAGE_SCN_ALIGN_8192BYTES 0x00E00000 Align data on an // 8192 - byte boundary.Valid only for object // files. setCharacteristics.Add("IMAGE_SCN_ALIGN_8192BYTES"); } if ((characteristics & 0x01000000) != 0) { //IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 The section // contains extended relocations. setCharacteristics.Add("IMAGE_SCN_LNK_NRELOC_OVFL"); } if ((characteristics & 0x02000000) != 0) { // IMAGE_SCN_MEM_DISCARDABLE 0x02000000 The section can // be discarded as needed. setCharacteristics.Add("IMAGE_SCN_MEM_DISCARDABLE"); } if ((characteristics & 0x04000000) != 0) { // IMAGE_SCN_MEM_NOT_CACHED 0x04000000 The section // cannot be cached. setCharacteristics.Add("IMAGE_SCN_MEM_NOT_CACHED"); } if ((characteristics & 0x08000000) != 0) { // IMAGE_SCN_MEM_NOT_PAGED 0x08000000 The section is not // pageable. setCharacteristics.Add("IMAGE_SCN_MEM_NOT_PAGED"); } if ((characteristics & 0x10000000) != 0) { // IMAGE_SCN_MEM_SHARED 0x10000000 The section can be // shared in memory. setCharacteristics.Add("IMAGE_SCN_MEM_SHARED"); } if ((characteristics & 0x20000000) != 0) { // IMAGE_SCN_MEM_EXECUTE 0x20000000 The section can be // executed as code. setCharacteristics.Add("IMAGE_SCN_MEM_EXECUTE"); } if ((characteristics & 0x40000000) != 0) { // IMAGE_SCN_MEM_READ 0x40000000 The section can be read. setCharacteristics.Add("IMAGE_SCN_MEM_READ"); } if ((characteristics & 0x80000000) != 0) { // IMAGE_SCN_MEM_WRITE 0x80000000 The section can be // written to. setCharacteristics.Add("IMAGE_SCN_MEM_WRITE"); } return string.Join(",", setCharacteristics); } }
And here is the output of the new portion of the code:
Name: .text VirtualSize: 948 VirtualAddress: 0x2000 SizeOfRawData: 1024 PointerToRawData: 0x200 PointerToRelocations: 0x0 PointerToLinenumbers: 0x0 NumberOfRelocations: 0 NumberOfLinenumbers: 0 Characteristics: 0x60000020 Characteristics (decoded): IMAGE_SCN_CNT_CODE,IMAGE_SCN_MEM_EXECUTE,IMAGE_SCN_ME M_READ Name: .rsrc VirtualSize: 720 VirtualAddress: 0x4000 SizeOfRawData: 1024 PointerToRawData: 0x600 PointerToRelocations: 0x0 PointerToLinenumbers: 0x0 NumberOfRelocations: 0 NumberOfLinenumbers: 0 Characteristics: 0x40000040 Characteristics (decoded): IMAGE_SCN_CNT_INITIALIZED_DATA,IMAGE_SCN_MEM_READ Name: .reloc VirtualSize: 12 VirtualAddress: 0x6000 SizeOfRawData: 512 PointerToRawData: 0xA00 PointerToRelocations: 0x0 PointerToLinenumbers: 0x0 NumberOfRelocations: 0 NumberOfLinenumbers: 0 Characteristics: 0x42000040 Characteristics (decoded): IMAGE_SCN_CNT_INITIALIZED_DATA,IMAGE_SCN_MEM_DISCARDA BLE,IMAGE_SCN_MEM_READ Press return to exit
The code is getting longer, so the next post will be about creating an open source project on GitHub. I am going to release it under the MIT license. That way you can try it out yourself, and perhaps help me build something interesting.
Keep coding!