0x0 基础知识
00 区段名及其含义
区段名 | 含义 |
.text | 默认的代码区块, 它的内容全是指令代码,链接器把所有目标文件的text块连接成一个大的.text块,使用Borland C++编译器产生的代码存放在CODE的区域里 |
.data | 默认的读/写数据块, 全局变量, 静态变量一般放在这个区段 |
.rdata | 默认只读数据区块,但程序中很少用到该块中的数据,一般两种情况用到,一是MS 的链接器产生EXE文件中用于存放调试目录,二是用于存放说明字符串,如果程序的DEF文件中指定了DESCRIPTION,字符串就会出现在rdata中 |
.idata | 包含其他外来的DLL的函数及数据信息, 即 |
.edata | |
.rsrc | |
.bss | 未初始化的数据,很少在用,取而代之的是执行文件的.data区块的的VirtualSize被扩展大的空间里用来装未初始化的数据. |
.crt | 用于C++ 运行时(CRT)所添加的数据 |
.tls | |
.reloc | |
.sdata | 相对于全局指针的可被定位的 短的读写数据 |
.pdata | 异常表, 包含CPU特定的IAMGE_RUNTIME_FUNTION_ENTRY结构数组,DataDirectory中的IMAGE_DIRECTORY_ENTRY_EXCEPTION指向它. |
.didat |
01 区段类别及分布
区段示例
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; // 8 bytes 块名
union {
DWORD PhysicalAddress; // 无
DWORD VirtualSize;
} Misc;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
- Name:区段的名称
- VirtualSize:区段在内存对齐中的大小
- VirtualOffset:区段在内存中的相对虚拟地址RVA
- RawSize:区段在文件对齐后的的大小
- RawOffset:区段在文件中的偏移地址
- Characteristics:特征值(下图中我们可以看到.text特征值600000020)
从区段表不难发现:.text段的RVA为1000,大小为4B48,也就是说.text区段在内存中的位置是从1000~5B48。其他区段也不难得出
通过区段图,得出程序加载到内存后的分布以及文件在硬盘的分布
- 程序加载到内存之后,都会分配4GB的内存地址空间(注:并不是内存大小)
- 在区段与区段之间并不是紧挨着的,因为内存会进行0x1000的内存对齐,空出来的空间进行填充0字节的数据。例如5B4B~6000的空间都是填充的0字节数据
如何正确识别一个区段为代码段
注:代码段的真正识别并不是根据.text名来判断,后面我们会知道,将.text修改后是不会影响到我们程序的真正运行的
- 方法一:通过Image_Option_Header中代码块起始RVA(BaseOfCode)中的地址
- 方法二:通过区段的特征值标志(属性)MEM_EXECUTE(可执行)、MEM_READ(可读),判断这个是代码段。例如 .text 区段(通过右击区段行,选择Edit Header即可查看):
注:并没有勾选MEN_WRITE标志,因为程序运行的一般情况下是不允许代码进行变化的。当然,我们也可以进行改变属性为可写,此时可称之为SMC(Self Modify Code 可变代码),程序在运行的时候,可能会对自身的代码进行修改,实现一些功能上的变化,比如产生偏移量的变化。当然如果实现自变形的功能,必须添加MEM_WRITE属性,否则会程序的崩溃。
0x1 实现代码
© 版权声明
THE END
暂无评论内容