btparser/cparser/tests/PETemplate.bt

821 lines
29 KiB
Plaintext
Raw Normal View History

//--------------------------------------
//--- 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 <format=hex,comment="IMAGE_DOS_SIGNATURE = 0x5A4D">;
WORD e_cblp <comment="Bytes on last page of file">;
WORD e_cp <comment="Pages in file">;
WORD e_crlc <comment="Relocations">;
WORD e_cparhdr <comment="Size of header in paragraphs">;
WORD e_minalloc <comment="Minimum extra paragraphs needed">;
WORD e_maxalloc <comment="Maximum extra paragraphs needed">;
WORD e_ss <comment="Initial (relative) SS value">;
WORD e_sp <comment="Initial SP value">;
WORD e_csum <comment="Checksum">;
WORD e_ip <comment="Initial IP value">;
WORD e_cs <comment="Initial (relative) CS value">;
WORD e_lfarlc <comment="File address of relocation table">;
WORD e_ovno <comment="Overlay number">;
WORD e_res[4] <comment="Reserved words">;
WORD e_oemid <comment="OEM identifier (for e_oeminfo)">;
WORD e_oeminfo <comment="OEM information; e_oemid specific">;
WORD e_res2[10] <comment="Reserved words">;
LONG e_lfanew <fgcolor=cPurple,format=hex,comment="NtHeader Offset">;
} IMAGE_DOS_HEADER;
typedef enum<WORD> _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 <comment="WORD">;
//Characteristics
typedef struct _FILE_CHARACTERISTICS
{
WORD IMAGE_FILE_RELOCS_STRIPPED:1 <comment="0x0001 Relocation info stripped from file">;
WORD IMAGE_FILE_EXECUTABLE_IMAGE:1 <comment="0x0002 File is executable">;
WORD IMAGE_FILE_LINE_NUMS_STRIPPED:1 <comment="0x0004 Line nunbers stripped from file">;
WORD IMAGE_FILE_LOCAL_SYMS_STRIPPED:1 <comment="0x0008 Local symbols stripped from file">;
WORD IMAGE_FILE_AGGRESIVE_WS_TRIM:1 <comment="0x0010 Agressively trim working set">;
WORD IMAGE_FILE_LARGE_ADDRESS_AWARE:1 <comment="0x0020 App can handle >2gb addresses">;
WORD :1 <comment="0x0040 Reserved",hidden=true>;
WORD IMAGE_FILE_BYTES_REVERSED_LO:1 <comment="0x0080 Bytes of machine word are reversed">;
WORD IMAGE_FILE_32BIT_MACHINE:1 <comment="0x0100 32 bit word machine">;
WORD IMAGE_FILE_DEBUG_STRIPPED:1 <comment="0x0200 Debugging info stripped from file in .DBG file">;
WORD IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP:1 <comment="0x0400 If Image is on removable media, copy and run from the swap file">;
WORD IMAGE_FILE_NET_RUN_FROM_SWAP:1 <comment="0x0800 If Image is on Net, copy and run from the swap file">;
WORD IMAGE_FILE_SYSTEM:1 <comment="0x1000 System File">;
WORD IMAGE_FILE_DLL:1 <comment="0x2000 File is a DLL">;
WORD IMAGE_FILE_UP_SYSTEM_ONLY:1 <comment="0x4000 File should only be run on a UP machine">;
WORD IMAGE_FILE_BYTES_REVERSED_HI:1 <comment="0x8000 Bytes of machine word are reversed">;
}FILE_CHARACTERISTICS <comment="WORD">;
typedef struct _IMAGE_FILE_HEADER
{
IMAGE_MACHINE Machine <fgcolor=cPurple,format=hex,comment="WORD">;
WORD NumberOfSections <fgcolor=cBlue,comment="Section num">;
time_t TimeDateStamp <format=hex,comment="DWORD,from 01/01/1970 12:00 AM">;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
FILE_CHARACTERISTICS Characteristics <comment="WORD">;
}IMAGE_FILE_HEADER;
typedef struct _IMAGE_DATA_DIRECTORY
{
DWORD VirtualAddress <format=hex,comment=CommentRVA2FOA>;
DWORD Size;
}IMAGE_DATA_DIRECTORY;
typedef struct _IMAGE_DATA_DIRECTORY_ARRAY
{
IMAGE_DATA_DIRECTORY DataDir0 <comment="IMAGE_DIRECTORY_ENTRY_EXPORT">;
IMAGE_DATA_DIRECTORY DataDir1 <fgcolor=cPurple,comment="IMAGE_DIRECTORY_ENTRY_IMPORT">;
IMAGE_DATA_DIRECTORY DataDir2 <comment="IMAGE_DIRECTORY_ENTRY_RESOURCE">;
IMAGE_DATA_DIRECTORY DataDir3 <comment="IMAGE_DIRECTORY_ENTRY_EXCEPTION">;
IMAGE_DATA_DIRECTORY DataDir4 <comment="IMAGE_DIRECTORY_ENTRY_SECURITY">;
IMAGE_DATA_DIRECTORY DataDir5 <fgcolor=cPurple,comment="IMAGE_DIRECTORY_ENTRY_BASERELOC">;
IMAGE_DATA_DIRECTORY DataDir6 <comment="IMAGE_DIRECTORY_ENTRY_DEBUG">;
IMAGE_DATA_DIRECTORY DataDir7 <comment="IMAGE_DIRECTORY_ENTRY_ARCHITECTURE">;
IMAGE_DATA_DIRECTORY DataDir8 <comment="IMAGE_DIRECTORY_ENTRY_GLOBALPTR">;
IMAGE_DATA_DIRECTORY DataDir9 <comment="IMAGE_DIRECTORY_ENTRY_TLS">;
IMAGE_DATA_DIRECTORY DataDir10 <comment="IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG">;
IMAGE_DATA_DIRECTORY DataDir11 <comment="IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT">;
IMAGE_DATA_DIRECTORY DataDir12 <fgcolor=cPurple,comment="IMAGE_DIRECTORY_ENTRY_IAT">;
IMAGE_DATA_DIRECTORY DataDir13 <comment="IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT">;
IMAGE_DATA_DIRECTORY DataDir14 <comment="IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR">;
IMAGE_DATA_DIRECTORY DataDir15 <comment="System Reserved">;
}IMAGE_DATA_DIRECTORY_ARRAY;
typedef enum<WORD> _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<comment="WORD">;
typedef struct _DLL_CHARACTERISTICS
{
WORD IMAGE_LIBRARY_PROCESS_INIT:1 <comment="0x0001 Reserved",hidden=true>;
WORD IMAGE_LIBRARY_PROCESS_TERM:1 <comment="0x0002 Reserved",hidden=true>;
WORD IMAGE_LIBRARY_THREAD_INIT:1 <comment="0x0004 Reserved",hidden=true>;
WORD IMAGE_LIBRARY_THREAD_TERM:1 <comment="0x0008 Reserved",hidden=true>;
WORD :2 <comment="0x0010,0x0020",hidden=true>;
WORD IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE:1 <comment="0x0040">;
WORD IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY:1 <comment="0x0080">;
WORD IMAGE_DLLCHARACTERISTICS_NX_COMPAT:1 <comment="0x0100">;
WORD IMAGE_DLLCHARACTERISTICS_NO_ISOLATION:1 <comment="0x0200">;
WORD IMAGE_DLLCHARACTERISTICS_NO_SEH:1 <comment="0x0400">;
WORD IMAGE_DLLCHARACTERISTICS_NO_BIND:1 <comment="0x0800">;
WORD :1 <comment="0x1000",hidden=true>;
WORD IMAGE_DLLCHARACTERISTICS_WDM_DRIVER:1 <comment="0x2000">;
WORD :1 <comment="0x4000",hidden=true>;
WORD IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE:1 <comment="0x8000">;
}DLL_CHARACTERISTICS <comment="WORD">;
typedef enum<WORD> _OPTIONAL_MAGIC
{
PE32=0x10b,
PE64=0x20b,
ROM=0x107
}OPTIONAL_MAGIC <comment="WORD">;
typedef struct _IMAGE_OPTIONAL_HEADER32
{
OPTIONAL_MAGIC Magic <format=hex>;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode <format=hex>;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint <fgcolor=cPurple,format=hex,comment=CommentRVA2FOA>;
DWORD BaseOfCode <format=hex,comment=CommentRVA2FOA>;
DWORD BaseOfData <format=hex,comment=CommentRVA2FOA>;
DWORD ImageBase <format=hex>;
DWORD SectionAlignment <format=hex>;
DWORD FileAlignment <format=hex>;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage <format=hex>;
DWORD SizeOfHeaders <format=hex>;
DWORD CheckSum <format=hex>;
IMAGE_SUBSYSTEM Subsystem;
DLL_CHARACTERISTICS DllCharacteristics;
DWORD SizeOfStackReserve <format=hex>;
DWORD SizeOfStackCommit <format=hex>;
DWORD SizeOfHeapReserve <format=hex>;
DWORD SizeOfHeapCommit <format=hex>;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY_ARRAY DataDirArray;
}IMAGE_OPTIONAL_HEADER32;
typedef struct _IMAGE_OPTIONAL_HEADER64
{
OPTIONAL_MAGIC Magic <format=hex>;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint <format=hex,comment=CommentRVA2FOA>;
DWORD BaseOfCode <format=hex>;
ULONGLONG ImageBase <format=hex>;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage <format=hex>;
DWORD SizeOfHeaders;
DWORD CheckSum;
IMAGE_SUBSYSTEM Subsystem;
DLL_CHARACTERISTICS DllCharacteristics;
ULONGLONG SizeOfStackReserve <format=hex>;
ULONGLONG SizeOfStackCommit <format=hex>;
ULONGLONG SizeOfHeapReserve <format=hex>;
ULONGLONG SizeOfHeapCommit <format=hex>;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY_ARRAY DataDirArray;
}IMAGE_OPTIONAL_HEADER64;
typedef struct _IMAGE_NT_HEADERS
{
DWORD Signature <format=hex,comment="IMAGE_NT_SIGNATURE = 0x00004550">;
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 <size=CalcImageNtHeadersSize>;
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 <hidden=true,comment="0x00000001 Reserved">;
ULONG IMAGE_SCN_TYPE_NOLOAD:1 <hidden=true,comment="0x00000002 Reserved">;
ULONG IMAGE_SCN_TYPE_GROUP:1 <hidden=true,comment="0x00000004 Reserved">;
ULONG IMAGE_SCN_TYPE_NO_PAD:1 <comment="0x00000008 Reserved">;
ULONG IMAGE_SCN_TYPE_COPY:1 <hidden=true,comment="0x00000010 Reserved">;
ULONG IMAGE_SCN_CNT_CODE:1 <comment="0x00000020 Section contains code">;
ULONG IMAGE_SCN_CNT_INITIALIZED_DATA:1 <comment="0x00000040 Section contains initialized data">;
ULONG IMAGE_SCN_CNT_UNINITIALIZED_DATA:1 <comment="0x00000080 Section contains uninitialized data">;
ULONG IMAGE_SCN_LNK_OTHER:1 <comment="0x00000100 Reserved">;
ULONG IMAGE_SCN_LNK_INFO:1 <comment="0x00000200 Section contains comments or some other type of information">;
ULONG IMAGE_SCN_TYPE_OVER:1 <hidden=true,comment="0x00000400 Reserved">;
ULONG IMAGE_SCN_LNK_REMOVE:1 <comment="0x00000800 Section contents will not become part of image">;
ULONG IMAGE_SCN_LNK_COMDAT:1 <comment="0x00001000 Section contents comdat">;
ULONG :1 <comment="0x00002000 Reserved">;
ULONG IMAGE_SCN_NO_DEFER_SPEC_EXC:1 <hidden=true,comment="0x00004000 Reset speculative exceptions handling bits in the TLB entries for this section.">;
ULONG IMAGE_SCN_GPREL:1 <comment="0x00008000 Section content can be accessed relative to GP">;
ULONG IMAGE_SCN_MEM_SYSHEAP:1 <hidden=true,comment="0x00010000 Obsolete">;
ULONG IMAGE_SCN_MEM_16BIT:1 <comment="0x00020000">;
ULONG IMAGE_SCN_MEM_LOCKED:1 <comment="0x00040000 ">;
ULONG IMAGE_SCN_MEM_PRELOAD:1 <comment="0x00080000">;
ULONG IMAGE_SCN_ALIGN_1BYTES:1 <comment="0x00100000">;
ULONG IMAGE_SCN_ALIGN_2BYTES:1 <comment="0x00200000">;
ULONG IMAGE_SCN_ALIGN_8BYTES:1 <comment="0x00400000">;
ULONG IMAGE_SCN_ALIGN_128BYTES:1 <comment="0x00800000">;
ULONG IMAGE_SCN_LNK_NRELOC_OVFL:1 <comment="0x01000000 Section contains extended relocations">;
ULONG IMAGE_SCN_MEM_DISCARDABLE:1 <comment="0x02000000 Section can be discarded.">;
ULONG IMAGE_SCN_MEM_NOT_CACHED:1 <comment="0x04000000 Section is not cachable">;
ULONG IMAGE_SCN_MEM_NOT_PAGED:1 <comment="0x08000000 Section is not pageable.">;
ULONG IMAGE_SCN_MEM_SHARED:1 <comment="0x10000000 Section is shareable">;
ULONG IMAGE_SCN_MEM_EXECUTE:1 <comment="0x20000000 Section is executable">;
ULONG IMAGE_SCN_MEM_READ:1 <comment="0x40000000 Section is readable">;
ULONG IMAGE_SCN_MEM_WRITE:1 <comment="0x80000000 Section is writeable">;
}SECTION_CHARACTERISTICS;
typedef struct _IMAGE_SECTION_HEADER
{
BYTE Name[8] <comment="can end without zero">;
union {
DWORD PhysicalAddress;
DWORD VirtualSize;
} Misc;
DWORD VirtualAddress <format=hex>;
DWORD SizeOfRawData <format=hex>;
DWORD PointerToRawData <format=hex>;
DWORD PointerToRelocations<format=hex>;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
SECTION_CHARACTERISTICS Characteristics <format=hex>;
}IMAGE_SECTION_HEADER;
typedef struct _IMAGE_SECTION_DATA(IMAGE_SECTION_HEADER& SecHeader)
{
local string sSecName=SecHeader.Name;
UCHAR Data[SecHeader.SizeOfRawData];
}IMAGE_SECTION_DATA <comment=commentSectionData>;
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 <comment=commentImageImportByName>;
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 <format=hex,comment=CommentRVA2FOA>;
}DUMMYUNIONNAME;
ULONG TimeDateStamp <comment="0 if not bound">;
ULONG ForwarderChain <comment="-1 if no forwarders">;
ULONG Name <format=hex,comment=CommentRVAString>;
ULONG FirstThunk <format=hex,comment=CommentRVA2FOA>;
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)<open=false>;
}
}
nNameIndex++;
}
}
}IMAGE_IMPORT_DESCRIPTOR <comment=commentImageImportDescriptor>;
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 <read=ReadExportByName,comment=commentExportByName>;
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 <format=hex,comment=CommentRVAString>;
DWORD Base;
DWORD NumberOfFunctions;
DWORD NumberOfNames;
DWORD AddressOfFunctions <format=hex,comment=CommentRVA2FOA>; // RVA from base of image
DWORD AddressOfNames <format=hex,comment=CommentRVA2FOA>; // RVA from base of image
DWORD AddressOfNameOrdinals <format=hex,comment=CommentRVA2FOA>; // 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 <comment=commentExportDirectory>;
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 <format=hex,comment=CommentRVA2FOA>;
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<format=hex,comment=CommentBaseRelocBlock>;
}
} IMAGE_BASE_RELOCATION <comment=commentImageBaseRelocation>;
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 <comment=commentBaseRelocationTable>;
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)] <hidden=true,fgcolor=cRed,comment="Space between dos header and nt 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 ] <hidden=true,fgcolor=cRed,comment="Space between header and first section">;
}
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");