之前的笔记搬运
0x1 Dos头
在可执行文件中, 第一个结构就是DOS头
1 | IMAGE_DOS_HEADER STRUCT |
图中蓝框圈住的就是Dos头, 因为历史遗留的问题, 是在DOS系统下运行的代码和信息
这个结构里只有e_magic 和 e_lfanew是必须的, 就也是红框圈住的
0x2 PE文件头
紧跟着DOS头的就是PE文件头
1 | IMAGE_NT_HEADERS STRUCT { |
0x3 映象文件头
1 | typedef struct _IMAGE_FILE_HEADER |
Machine: Intel平台一般是14C
NumberOfSections : 记录此程序节的数量
SizeOfOptionalHeader: 记录选择头结构的大小, 程序运行时依靠此大小来访问节表,
一般大小为E0, 而OD不是读取此值而是写的死值E0来访问节表,
所以可以通过更改此值来达到反调试的效果
Characteristics: 文件属性, 一般是用位来记录, 或运算后得到的值
常用的属性位:
1 | 0x0001: 文件没有重定位 |
0x4 选择头结构
1 | typedef struct _IMAGE_OPTIONAL_HEADER |
Magic: 标志位表示文件是ROM(0x0107), 32位程序(0x010B), 还是64位程序(0x020B)
SizeOfCode: 所有含代码的节的总大小,
但是OD在分析代码时会申请这个值大小的空间用作分析代码的空间, 修改这个值很大时,
OD在分析代码时会很慢甚至卡死, 达到干扰和反调试目的
SizeOfInitializedData: (不一定正确)所有含已初始化数据的节的总大小,
就是在编译时所构成的块大小
SizeOfUninitializedData: (不一定正确)所有含未初始化数据的节的总大小
AddressOfEntryPoint: 程序执行入口(RVA)
BaseOfCode: 代码段起始地址(RVA)
BaseOfData: 代码段的起始地址(RVA)
ImageBase: 程序装入内存的首选地址
SectionAlignment: 内存中的区块的对齐大小
FileAlignment: 文件中的区块的对齐大小
SizeOfImage: 映像装入内存后的总尺寸, 这里表示所有区段的大小, 必须如实填写,
不符合大小无法运行
SizeOfHeaders: 所有头 + 区块表的尺寸大小, 也就是到第一个节前的大小
0x5 数据目录
1 | typedef struct _IMAGE_DATA_DIRECTORY { |
黑色标记为常用项, 其余不用关心:
Offset (PE/PE32+) | Description |
---|---|
96/112 | Export table address and size |
104/120 | Import table address and size |
112/128 | Resource table address and size |
120/136 | Exception table address and size |
128/144 | Certificate table address and size |
136/152 | Base relocation table address and size |
144/160 | Debugging information starting address and size |
152/168 | Architecture-specific data address and size |
160/176 | Global pointer register relative virtual address |
168/184 | Thread local storage (TLS) table address and size |
176/192 | Load configuration table address and size |
184/200 | Bound import table address and size |
192/208 | Import address table address and size |
200/216 | Delay import descriptor address and size |
208/224 | The CLR header address and size |
216/232 | Reserved |
0x6 节表
1 | typedef struct _IMAGE_SECTION_HEADER |
Name:区块名。这是一个由8位的char, 说明信息, 可以任意更改
Virtual
Size:该区块表对应的区块的大小,这是区块的数据在没有进行对齐处理前的实际大小。
Virtual Address:该区块装载到内存中的RVA 地址。这个地址是按照内存页来对齐的
SizeOfRawData:该区块在磁盘中所占的大小。
PointerToRawData:该区块在磁盘中的偏移。这个数值是从文件头开始算起的偏移量哦。
PointerToRelocations:这哥们在EXE文件中没有意义,在OBJ
文件中,表示本区块重定位信息的偏移值。(在OBJ
文件中如果不是零,它会指向一个IMAGE_RELOCATION 结构的数组)
PointerToLinenumbers:行号表在文件中的偏移值,文件的调试信息,于我们没用,鸡肋。
NumberOfRelocations:这哥们在EXE文件中也没有意义,在OBJ
文件中,是本区块在重定位表中的重定位数目来着。
NumberOfLinenumbers:该区块在行号表中的行号数目,鸡肋。
Characteristics:该区块的属性。该字段是按位来指出区块的属性(如代码/数据/可读/可写等)的标志。