PE文件(十一)移动导出表和重定位表

移动表的原因

一个PE文件中有很多节,每个节都存储不同的数据。而PE文件中的各种表也都分散存储在这些节当中。此时各种表的信息与程序的代码和数据相互混合在一起,如果我们直接对整个程序进行加密,那系统在初始化程序时就会出问题。比如:这些表的数据被加密时,系统就无法根据这些表将用到的.DLL中的函数地址存储到IAT表中,这时候程序就无法正常启动

所以对程序加密或破解之前,需要移动各种表到程序新增的节当中,再对剩下的数据进行加密

注意:DOS头、NT头等所有头和节表是操作系统判断该文件是否为Windows可执行程序的依据,因此这些数据不可以加密。

学会移动各种表,是对程序加密/破解的基础

移动导出表

步骤说明:

在FileBuffer中进行操作,现结合图示来理解移动的步骤

在PE文件FileBuffer中新增一个节,并获取该节的FOA。该表用来存储导出表,节大小按照表的的大小对齐以后计算,粗略估计0x1000字节大小,

新增节时需要修改的数据:

1.修改PE头中的字段:NumberOfSections、SizeOfImage

2.重新开辟一个FileBuffer,并新增节表

3.修改节表中的字段:Name、Misc.VirtualSize、VirtualAddress、SizeOfRawData、PointerToRawData、Characteristics。

新增节进行填充的数据:

1.复制导出表IMAGE_EXPORT_DIRECTORY到新节中,大小固定40字节

2.复制AddressOfFunctions指向的函数地址表到新节中(注意RVA转FOA),数据大小为4 * NumberOfFunctions字节

3.复制AddressOfNameOrdinals指向的函数序号表到新节中,数据大小为2 * NumberOfNames字节

4.复制AddressOfNames指向的函数名称表到新节中,数据大小为4 * NumberOfNames字节

5.依次复制函数名称表中元素所指向的函数名称字符串到新节中,注意以00结尾。遍历函数名称表,用strlen()函数依次求出每个字符串长度,再求和。每复制一个字符串到新节中,就修改对应的函数名称表中的地址值

注意:函数名称表中存的是RVA,所以把字符串复制到新节后还需要把FOA转成RVA,再存入

如果只移动函数名称表的话,对剩下的数据加密后,当需要根据函数名去调用导出函数时,由于字符串被加密,只能根据函数名称表查到名称字符串所在地址,但是无法匹配字符串。

6.修改导出表中的成员值,指向三个子表在新节中的位置,由于各个子表在导出表的地址数据是RVA,因此需要将FOA转成RVA

7.最后修复导出表数据目录中的VirtualAddress,指向导出表IMAGE_EXPORT_DIRECTORY在新节中的位置,该地址也要FOA转RVA

移动重定位表

步骤说明

结合图示来理解移动重定位表过程:

1.新增节,大小能够循环遍历重定位表的每个块,即把所有块的SizeOfBlock求和 + 结束标记8字节最后再对齐,粗略估算0x1000就满足大部分情况了

2.复制重定位表到新节中,大小为所有块的SizeOfBlock求和 + 结束标记8字节

3.修改重定位表数据目录中的VirtualAddress,指向重定位表在新节中的位置即可(FOA转RVA)

4.修复重定位表:根据重定位表中的各个具体项,去修改具体项指向的地方的值。这个值可能是DLL中全局变量的绝对地址,或者是DLL中函数的绝对地址等

一般情况下一个PE文件自身的.exe的ImageBase很少会和其子PE文件ImageBase发生冲突,但是.dll文件容易发生冲突。默认情况下.DLL的ImageBase为0x10000000,所以如果一个程序要用的DLL没有合理的修改分配装载起始地址,就可能出现多个DLL的ImageBase都是同一个地址,造成装载冲突

现在我们自己故意修改一个DLL文件的ImageBase,再根据其重定位表去修正,最后存盘,看此DLL文件是否可以正常使用,即手动模拟操作系统修复重定位表的过程

修正过程:比如DLL的ImageBase原来为0x400000,现在修改为0x500000;接着找到重定位表,遍历每个块中的具体项,根据具体项去找哪里的地址值需要修改重定位;找到后,将原来的地址值 + (0x500000 - 0x400000)即可

作业

1.在DLL新增一个节,并将导出表信息移动到这个新的节中,
2.使用工具打开修改后的DLL看能否正常解析.
3.在DLL中新增一个节,并将重定位表移动到这个新的节中,
4.修改DLL的ImageBase,根据重定位表修正,然后存盘.看叫号否可以使用.
 

  • 15
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值