这个是主程序,它的模块信息:
名称 | 基址 | 大小 | 入口点 |
f:embedetoolsDebugbinbash.exe | 00400000 | 0006f000 | 0045bb30 |
对应的内存块:
基址 | 分配基址 | 分配保护 | 大小 | 状态 | 保护 | 类型 |
00400000 | 00400000 | 00000080 PAGE_EXECUTE_WRITECOPY | 00001000 | 00001000 MEM_COMMIT | 00000002 PAGE_READONLY | 01000000 MEM_IMAGE |
00401000 | 00400000 | 00000080 PAGE_EXECUTE_WRITECOPY | 0005c000 | 00001000 MEM_COMMIT | 00000020 PAGE_EXECUTE_READ | 01000000 MEM_IMAGE |
0045d000 | 00400000 | 00000080 PAGE_EXECUTE_WRITECOPY | 00007000 | 00001000 MEM_COMMIT | 00000002 PAGE_READONLY | 01000000 MEM_IMAGE |
00464000 | 00400000 | 00000080 PAGE_EXECUTE_WRITECOPY | 00001000 | 00001000 MEM_COMMIT | 00000008 PAGE_WRITECOPY | 01000000 MEM_IMAGE |
00465000 | 00400000 | 00000080 PAGE_EXECUTE_WRITECOPY | 00003000 | 00001000 MEM_COMMIT | 00000004 PAGE_READWRITE | 01000000 MEM_IMAGE |
00468000 | 00400000 | 00000080 PAGE_EXECUTE_WRITECOPY | 00007000 | 00001000 MEM_COMMIT | 00000002 PAGE_READONLY | 01000000 MEM_IMAGE |
0046f000 | 00000000 | 00000000 | 00001000 | 00010000 MEM_FREE | 00000001 PAGE_NOACCESS | 00000000 |
这些块的类型都是MEM_IMAGE,且分配时的保护标志都是PAGE_EXECUTE_WRITECOPY,MSDN这样解释这个标志位:
Enables execute, read, and write access to the committed region of image file code pages. The pages are shared read-on-write and copy-on-write.
这几个内存块的分配基址都是一样的,猜测windows是为整个文件申请了一块大的空间,然后将文件里面的section分别写入到不同的区域里面去。
用下面的命令行将所有的信息dump出来。
dumpbin /all bash.exe
再把它们和内存里的数据进行比较。
1.1 文件头
先看从原始文件中dump出来的文件头:
FILE HEADER VALUES
14C machine (x86)
5 number of sections
4A910052 time date stamp Sun Aug 23 16:39:46 2009
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
102 characteristics
Executable
32 bit word machine
一共有5个section,但是上面有6个块,怎么就对应不上呢,想来0x0040 0000这个块应该是文件头信息:
0x00400000 4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00 MZ..............
0x00400010 b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ........@.......
0x00400020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x00400030 00 00 00 00 00 00 00 00 00 00 00 00 e0 00 00 00 ................
0x00400040 0e 1f ba 0e 00 b4 09 cd 21 b8 01 4c cd 21 54 68 ........!..L.!Th
0x00400050 69 73 20 70 72 6f 67 72 61 6d 20 63 61 6e 6e 6f is program canno
0x00400060 74 20 62 65 20 72 75 6e 20 69 6e 20 44 4f 53 20 t be run in DOS
0x00400070 6d 6f 64 65 2e 0d 0d 0a 24 00 00 00 00 00 00 00 mode....$.......
0x00400080 b0 80 2d 3c f4 e1 43 6f f4 e1 43 6f f4 e1 43 6f .€-<..Co..Co..Co
0x00400090 49 ae d5 6f f9 e1 43 6f ea b3 d6 6f ff e1 43 6f I..o..Co...o..Co
0x004000A0 ea b3 c7 6f f3 e1 43 6f ea b3 d0 6f f0 e1 43 6f ...o..Co...o..Co
0x004000B0 f4 e1 42 6f 5f e1 43 6f d3 27 38 6f f3 e1 43 6f ..Bo_.Co.'8o..Co
0x004000C0 ea b3 c0 6f 88 e1 43 6f ea b3 d2 6f f5 e1 43 6f ...o..Co...o..Co
0x004000D0 52 69 63 68 f4 e1 43 6f 00 00 00 00 00 00 00 00 Rich..Co........
0x004000E0 50 45 00 00 4c 01 05 00 49 a8 94 4a 00 00 00 00 PE..L...I..J....
0x004000F0 00 00 00 00 e0 00 02 01 0b 01 09 00 00 be 05 00 ................
0x00400100 00 e2 00 00 00 00 00 00 30 bb 05 00 00 10 00 00 ........0.......
0x00400110 00 d0 05 00 00 00 40 00 00 10 00 00 00 02 00 00 ......@.........
0x00400120 05 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 ................
0x00400130 00 f0 06 00 00 04 00 00 60 40 07 00 03 00 40 81 ........`@....@.
0x00400140 00 00 10 00 00 10 00 00 00 00 10 00 00 10 00 00 ................
0x00400150 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 ................
这些内存数据和原始文件头里面的数据是完全相同的。
在c运行库里提供了一个叫__ImageBase的全局变量,存放这个变量的地址就在0x0040 0000,下面给出这个结构体成员的一些值:
e_magic | 0x5a4d | unsigned short |
e_cblp | 0x0090 | unsigned short |
e_cp | 0x0003 | unsigned short |
e_crlc | 0x0000 | unsigned short |
e_cparhdr | 0x0004 | unsigned short |
e_minalloc | 0x0000 | unsigned short |
e_maxalloc | 0xffff | unsigned short |
e_ss | 0x0000 | unsigned short |
e_sp | 0x00b8 | unsigned short |
e_csum | 0x0000 | unsigned short |
e_ip | 0x0000 | unsigned short |
e_cs | 0x0000 | unsigned short |
e_lfarlc | 0x0040 | unsigned short |
e_ovno | 0x0000 | unsigned short |
e_res | 0x0040001c "" | unsigned short [4] |
e_ oemid | 0x0000 | unsigned short |
e_oeminfo | 0x0000 | unsigned short |
e_res2 | 0x00400028 "" | unsigned short [10] |
e_lfanew | 0x000000e0 | long |
注意系统对这个区域的保护:
00400000 | 00400000 | 00000080 PAGE_EXECUTE_WRITECOPY | 00001000 | 00001000 MEM_COMMIT | 00000002 PAGE_READONLY | 01000000 MEM_IMAGE |
这个区域将是只读的。
根据PE文件的规定,在0x3c这个偏移量的位置(也就是__ImageBase.e_lfanew这个成员)指明了IMAGE_FILE_HEAD的偏移量。我们直接用一个IMAGE_FILE_HEAD指针指向这个位置,就可以看到IMAGE_FILE_HEAD的值了:
Machine | 0x014c | unsigned short |
NumberOfSections | 0x0005 | unsigned short |
TimeDateStamp | 0x4a94cfc5 | unsigned long |
PointerToSymbolTable | 0x00000000 | unsigned long |
NumberOfSymbols | 0x00000000 | unsigned long |
SizeOfOptionalHeader | 0x00e0 | unsigned short |
Characteristics | 0x0102 | unsigned short |
再按照这个结构体得到的SizeOfOptionalHeader,我们将得以遍历所有的section head。
紧接着IMAGE_FILE_HEAD之后的是一个叫IMAGE_OPTIONAL_HEAD的结构体,我们直接用一个指针指向这个位置并得到实际的值:
Magic | 0x010b | unsigned short |
MajorLinkerVersion | 0x09 ' | ' |
MinorLinkerVersion | 0x00 | unsigned char |
SizeOfCode | 0x0005be00 | unsigned long |
SizeOfInitializedData | 0x0000e200 | unsigned long |
SizeOfUninitializedData | 0x00000000 | unsigned long |
AddressOfEntryPoint | 0x0005bb60 | unsigned long |
BaseOfCode | 0x00001000 | unsigned long |
BaseOfData | 0x0005d000 | unsigned long |
ImageBase | 0x00400000 | unsigned long |
SectionAlignment | 0x00001000 | unsigned long |
FileAlignment | 0x00000200 | unsigned long |
MajorOperatingSystemVersion | 0x0005 | unsigned short |
MinorOperatingSystemVersion | 0x0000 | unsigned short |
MajorImageVersion | 0 x0000 | unsigned short |
MinorImageVersion | 0x0000 | unsigned short |
MajorSubsystemVersion | 0x0005 | unsigned short |
MinorSubsystemVersion | 0x0000 | unsigned short |
Win32VersionValue | 0x00000000 | unsigned long |
SizeOfImage | 0x0006f000 | unsigned long |
SizeOfHeaders | 0x00000400 | unsigned long |
CheckSum | 0x00077b4f | unsigned long |
Subsystem | 0x0003 | unsigned short |
DllCharacteristics | 0x8140 | unsigned short |
SizeOfStackReserve | 0x00100000 | unsigned long |
SizeOfStackCommit | 0x00001000 | unsigned long |
SizeOfHeapReserve | 0x00100000 | unsigned long |
SizeOfHeapCommit | 0x00001000 | unsigned long |
LoaderFlags | 0x00000000 | unsigned long |
NumberOfRvaAndSizes | 0x00000010 | unsigned long |
DataDirectory | 0x00400158 {VirtualAddress=0x00000000 Size=0x00000000 } | _IMAGE_DATA_DIRECTORY [16] |
[0x0] | {VirtualAddress=0x00000000 Size=0x00000000 } | _IMAGE_DATA_DIRECTORY |
[0x1] | {VirtualAddress=0x00063354 Size=0x00000078 } | _IMAGE_DATA_DIRECTORY |
[0x2] | {VirtualAddress=0x00068000 Size=0x000002b4 } | _IMAGE_DATA_DIRECTORY |
[0x3] | {VirtualAddress=0x00000000 Size=0x00000000 } | _IMAGE_DATA_DIRECTORY |
[0x4] | {VirtualAddress=0x00000000 Size=0x00000000 } | _IMAGE_DATA_DIRECTORY |
[0x5] | {VirtualAddress=0x00069000 Size=0x00005844 } | _IMAGE_DATA_DIRECTORY |
[0x6] | {VirtualAddress=0x0005d2e0 Size=0x0000001c } | _IMAGE_DATA_DIRECTORY |
[0x7] | {VirtualAddress=0x00000000 Size=0x00000000 } | _IMAGE_DATA_DIRECTORY |
[0x8] | {VirtualAddress=0x00000000 Size=0x00000000 } | _IMAGE_DATA_DIRECTORY |
[0x9] | {VirtualAddress=0x00000000 Size=0x00000000 } | _IMAGE_DATA_DIRECTORY |
[0xa] | {VirtualAddress=0x00062ee0 Size=0x00000040 } | _IMAGE_DATA_DIRECTORY |
[0xb] | {VirtualAddress=0x00000000 Size=0x00000000 } | _IMAGE_DATA_DIRECTORY |