手动添加重定位
00 什么是重定位
- 什么是重定位?
- 在32程序中内存有4G空间,其中高2G是系统空间,低2G是用户空间,当一个程序被加载,会被安排到这个空间中的某个地方,默认情况下EXE会被加载到0x00400000,dll会被加载到0x10000000位置。
- 一般情况下dll都必须开启重定位,应为一个程序中会存在多个dll,如果全部的dll都加载到0x10000000位置,dll相互直接会被覆盖。而exe可以选择不开启重定位,一个程序中只有一个主模块。
- 而在程序中,如果有引用到绝对地点的代码,例如下

- 加载器怎样修复重定位的?
- 当一个可执行程序,被加载到内存中,首先会判断是否开启随机基址,可以通过两个字段
IMAGE_FILE_HEADER FileHeader; //文件头FileHeader.Characteristics; // 属性字段IMAGE_OPTIONAL_HEADER OptionalHeader;// 扩展头OptionalHeader.DllCharacteristics;// 属性字段
- 当这个两个属性中都开启了随机基址后,那么加载器就会找数据目次表【5】项,(重定位表)
- 这个重定位指向一个结构体,该结构是一个不定长度的表
typedef struct _IMAGE_BASE_RELOCATION { DWORD VirtualAddress; //RVA,指向一个分页的基址,都是0x1000的倍数 DWORD SizeOfBlock; //这个重定位数据总大小// WORD TypeOffset[1]; //需要修复的数据块项,个数= (SizeOfBlock-8)/2} IMAGE_BASE_RELOCATION;typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;// 数据块结构typedef struct _TYPEDATA { WORD offset : 12; // 一个分页的偏移 WORD type : 4; // 重定位块的属性,通常如果为3,表示32位地点需要修复}TYPEDATA, * PTYPEDATA;
- 加载器中这个重定位表获取 VirtualAddress + TYPEDATA.offset 找到要修复的数据,按照修复公式举行修复
修复后的地点 = 待修复的数据(0x00402000) - 默认基址(0x00400000) + 当前加载基址(0x00A80000)
</ul>02 开启重定位
- 将FileHeader.Characteristics第0位置0

</ul>03 构建重定位表
- 为了给程序添加一个重定位表,我们可以找到一个空白的区域,或者添加一个区段,作为重定位表,然后让数据目次表【5】,重定位表指向它。
- 在这个程序中我选择0x880这个文件偏移(FOA)位置,作为重定位表

、


来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |