Useful Tools:
1. WDK安装目录下搜下depends.exe,这个工具可以查看.exe文件依赖的.dll,以及用到的dll中的api。
2.PE文件格式分析器:
有很多的PE格式分析器,我随便试了两个,lordPE.exe,prjPEParserEx.exe都还不错,放我百度云盘了。
http://yun.baidu.com/share/link?shareid=2025240688&uk=758458210
3.Visual Studio自带的的dumpbin工具
dumpbin /ALL xxx.exe >>xx.txt
PE文件格式适用于.exe,.dll,.sys文件(.obj->COFF类似)
PE文件的布局:
__________________________________
| |<----Base of Image Header
| DOS compatible EXE header |--|
|__________________________________| |
| | |
| Unused | |
|__________________________________| |
| | |
| OEM identifier | |
|__________________________________| |
| | |
| OEM info | |-->Uninteresting(DOS Compatibility)
|__________________________________| |
| | |
| Offset to PE Header |----->Very interesting
|__________________________________| |
| | |
| DOS Stub program and reloc table | |
|__________________________________| |
| | |
| Unused |__|
|__________________________________|
| |
| PE header(IMAGE_FILE_HEADER) |--|
|__________________________________| |
| | |
| PE header(IMAGE_OPTIONAL_HEADER) | |
|__________________________________| |-->Very very interesting :)
| | |
| Section Table | |
|__________________________________| |
| | |
| Sections |__|
|__________________________________|
★ Dos Header Info (IMAGE_DOS_HEADER)
IMAGE_DOS_HEADER的定义如下
1 typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header 2 WORD e_magic; // Magic number 3 WORD e_cblp; // Bytes on last page of file 4 WORD e_cp; // Pages in file 5 WORD e_crlc; // Relocations 6 WORD e_cparhdr; // Size of header in paragraphs 7 WORD e_minalloc; // Minimum extra paragraphs needed 8 WORD e_maxalloc; // Maximum extra paragraphs needed 9 WORD e_ss; // Initial (relative) SS value 10 WORD e_sp; // Initial SP value 11 WORD e_csum; // Checksum 12 WORD e_ip; // Initial IP value 13 WORD e_cs; // Initial (relative) CS value 14 WORD e_lfarlc; // File address of relocation table 15 WORD e_ovno; // Overlay number 16 WORD e_res[4]; // Reserved words 17 WORD e_oemid; // OEM identifier (for e_oeminfo) 18 WORD e_oeminfo; // OEM information; e_oemid specific 19 WORD e_res2[10]; // Reserved words 20 LONG e_lfanew; // File address of new exe header 21 } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
比较有用的是:e_lfanew,表示IMAGE_NT_HEADERS在文件中地址。
★ PE Header Info (IMAGE_NT_HEADER)
1 IMAGE_NT_HEADERS STRUCT{ 2 +00H DWORD Signature 3 +04H IMAGE_FILE_HEADER FileHeader 4 +18H IMAGE_OPTIONAL_HEADER32 OptionalHeader 5 }IMAGE_NT_HEADERS
★ File Header Info (IMAGE_FILE_HEADER)
1 typedef struct _IMAGE_FILE_HEADER{ 2 +04H WORD Machine; //运行平台 3 +06H WORD NumberOfSections; //文件的区块数目 !!important 4 +08H DWORD TimeDateStamp; //文件创建日期和事件 5 +0CH DWORD PointerToSymbolTable; //只想符号表(主要用于调试) 6 +10H DWORD NumberOfSymbols; //符号表中的符号个数(同上) 7 +14H WORD SizeOfOptionalHeader; //IMAGE_OPTIONAL_HEADER32结构大小 8 +16H WORD Characteristics; //文件属性 9 }IMAGE_FILE_HEADER,*PIMAGE_FILE_HEADER;
★ Optional Header Info (IMAGE_OPTIONAL_HEADER)
1 typedef struct _IMAGE_OPTIONAL_HEADER{ 2 +28H DWORD AddressOfEntryPoint; // 程序执行入口RVA 3 +34H DWORD ImageBase; // 程序的首选装载地址 4 +38H DWORD SectionAlignment; // 内存中的区块的对齐大小 5 +3CH DWORD FileAlignment; // 文件中的区块的对齐大小 6 +5CH WORD Subsystem; // 可执行文件期望的子系统 7 +78H IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; //IMAGE_NUMBEROF_DIRECTORY_ENTRIES=0x10
8 }IMAGE_OPTIONAL_HEADER32,*PIMAGE_OPTION_HEADER32
Directory Entry的结构
1 IMAGE_DATA_DIRECTORY STRUCT{ 2 VirtualAddress DWORD ? ;相对虚拟地址 3 isize DWORD ? ;大小 4 }IMAGE_DATA_DIRECTORY
那16个Directory Entry,根据其RVA(VirtualAddress)可以推算出其在哪个section,在文件哪个位置。
比如:Export Entry一般在.rdata section中, Import Entry在.idata section(The imports table),
Resource Entry在.rsrc section(The resources),BaseReloc Entry在.reloc section
Debug Entry 在.rdata section, IAT Entry在.idata section...
★ Section Header Info
1 typedef struct IMAGE_SECTION_HEADER 2 { 3 BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; //IMAGE_SIZEOF_SHORT_NAME = 8 4 union 5 { 6 DWORD PhysicalAddress; 7 DWORD VirtualSize; 8 }Misc; 9 DWORD VirtualAddress; //节被载到内存之后的偏移 10 DWORD SizeOfRawData; 11 DWORD PointerToRawData; 12 DWORD PointerToRelocations; 13 DWORD PointerToLinenumbers; 14 WORD NumberOfRelocations; 15 WORD NumberOfLinenumbers; 16 DWORD Characteristics; 17 }IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
共0x28个Byte.
IMAGE_FILE_HEADER里面会制定section的个数
.text .data .rdata .idata .didat .reloc .rsrc.
在这个section table之后,会按照IMAGE_OPTIONAL_HEADER->FileAlignment来对其,然后就是各个section的内容了。
如果没有symbol啥的信息的话,各个section填完之后,文件就结束了。
=================================================
section table,
所有section都有两个对齐值(文件内offset(0x200),内存offset(一个Page)),section的其实地址需要以此对齐。
如:
01 .text VirtSize: 00074658 VirtAddr: 00001000 raw data offs: 00000400 raw data size: 00074800...
02 .data VirtSize: 000028CA VirtAddr: 00076000 raw data offs: 00074C00 raw data size: 00002400
Can refer this useful link:
http://en.wikibooks.org/wiki/X86_Disassembly/Windows_Executable_Files#Relative_Virtual_Addressing_.28RVA.29