有关windows pe的实验系列(一)

以下这些实验的方案,都是建立在理解windows loader加载机制上,能正常运行来设计。选择的实验对象,虽然是任意的程序,但要保证程序内部不会有校验文件自身完整性的代码段,避免程序自身出错信息和系统loader出错信息弄混。


【实验一】Windows 8.1,使用WinHex打开某程序,查看任意的前后紧挨着的二个节头,找到它们对应的节、将前一个节调换到后一个节后面,然后修改节头中的IMAGE_SECTION_HEADER.PointerToRawData为正确的新值。程序仍然可以正常打开运行。

实验步骤一:使用WinHex打开某程序,记录下要修改的节头

.text       EA7C       1000    EC00  600

.data          50      10000     200   F200

.rdata    94A8      11000       9600 F400

实验步骤二:将文件偏移600处的EC00个字节剪切后,插入到文件偏移800处。

实验步骤三:修改二处数据,如下

.text       EA7C       1000    EC00  800

.data          50      10000     200   600

.rdata    94A8      11000       9600 F400


结论:经以前黑箱实验,windows loader遍历节头加载节,会进行有效性检查:Next VirtualAddress == Pre VirtualAddress + VirtualSize;经此实验,说明不会进行这样的有效性检查:后一个PointerToRawData == 前一个PointerToRawData + SizeOfRawData.


【实验二】Windows 8.1,使用WinHex打开某程序,找到任意一个节头,将对应的节数据复制粘贴到文件最后(起址是FileAlignment的整数倍),将原位置的节数据全部填上FF,修改PointerToRawData为正确的值,修改IMAGE_OPTIONAL_HEADER.SizeOfImage为正确的值。程序仍然可以正常打开运行。

实验步骤一:使用WinHex打开某程序,记录下某节头的数据

.text       EA7C       1000    EC00  600

实验步骤二:文件原尺寸是0x1EDC9F,FileAlignment是0x200,新的起址必须是FileAlignment的整数倍,取0x1EE000。

将文件偏移600处的EC00个字节复制粘贴到文件偏移1EE000处。

实验步骤三:将文件偏移600处的共EC00个字节全部填成FF。

,取

实验步骤四:修改节头中的一个数据,如下

.text       EA7C       1000    1EE000  800

实验步骤五:修改IMAGE_OPTIONAL_HEADER为正确的值

结论:再次验证windows loader针对节头的有效性检查;windows loader加载PE文件,不是简单地镜像操作,硬盘文件中未用到部分会被丢弃掉(比如上面填FF的那一大段)。


【实验三】

在WinHex中打开任意一个32位程序,复制数据块,起址为IMAGE_NT_HEADERS头、终址为Min(IMAGE_SECTION_HEADER.PointerToRawData)-1;新的起址为0x10;

修改文件偏移0x3C处四个字节为0x00000010。程序仍然可以正常打开运行。


程序开头原来的样子。



实验步骤一:打开程序,查找到IMAGE_NT_HEADERS在偏移0x108处,Min(IMAGE_SECTION_HEADER_HEADER.PointerToRawData)为0x400。复制数据块,从0x108到0x3FF。



实验步骤二:复制数据块0x108~0x3FF到偏移0x0C处,新的终址为0x303。

实验步骤三:修改偏移0x3C处为0x0000000C。新的程序看起来如下图这个样子。双击程序,程序正常执行。


结论:PE程序开头的DOS Stub大部分数据域无关紧要,除了e_magic和e_lfanew;IMAGE_OPTIONAL_HEADER中的BaseOfCode,BaseOfData也是无关紧要。
32位程序,从IMAGE_NT_HEADERS开始的头部最多可以前移到文件偏移0x0C处,64位程序,从IMAGE_NT_HEADERS64开始的头部最多可以前移到文件偏移0x10处。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值