//-------------------------------------- //--- 010 Editor v4.0.3 Binary Template // // File: https://ntreserved.googlecode.com/svn/trunk/Wiki/PE.bt // Author: xSpy [cdutboy@gmail.com] // Revision: 0.0.0.2 // Purpose: Parse x86/x64 exe,dll,sys // Build: 2013.01.01 // Update: 2013.01.06 /* 0.0.0.2 Add Parse Reloc 0.0.0.1 Basic */ //-------------------------------------- typedef QWORD ULONGLONG; //fix ULONGLONG typedef struct _IMAGE_DOS_HEADER { WORD e_magic ; WORD e_cblp ; WORD e_cp ; WORD e_crlc ; WORD e_cparhdr ; WORD e_minalloc ; WORD e_maxalloc ; WORD e_ss ; WORD e_sp ; WORD e_csum ; WORD e_ip ; WORD e_cs ; WORD e_lfarlc ; WORD e_ovno ; WORD e_res[4] ; WORD e_oemid ; WORD e_oeminfo ; WORD e_res2[10] ; LONG e_lfanew ; } IMAGE_DOS_HEADER; typedef enum _IMAGE_MACHINE { 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 _FILE_CHARACTERISTICS { 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_FILE_HEADER { IMAGE_MACHINE Machine ; WORD NumberOfSections ; time_t TimeDateStamp ; DWORD PointerToSymbolTable; DWORD NumberOfSymbols; WORD SizeOfOptionalHeader; FILE_CHARACTERISTICS Characteristics ; }IMAGE_FILE_HEADER; typedef struct _IMAGE_DATA_DIRECTORY { DWORD VirtualAddress ; DWORD Size; }IMAGE_DATA_DIRECTORY; typedef struct _IMAGE_DATA_DIRECTORY_ARRAY { IMAGE_DATA_DIRECTORY DataDir0 ; IMAGE_DATA_DIRECTORY DataDir1 ; IMAGE_DATA_DIRECTORY DataDir2 ; IMAGE_DATA_DIRECTORY DataDir3 ; IMAGE_DATA_DIRECTORY DataDir4 ; IMAGE_DATA_DIRECTORY DataDir5 ; IMAGE_DATA_DIRECTORY DataDir6 ; IMAGE_DATA_DIRECTORY DataDir7 ; IMAGE_DATA_DIRECTORY DataDir8 ; IMAGE_DATA_DIRECTORY DataDir9 ; IMAGE_DATA_DIRECTORY DataDir10 ; IMAGE_DATA_DIRECTORY DataDir11 ; IMAGE_DATA_DIRECTORY DataDir12 ; IMAGE_DATA_DIRECTORY DataDir13 ; IMAGE_DATA_DIRECTORY DataDir14 ; IMAGE_DATA_DIRECTORY DataDir15 ; }IMAGE_DATA_DIRECTORY_ARRAY; typedef enum _IMAGE_SUBSYSTEM { 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 _DLL_CHARACTERISTICS { 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 _OPTIONAL_MAGIC { PE32=0x10b, PE64=0x20b, ROM=0x107 }OPTIONAL_MAGIC ; typedef struct _IMAGE_OPTIONAL_HEADER32 { 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 _IMAGE_OPTIONAL_HEADER64 { 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 _IMAGE_NT_HEADERS { 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 _SECTION_CHARACTERISTICS { 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 _IMAGE_SECTION_HEADER { 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; typedef struct _IMAGE_SECTION_DATA(IMAGE_SECTION_HEADER& SecHeader) { local string sSecName=SecHeader.Name; UCHAR Data[SecHeader.SizeOfRawData]; }IMAGE_SECTION_DATA ; string commentSectionData(IMAGE_SECTION_DATA& SecData) { return SecData.sSecName; } typedef struct _IMAGE_IMPORT_BY_NAME(int nNameLen) { WORD Hint; BYTE Name[nNameLen]; } IMAGE_IMPORT_BY_NAME ; string commentImageImportByName(IMAGE_IMPORT_BY_NAME& ImportByName) { return ImportByName.Name; } typedef struct _IMAGE_IMPORT_DESCRIPTOR { 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 commentImageImportDescriptor(IMAGE_IMPORT_DESCRIPTOR& ImportDescriptor) { return ReadString( RVA2FOA(ImportDescriptor.Name)); } typedef struct _IMAGE_EXPORT_BY_NAME(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 _IMAGE_EXPORT_DIRECTORY { 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.DataDir0.VirtualAddress ) && \ (ulFuncRVA < NtHeader.OptionalHeader.DataDirArray.DataDir0.VirtualAddress + NtHeader.OptionalHeader.DataDirArray.DataDir0.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 _IMAGE_BASE_RELOCATION { DWORD VirtualAddress ; DWORD SizeOfBlock; // WORD TypeOffset[1]; local ULONG ulBlockNum=0; local ULONG ulIndex=0; ulBlockNum = (SizeOfBlock - 8)/2; for(ulIndex=0; ulIndex< ulBlockNum ;ulIndex++) { WORD Block; } } IMAGE_BASE_RELOCATION ; string CommentBaseRelocBlock(WORD Block) { if(0x3000 == (Block & 0xF000) ) { return "HIGHLOW"; } else { return "ABSULUTE"; } return ""; } string commentImageBaseRelocation(IMAGE_BASE_RELOCATION& BaseReloc) { local string sComment=""; SPrintf(sComment,"%d",BaseReloc.ulBlockNum); return sComment; } typedef struct _BASE_RELOCATION_TABLE { 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.DataDir0.VirtualAddress != 0) && (NtHeader.OptionalHeader.DataDirArray.DataDir0.Size != 0) ) { local ULONG ulExportFOA= RVA2FOA(NtHeader.OptionalHeader.DataDirArray.DataDir0.VirtualAddress); FSeek(ulExportFOA); IMAGE_EXPORT_DIRECTORY ExportDir; } } //Import Directory void ParseIAT() { if( (NtHeader.OptionalHeader.DataDirArray.DataDir1.VirtualAddress != 0) && (NtHeader.OptionalHeader.DataDirArray.DataDir1.Size != 0) ) { local ULONG ulImportFOA = RVA2FOA(NtHeader.OptionalHeader.DataDirArray.DataDir1.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.DataDir2.VirtualAddress == 0) || (NtHeader.OptionalHeader.DataDirArray.DataDir2.Size == 0) ) { return; } //FixMe } //Exception Directory 3 void ParseException() { if( (NtHeader.OptionalHeader.DataDirArray.DataDir3.VirtualAddress == 0) || (NtHeader.OptionalHeader.DataDirArray.DataDir3.Size == 0) ) { return; } //FixMe } //Security Directory 4 void ParseSecurity() { if( (NtHeader.OptionalHeader.DataDirArray.DataDir4.VirtualAddress == 0) || (NtHeader.OptionalHeader.DataDirArray.DataDir4.Size == 0) ) { return; } //FixMe } //Relocation Directory 5 void ParseBaseReloc() { if( (NtHeader.OptionalHeader.DataDirArray.DataDir5.VirtualAddress == 0) || (NtHeader.OptionalHeader.DataDirArray.DataDir5.Size == 0) ) { return; } FSeek( RVA2FOA(NtHeader.OptionalHeader.DataDirArray.DataDir5.VirtualAddress) ); BASE_RELOCATION_TABLE RelocTable; } //Debug Directory 6 void ParseDebug() { if( (NtHeader.OptionalHeader.DataDirArray.DataDir6.VirtualAddress == 0) || (NtHeader.OptionalHeader.DataDirArray.DataDir6.Size == 0) ) { return; } //FixMe } //TLS 9 void ParseTLS() { if( (NtHeader.OptionalHeader.DataDirArray.DataDir9.VirtualAddress == 0) || (NtHeader.OptionalHeader.DataDirArray.DataDir9.Size == 0) ) { return; } //FixMe } //Bound Import 11 void ParseBoundImport() { if( (NtHeader.OptionalHeader.DataDirArray.DataDir11.VirtualAddress == 0) || (NtHeader.OptionalHeader.DataDirArray.DataDir11.Size == 0) ) { return; } //FixMe } //Delay Import 13 void ParseDelayImport() { if( (NtHeader.OptionalHeader.DataDirArray.DataDir13.VirtualAddress == 0) || (NtHeader.OptionalHeader.DataDirArray.DataDir13.Size == 0) ) { return; } //FixMe } //-------------------------------------------------------------------------------------------------------- //Code Printf("Parse PE Begin.\n"); IMAGE_DOS_HEADER DosHeader; if (DosHeader.e_magic != 0x5A4D) { Printf("invalid dos magic.\n"); return 1; } if (0 == DosHeader.e_lfanew ) { Warning("not invalid e_lfanew = 0x%X",DosHeader.e_lfanew); return 2; } UCHAR Space1[DosHeader.e_lfanew - sizeof(IMAGE_DOS_HEADER)] ; Printf("Space between dos header and nt header is %d bytes \n",DosHeader.e_lfanew - sizeof(IMAGE_DOS_HEADER)); FSeek(DosHeader.e_lfanew); 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.e_lfanew + 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");