吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6600|回复: 31
收起左侧

[调试逆向] 手动添加重定位

  [复制链接]
fily 发表于 2021-6-4 15:14
本帖最后由 fily 于 2021-6-4 20:12 编辑

手动添加重定位

00 什么是重定位

  • 什么是重定位?

    • 在32程序中内存有4G空间,其中高2G是系统空间,低2G是用户空间,当一个程序被加载,会被安排到这个空间中的某个地方,默认情况下EXE会被加载到0x00400000,dll会被加载到0x10000000位置。

    • 一般情况下dll都必须开启重定位,应为一个程序中会存在多个dll,如果所有的dll都加载到0x10000000位置,dll相互直接会被覆盖。而exe可以选择不开启重定位,一个程序中只有一个主模块。

    • 而在程序中,如果有引用到绝对地址的代码,例如下

1.png

  • 那么程序如果开启随机基址,那么这个指令将执行失败,应为它并不是指向当前加载的地址,而是以0x00400000为基址的数据,此时这个地址是无法访问的。

2.png

  • 加载器如何修复重定位的?

    • 当一个可执行程序,被加载到内存中,首先会判断是否开启随机基址,可以通过两个字段
    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)
    • 修复后程序可以正常运行

3.png

01 编写测试代码

  • 使用RadAsm编写测试代码
.386
.model flat,stdcall

include user32.inc
includelib user32.lib

.data
        szText db "hello",0

.code
main:
        push 0
        push 0
        push offset szText ;待修复的地址 0x00403000
        push 0
        call MessageBox
        ret
end main
end
  • 该程序没有重定位表,没有开启随机基址
    4.png

02 开启重定位

  • 将FileHeader.Characteristics第0位置0

5.png

  • 将OptionalHeader.DllCharacteristics的第4位置为1

    6.png

03 构建重定位表

  • 为了给程序添加一个重定位表,我们可以找到一个空白的区域,或者添加一个区段,作为重定位表,然后让数据目录表【5】,重定位表指向它。

  • 在这个程序中我选择0x880这个文件偏移(FOA)位置,作为重定位表

7.png

  • 但是由于PE文件中绝大部分地址保存的都是RVA,所以我们需要将FOA转换为RVA。转换公式

    RVA  = FOA(0x880) - FOA区段偏移(0x800) + RVA区段内存偏移(0x3000)
    RVA  = 0x3080

8.png

  • 确定重定位数据。

9.png

  • 根据重定位表结构,构建数据

    VirtualAddress = 0x1000;                        
    SizeOfBlock= 2*2 + 8 = 0x0C;                        
    TYPE1 = 3005
    TYPE2 = 3014

10.png

  • 最后将数据目录表【5】中填充正偏移和大小即可

11.png

04 验证程序

12.png

免费评分

参与人数 16威望 +1 吾爱币 +34 热心值 +15 收起 理由
catoo1 + 1 + 1 我很赞同!
jiaokai + 1 + 1 谢谢大佬的教程,对DLL加载到EXE程序中 修改程序中调用的DLL常量和绝对地址.
SHY007 + 1 + 1 我很赞同!
kunlun945 + 1 我很赞同!
gunxsword + 1 + 1 谢谢@Thanks!
Foticing + 1 + 1 我很赞同!
shiina0831 + 1 + 1 谢谢@Thanks!
lyl610abc + 3 + 1 我很赞同!
经典柚子 + 1 + 1 已经处理,感谢您对吾爱破解论坛的支持!
一栋 + 1 我很赞同!
这是追求不是梦 + 1 + 1 热心回复!
zyh666 + 1 + 1 感谢科普
diaoes + 1 + 1 涨姿势
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
yunji + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
xzl9552547 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

lyl610abc 发表于 2021-6-5 10:23
fily 发表于 2021-6-4 18:47
末尾图片自己添加进去的,删不了:

帖子还是偏简单了一些,可以添加构造一段无需修复重定位的ShellCode的例子,加深对重定位表的了解
PrincessSnow 发表于 2021-6-4 15:34
8204118 发表于 2021-6-4 15:37
yingsummery 发表于 2021-6-4 15:57
学习了,感谢楼主
Hmily 发表于 2021-6-4 17:22
@fily 最后多了几个图片是忘记插入正文了?
头像被屏蔽
benq7378 发表于 2021-6-4 18:05
提示: 作者被禁止或删除 内容自动屏蔽
 楼主| fily 发表于 2021-6-4 18:47
Hmily 发表于 2021-6-4 17:22
@fily 最后多了几个图片是忘记插入正文了?

末尾图片自己添加进去的,删不了:
sd4060483 发表于 2021-6-4 21:19
这个看着挺厉害的样子
路人王2021 发表于 2021-6-4 21:47

学习了,感谢楼主
haoxiangzuo 发表于 2021-6-4 22:51
谢谢大佬的教学
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-22 10:52

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表