//------------------------------------------------ //--- 010 Editor v4.0.3 Binary Template // // File: EXE.bt // Authors: xSpy, Peter Kankowski, SweetScape Software // E-mail: cdutboy@gmail.com (xSpy) // Website: http://smallcode.weblogs.us (Peter Kankowski) // Version: 0.1 // Purpose: Parse Windows executable exe, dll, and sys files. // Supports 32 and 64 bit. // Category: Executable // File Mask: *.exe,*.dll,*.sys // ID Bytes: 4D 5A //MZ // History: // 0.1 2016-02-15 SweetScape Software: Merged changes from PETemplate.bt and EXETemplate2.bt // and renamed to this file. Added some coloring and rearranged // for readability. Update header for repository submission. // 0.0.0.2 2013-01-06 xSpy: Add Parse Reloc. // 0.0.0.1 2013-01-01 xSpy: Public release. // // Recommended reading: // 1. Bernd Luevelsmeyer. The PE file format // http://webster.cs.ucr.edu/Page_TechDocs/pe.txt // 2. DJ Delorie. MS DOS EXE format // http://www.delorie.com/djgpp/doc/exe/ // 3. Iczelion. PE tutorial // http://spiff.tripnet.se/~iczelion/tutorials.html //------------------------------------------------ typedef QWORD ULONGLONG; //fix ULONGLONG typedef struct { WORD MZSignature ; WORD UsedBytesInTheLastPage ; WORD FileSizeInPages ; WORD NumberOfRelocationItems ; WORD HeaderSizeInParagraphs ; WORD MinimumExtraParagraphs ; WORD MaximumExtraParagraphs ; WORD InitialRelativeSS ; WORD InitialSP ; WORD Checksum ; WORD InitialIP ; WORD InitialRelativeCS ; WORD AddressOfRelocationTable ; WORD OverlayNumber ; WORD Reserved[4] ; WORD OEMid ; WORD OEMinfo ; WORD Reserved2[10] ; LONG AddressOfNewExeHeader ; } IMAGE_DOS_HEADER; typedef enum { IMAGE_MACHINE_UNKNOWN = 0, I386 = 0x014c, R3000 = 0x0162, // MIPS little-endian, 0x160 big-endian R4000 = 0x0166, // MIPS little-endian R10000 = 0x0168, // MIPS little-endian WCEMIPSV2= 0x0169, // MIPS little-endian WCE v2 ALPHA = 0x0184, // Alpha_AXP SH3 = 0x01a2, // SH3 little-endian SH3DSP = 0x01a3, SH3E = 0x01a4, // SH3E little-endian SH4 = 0x01a6, // SH4 little-endian SH5 = 0x01a8, // SH5 ARM = 0x01c0, // ARM Little-Endian THUMB = 0x01c2, AM33 = 0x01d3, POWERPC = 0x01F0, // IBM PowerPC Little-Endian POWERPCFP= 0x01f1, IA64 = 0x0200, // Intel 64 MIPS16 = 0x0266, // MIPS ALPHA64 = 0x0284, // ALPHA64 MIPSFPU = 0x0366, // MIPS MIPSFPU16= 0x0466, // MIPS TRICORE = 0x0520, // Infineon CEF = 0x0CEF, EBC = 0x0EBC, // EFI Byte Code AMD64 = 0x8664, // AMD64 (K8) M32R = 0x9041, // M32R little-endian CEE = 0xC0EE }IMAGE_MACHINE ; //Characteristics typedef struct { WORD IMAGE_FILE_RELOCS_STRIPPED:1 ; WORD IMAGE_FILE_EXECUTABLE_IMAGE:1 ; WORD IMAGE_FILE_LINE_NUMS_STRIPPED:1 ; WORD IMAGE_FILE_LOCAL_SYMS_STRIPPED:1 ; WORD IMAGE_FILE_AGGRESIVE_WS_TRIM:1 ; WORD IMAGE_FILE_LARGE_ADDRESS_AWARE:1 2gb addresses">; WORD :1 ; WORD IMAGE_FILE_BYTES_REVERSED_LO:1 ; WORD IMAGE_FILE_32BIT_MACHINE:1 ; WORD IMAGE_FILE_DEBUG_STRIPPED:1 ; WORD IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP:1 ; WORD IMAGE_FILE_NET_RUN_FROM_SWAP:1 ; WORD IMAGE_FILE_SYSTEM:1 ; WORD IMAGE_FILE_DLL:1 ; WORD IMAGE_FILE_UP_SYSTEM_ONLY:1 ; WORD IMAGE_FILE_BYTES_REVERSED_HI:1 ; }FILE_CHARACTERISTICS ; typedef struct { IMAGE_MACHINE Machine ; WORD NumberOfSections ; time_t TimeDateStamp ; DWORD PointerToSymbolTable; DWORD NumberOfSymbols; WORD SizeOfOptionalHeader; FILE_CHARACTERISTICS Characteristics ; }IMAGE_FILE_HEADER; typedef struct { DWORD VirtualAddress ; DWORD Size; }IMAGE_DATA_DIRECTORY; typedef struct { local int len = NtHeader.OptionalHeader.NumberOfRvaAndSizes; if(len > 16) len = 16; if(len > 0) IMAGE_DATA_DIRECTORY Export ; if(len > 1) IMAGE_DATA_DIRECTORY Import ; if(len > 2) IMAGE_DATA_DIRECTORY Resource ; if(len > 3) IMAGE_DATA_DIRECTORY Exception ; if(len > 4) IMAGE_DATA_DIRECTORY Security ; if(len > 5) IMAGE_DATA_DIRECTORY BaseRelocationTable ; if(len > 6) IMAGE_DATA_DIRECTORY DebugDirectory ; if(len > 7) IMAGE_DATA_DIRECTORY CopyrightOrArchitectureSpecificData ; if(len > 8) IMAGE_DATA_DIRECTORY GlobalPtr ; if(len > 9) IMAGE_DATA_DIRECTORY TLSDirectory ; if(len > 10) IMAGE_DATA_DIRECTORY LoadConfigurationDirectory ; if(len > 11) IMAGE_DATA_DIRECTORY BoundImportDirectory ; if(len > 12) IMAGE_DATA_DIRECTORY ImportAddressTable ; if(len > 13) IMAGE_DATA_DIRECTORY DelayLoadImportDescriptors ; if(len > 14) IMAGE_DATA_DIRECTORY COMRuntimedescriptor ; if(len > 15) IMAGE_DATA_DIRECTORY Reserved ; }IMAGE_DATA_DIRECTORY_ARRAY; typedef enum { IMAGE_SUBSYSTEM_UNKNOWN =0, // Unknown subsystem. NATIVE =1, // Image doesn't require a subsystem. WINDOWS_GUI =2, // Image runs in the Windows GUI subsystem. WINDOWS_CUI =3, // Image runs in the Windows character subsystem. OS2_CUI =5, // image runs in the OS/2 character subsystem. POSIX_CUI =7, // image runs in the Posix character subsystem. NATIVE_WINDOWS =8, // image is a native Win9x driver. WINDOWS_CE_GUI =9, // Image runs in the Windows CE subsystem. EFI_APPLICATION =10, EFI_BOOT_SERVICE_DRIVER =11, EFI_RUNTIME_DRIVER =12, EFI_ROM =13, XBOX =14, WINDOWS_BOOT_APPLICATION=16 }IMAGE_SUBSYSTEM; typedef struct { WORD IMAGE_LIBRARY_PROCESS_INIT:1 ; WORD IMAGE_LIBRARY_PROCESS_TERM:1 ; WORD IMAGE_LIBRARY_THREAD_INIT:1 ; WORD IMAGE_LIBRARY_THREAD_TERM:1 ; WORD :2 ; WORD IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE:1 ; WORD IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY:1 ; WORD IMAGE_DLLCHARACTERISTICS_NX_COMPAT:1 ; WORD IMAGE_DLLCHARACTERISTICS_NO_ISOLATION:1 ; WORD IMAGE_DLLCHARACTERISTICS_NO_SEH:1 ; WORD IMAGE_DLLCHARACTERISTICS_NO_BIND:1 ; WORD :1 ; WORD IMAGE_DLLCHARACTERISTICS_WDM_DRIVER:1 ; WORD :1 ; WORD IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE:1 ; }DLL_CHARACTERISTICS ; typedef enum { PE32=0x10b, PE64=0x20b, ROM=0x107 }OPTIONAL_MAGIC ; typedef struct { OPTIONAL_MAGIC Magic ; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode ; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint ; DWORD BaseOfCode ; DWORD BaseOfData ; DWORD ImageBase ; DWORD SectionAlignment ; DWORD FileAlignment ; WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; DWORD Win32VersionValue; DWORD SizeOfImage ; DWORD SizeOfHeaders ; DWORD CheckSum ; IMAGE_SUBSYSTEM Subsystem; DLL_CHARACTERISTICS DllCharacteristics; DWORD SizeOfStackReserve ; DWORD SizeOfStackCommit ; DWORD SizeOfHeapReserve ; DWORD SizeOfHeapCommit ; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY_ARRAY DataDirArray; }IMAGE_OPTIONAL_HEADER32; typedef struct { OPTIONAL_MAGIC Magic ; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint ; DWORD BaseOfCode ; ULONGLONG ImageBase ; DWORD SectionAlignment; DWORD FileAlignment; WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; DWORD Win32VersionValue; DWORD SizeOfImage ; DWORD SizeOfHeaders; DWORD CheckSum; IMAGE_SUBSYSTEM Subsystem; DLL_CHARACTERISTICS DllCharacteristics; ULONGLONG SizeOfStackReserve ; ULONGLONG SizeOfStackCommit ; ULONGLONG SizeOfHeapReserve ; ULONGLONG SizeOfHeapCommit ; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY_ARRAY DataDirArray; }IMAGE_OPTIONAL_HEADER64; typedef struct { DWORD Signature ; IMAGE_FILE_HEADER FileHeader; local WORD OptionalHeaderMagic = ReadShort(FTell()); if (0x10b == OptionalHeaderMagic) { IMAGE_OPTIONAL_HEADER32 OptionalHeader; } else if (0x20b == OptionalHeaderMagic) { IMAGE_OPTIONAL_HEADER64 OptionalHeader; } else { Printf("not valid Optional header magic %x.\n",OptionalHeaderMagic); return 1; } }IMAGE_NT_HEADERS ; int CalcImageNtHeadersSize(IMAGE_NT_HEADERS& stNtHeader) { local WORD OptionalHeaderMagic = ReadShort(startof(stNtHeader) + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) ); if(0x10B == OptionalHeaderMagic) { Printf("PE32\n"); return 0xF8; //sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) + sizeof(IMAGE_OPTIONAL_HEADER32); } else if (0x20B == OptionalHeaderMagic) { Printf("PE64\n"); return 0x108; //sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) + sizeof(IMAGE_OPTIONAL_HEADER64); } else { return sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) + 0; // } return 0; } typedef struct { ULONG IMAGE_SCN_TYPE_DSECT:1 ; ULONG IMAGE_SCN_TYPE_NOLOAD:1 ; ULONG IMAGE_SCN_TYPE_GROUP:1 ; ULONG IMAGE_SCN_TYPE_NO_PAD:1 ; ULONG IMAGE_SCN_TYPE_COPY:1 ; ULONG IMAGE_SCN_CNT_CODE:1 ; ULONG IMAGE_SCN_CNT_INITIALIZED_DATA:1 ; ULONG IMAGE_SCN_CNT_UNINITIALIZED_DATA:1 ; ULONG IMAGE_SCN_LNK_OTHER:1 ; ULONG IMAGE_SCN_LNK_INFO:1 ; ULONG IMAGE_SCN_TYPE_OVER:1 ; ULONG IMAGE_SCN_LNK_REMOVE:1 ; ULONG IMAGE_SCN_LNK_COMDAT:1 ; ULONG :1 ; ULONG IMAGE_SCN_NO_DEFER_SPEC_EXC:1 ; ULONG IMAGE_SCN_GPREL:1 ; ULONG IMAGE_SCN_MEM_SYSHEAP:1 ; ULONG IMAGE_SCN_MEM_16BIT:1 ; ULONG IMAGE_SCN_MEM_LOCKED:1 ; ULONG IMAGE_SCN_MEM_PRELOAD:1 ; ULONG IMAGE_SCN_ALIGN_1BYTES:1 ; ULONG IMAGE_SCN_ALIGN_2BYTES:1 ; ULONG IMAGE_SCN_ALIGN_8BYTES:1 ; ULONG IMAGE_SCN_ALIGN_128BYTES:1 ; ULONG IMAGE_SCN_LNK_NRELOC_OVFL:1 ; ULONG IMAGE_SCN_MEM_DISCARDABLE:1 ; ULONG IMAGE_SCN_MEM_NOT_CACHED:1 ; ULONG IMAGE_SCN_MEM_NOT_PAGED:1 ; ULONG IMAGE_SCN_MEM_SHARED:1 ; ULONG IMAGE_SCN_MEM_EXECUTE:1 ; ULONG IMAGE_SCN_MEM_READ:1 ; ULONG IMAGE_SCN_MEM_WRITE:1 ; }SECTION_CHARACTERISTICS; typedef struct { BYTE Name[8] ; union { DWORD PhysicalAddress; DWORD VirtualSize; } Misc; DWORD VirtualAddress ; DWORD SizeOfRawData ; DWORD PointerToRawData ; DWORD PointerToRelocations; DWORD PointerToLinenumbers; WORD NumberOfRelocations; WORD NumberOfLinenumbers; SECTION_CHARACTERISTICS Characteristics ; }IMAGE_SECTION_HEADER ; string ReadImageSectionHeader( IMAGE_SECTION_HEADER &h ) { return h.Name; } typedef struct (IMAGE_SECTION_HEADER& SecHeader) { local string sSecName=SecHeader.Name; UCHAR Data[SecHeader.SizeOfRawData]; }IMAGE_SECTION_DATA ; string ReadSectionData(IMAGE_SECTION_DATA& SecData) { return SecData.sSecName; } typedef struct (int nNameLen) { WORD Hint; BYTE Name[nNameLen]; } IMAGE_IMPORT_BY_NAME ; string commentImageImportByName(IMAGE_IMPORT_BY_NAME& ImportByName) { return ImportByName.Name; } typedef struct { local int nNameIndex=0; local ULONG ulThrunk=0; local int nNameLen=0; local string sDllName=""; local ULONG ulOriginalFirstThunkFOA=0; union { ULONG Characteristics; ULONG OriginalFirstThunk ; }DUMMYUNIONNAME; ULONG TimeDateStamp ; ULONG ForwarderChain ; ULONG Name ; ULONG FirstThunk ; ulOriginalFirstThunkFOA = RVA2FOA(DUMMYUNIONNAME.OriginalFirstThunk); if ((0x20b == NtHeader.OptionalHeader.Magic)) { } else { nNameIndex =0; while(1) { ulThrunk = ReadUInt(ulOriginalFirstThunkFOA + 4 * nNameIndex); if (0 == ulThrunk) { break; } if (ulThrunk & 0x80000000) { Printf("mport by order \n"); } else { nNameLen = Strlen(ReadString(RVA2FOA(ulThrunk) + sizeof(WORD))); if(0 != nNameLen) { FSeek(RVA2FOA(ulThrunk)); IMAGE_IMPORT_BY_NAME ImportByName(nNameLen +1); } } nNameIndex++; } } }IMAGE_IMPORT_DESCRIPTOR ; string ReadImageImportDescriptor(IMAGE_IMPORT_DESCRIPTOR& ImportDescriptor) { return ReadString( RVA2FOA(ImportDescriptor.Name)); } typedef struct (string& sExportFuncName,ULONG ulDestRVA,string& sJmpName) { local ULONG ulLocalDestRVA=ulDestRVA; local string sLocalJmpName=sJmpName; char Function[Strlen(sExportFuncName)]; }IMAGE_EXPORT_BY_NAME ; string ReadExportByName(IMAGE_EXPORT_BY_NAME& ExportByName) { return ExportByName.Function; } string commentExportByName(IMAGE_EXPORT_BY_NAME& ExportByName) { local string sComment=""; if (0 == Strlen(ExportByName.sLocalJmpName) ) { SPrintf(sComment,"0x%X",ExportByName.ulLocalDestRVA); } else { SPrintf(sComment,"%s",ExportByName.sLocalJmpName); } return sComment; } typedef struct { DWORD Characteristics; time_t TimeDateStamp; WORD MajorVersion; WORD MinorVersion; DWORD Name ; DWORD Base; DWORD NumberOfFunctions; DWORD NumberOfNames; DWORD AddressOfFunctions ; // RVA from base of image DWORD AddressOfNames ; // RVA from base of image DWORD AddressOfNameOrdinals ; // RVA from base of image local int nIndex=0; local ULONG NameArrayFOA=0; local ULONG OrdinalArrayFOA=0; local ULONG FuncArrayFOA=0; local ULONG ulNameRVA=0; local ULONG ulNameFOA=0; local ULONG ulFuncRVA=0; local WORD wOrdinal=0; local string sExportName=""; local string sJmpName=""; //List Export names. NameArrayFOA = RVA2FOA(ExportDir.AddressOfNames); OrdinalArrayFOA = RVA2FOA(ExportDir.AddressOfNameOrdinals); FuncArrayFOA = RVA2FOA(ExportDir.AddressOfFunctions); for(nIndex=0; nIndex < ExportDir.NumberOfNames; nIndex++) { ulNameRVA = ReadUInt(NameArrayFOA + nIndex*sizeof(ULONG) ); ulNameFOA = RVA2FOA(ulNameRVA); sExportName = ReadString(ulNameFOA); if (0 != Strlen(sExportName)) { wOrdinal = ReadUShort(OrdinalArrayFOA + nIndex*sizeof(USHORT)); ulFuncRVA = ReadUInt(FuncArrayFOA + wOrdinal* sizeof(ULONG) ); //GetRVA if ( (ulFuncRVA >NtHeader.OptionalHeader.DataDirArray.Export.VirtualAddress ) && \ (ulFuncRVA < NtHeader.OptionalHeader.DataDirArray.Export.VirtualAddress + NtHeader.OptionalHeader.DataDirArray.Export.Size ) ) { //is a jmp sJmpName = ReadString( RVA2FOA(ulFuncRVA) ); FSeek(ulNameFOA); IMAGE_EXPORT_BY_NAME ExportByName(sExportName,ulFuncRVA,sJmpName); } else { //normal sJmpName =""; FSeek(ulNameFOA); IMAGE_EXPORT_BY_NAME ExportByName(sExportName,ulFuncRVA,sJmpName); } } } }IMAGE_EXPORT_DIRECTORY ; string commentExportDirectory(IMAGE_EXPORT_DIRECTORY& ExportDir) { return ReadString(RVA2FOA(ExportDir.Name)); } ULONG RVA2FOA(ULONG ulRVA) { local int i=0; for(i=0; i < NtHeader.FileHeader.NumberOfSections; i++) { if ( (ulRVA >= SectionHeaders[i].VirtualAddress) && (ulRVA <= SectionHeaders[i].VirtualAddress + SectionHeaders[i].SizeOfRawData) ) { return SectionHeaders[i].PointerToRawData + (ulRVA - SectionHeaders[i].VirtualAddress); } } return 0; } string LocationRVA(ULONG ulRVA) { local int i=0; for(i=0; i < NtHeader.FileHeader.NumberOfSections; i++) { if ( (ulRVA >= SectionHeaders[i].VirtualAddress) && (ulRVA <= SectionHeaders[i].VirtualAddress + SectionHeaders[i].SizeOfRawData) ) { return SectionHeaders[i].Name; } } return ""; } string CommentRVA2FOA(DWORD dwRVA) { local string sComment=""; if (0 != dwRVA) { SPrintf(sComment,"%s FOA = 0x%X \n",LocationRVA(dwRVA),RVA2FOA(dwRVA)); } return sComment; } string CommentRVAString(DWORD dwRVA) { local string sComment=""; if (0 != dwRVA) { SPrintf(sComment,"%s FOA = 0x%X -> %s",LocationRVA(dwRVA),RVA2FOA(dwRVA),ReadString(RVA2FOA(dwRVA)) ); } return sComment; } typedef struct { DWORD VirtualAddress ; DWORD SizeOfBlock; // WORD TypeOffset[1]; local ULONG ulBlockNum=0; ulBlockNum = (SizeOfBlock - 8)/2; WORD Block[ulBlockNum] ; } IMAGE_BASE_RELOCATION ; string CommentBaseRelocBlock(WORD Block) { if(0x3000 == (Block & 0xF000) ) { return "HIGHLOW"; } else { return "ABSOLUTE"; } return ""; } string commentImageBaseRelocation(IMAGE_BASE_RELOCATION& BaseReloc) { local string sComment=""; SPrintf(sComment,"%d",BaseReloc.ulBlockNum); return sComment; } typedef struct { local ULONG ulRelocNum=0; while(1) { if(0 == ReadUInt(FTell()) ) { break; } IMAGE_BASE_RELOCATION BaseReloc; ulRelocNum++; } }BASE_RELOCATION_TABLE ; string commentBaseRelocationTable(BASE_RELOCATION_TABLE& RelocTable) { local string sComment=""; SPrintf(sComment,"%d",RelocTable.ulRelocNum); return sComment; } //Parse Export Directory void ParseEAT(void) { if( (NtHeader.OptionalHeader.DataDirArray.Export.VirtualAddress != 0) && (NtHeader.OptionalHeader.DataDirArray.Export.Size != 0) ) { local ULONG ulExportFOA= RVA2FOA(NtHeader.OptionalHeader.DataDirArray.Export.VirtualAddress); FSeek(ulExportFOA); IMAGE_EXPORT_DIRECTORY ExportDir; } } //Import Directory void ParseIAT() { if( (NtHeader.OptionalHeader.DataDirArray.Import.VirtualAddress != 0) && (NtHeader.OptionalHeader.DataDirArray.Import.Size != 0) ) { local ULONG ulImportFOA = RVA2FOA(NtHeader.OptionalHeader.DataDirArray.Import.VirtualAddress); //Import local ULONG ulOriginalFirstThunk=0; local ULONG ulOriginalFirstThunkFOA=0; local int nImportIndex=0; FSeek(ulImportFOA); while(1) { ulOriginalFirstThunk = ReadUInt(ulImportFOA + 0x14*nImportIndex ); if (0 == ulOriginalFirstThunk) { break; } FSeek(ulImportFOA + 0x14*nImportIndex); IMAGE_IMPORT_DESCRIPTOR ImportDescriptor; nImportIndex++; } } } //Resource Directory 2 void ParseResource() { if( (NtHeader.OptionalHeader.DataDirArray.Resource.VirtualAddress == 0) || (NtHeader.OptionalHeader.DataDirArray.Resource.Size == 0) ) { return; } //FixMe } //Exception Directory 3 void ParseException() { if( (NtHeader.OptionalHeader.DataDirArray.Exception.VirtualAddress == 0) || (NtHeader.OptionalHeader.DataDirArray.Exception.Size == 0) ) { return; } //FixMe } //Security Directory 4 void ParseSecurity() { if( (NtHeader.OptionalHeader.DataDirArray.Security.VirtualAddress == 0) || (NtHeader.OptionalHeader.DataDirArray.Security.Size == 0) ) { return; } //FixMe } //Relocation Directory 5 void ParseBaseReloc() { if( (NtHeader.OptionalHeader.DataDirArray.BaseRelocationTable.VirtualAddress == 0) || (NtHeader.OptionalHeader.DataDirArray.BaseRelocationTable.Size == 0) ) { return; } FSeek( RVA2FOA(NtHeader.OptionalHeader.DataDirArray.BaseRelocationTable.VirtualAddress) ); BASE_RELOCATION_TABLE RelocTable; } //Debug Directory 6 void ParseDebug() { if( (NtHeader.OptionalHeader.DataDirArray.DebugDirectory.VirtualAddress == 0) || (NtHeader.OptionalHeader.DataDirArray.DebugDirectory.Size == 0) ) { return; } //FixMe } //TLS 9 void ParseTLS() { if( (NtHeader.OptionalHeader.DataDirArray.TLSDirectory.VirtualAddress == 0) || (NtHeader.OptionalHeader.DataDirArray.TLSDirectory.Size == 0) ) { return; } //FixMe } //Bound Import 11 void ParseBoundImport() { if( (NtHeader.OptionalHeader.DataDirArray.BoundImportDirectory.VirtualAddress == 0) || (NtHeader.OptionalHeader.DataDirArray.BoundImportDirectory.Size == 0) ) { return; } //FixMe } //Delay Import 13 void ParseDelayImport() { if( (NtHeader.OptionalHeader.DataDirArray.DelayLoadImportDescriptors.VirtualAddress == 0) || (NtHeader.OptionalHeader.DataDirArray.DelayLoadImportDescriptors.Size == 0) ) { return; } //FixMe } //-------------------------------------------------------------------------------------------------------- //Code Printf("Parse PE Begin.\n"); IMAGE_DOS_HEADER DosHeader ; if (DosHeader.MZSignature != 0x5A4D) { Printf("invalid dos magic.\n"); return 1; } if (0 == DosHeader.AddressOfNewExeHeader ) { Warning("not invalid AddressOfNewExeHeader = 0x%X",DosHeader.AddressOfNewExeHeader); return 2; } struct IMAGE_DOS_STUB { UCHAR Data[DosHeader.AddressOfNewExeHeader - sizeof(IMAGE_DOS_HEADER)] ; Printf("Space between dos header and nt header is %d bytes \n",DosHeader.AddressOfNewExeHeader - sizeof(IMAGE_DOS_HEADER)); } DosStub; FSeek(DosHeader.AddressOfNewExeHeader); IMAGE_NT_HEADERS NtHeader ; if (0x00004550 != NtHeader.Signature) { Printf("invalid nt Signature 0x%x \n",NtHeader.Signature); return 3; } IMAGE_SECTION_HEADER SectionHeaders[NtHeader.FileHeader.NumberOfSections] ; //no align header size local ULONG ulRawHeaderSize = DosHeader.AddressOfNewExeHeader + sizeof(NtHeader) + NtHeader.FileHeader.NumberOfSections*sizeof(IMAGE_SECTION_HEADER); if (NtHeader.OptionalHeader.SizeOfHeaders - ulRawHeaderSize >0) { UCHAR Space2[NtHeader.OptionalHeader.SizeOfHeaders - ulRawHeaderSize ] ; } Printf("Space between headers and first sections is %d bytes\n",NtHeader.OptionalHeader.SizeOfHeaders - ulRawHeaderSize); FSeek(NtHeader.OptionalHeader.SizeOfHeaders); local ULONG ulIndex=0; for (ulIndex=0; ulIndex < NtHeader.FileHeader.NumberOfSections; ulIndex++) { if ( 0 == SectionHeaders[ulIndex].PointerToRawData ) { continue; } if ( 0 == SectionHeaders[ulIndex].SizeOfRawData ) { continue; } IMAGE_SECTION_DATA Section(SectionHeaders[ulIndex]); } FSeek(NtHeader.OptionalHeader.SizeOfHeaders); //Parse Directory ParseEAT(); ParseIAT(); ParseResource(); ParseException(); ParseSecurity(); ParseBaseReloc(); ParseDebug(); ParseTLS(); ParseBoundImport(); ParseDelayImport(); Printf("Parse PE finish.\n");