首页
社区
课程
招聘
[原创]拿Win7系统下的notepad.exe文件用19个实例来猜测Win7PE加载器的一些行为
发表于: 2013-6-13 11:36 6523

[原创]拿Win7系统下的notepad.exe文件用19个实例来猜测Win7PE加载器的一些行为

2013-6-13 11:36
6523

这只是我之前的实例操作,总有哪天回过期的,我的结论如果有错误的地方,希望大牛拍砖、指正。
首先记下notepad.exe文件的四个值:

  SizeOfCode(DWORD)包含代码节总长度(0x0000A800)
  SizeOfInitializedData(DWORD)已初始化的数据总长度(0x00022400)
  SizeOfUninitializedData(DWORD)未初始化的数据总长度(0)
  AddressOfEntryPoint(DWORD)程序入口RVA(0x00003689 )
  BaseOfCode(DWORD)代码的第一个字节的RVA(0x00001000)
  BaseOfData(DWORD)数据的第一个字节的RVA(0x0000C000)
  SectionAlignment(DWORD)节的内存对齐粒度(0x00001000)
  FileAlignment(DWORD)节的文件对齐粒度(0x00000200 )
  SizeOfImage(DWORD)PE内存中的映像尺寸(0x00030000)

  
实例操作1 :修改 SizeOfCode(DWORD)包含代码节总长度 值为 (0x0000A601,因为0x0000A601与0x0000A800按文件对齐值是一样的)

   结果:notepad.exe 正常启动,MDebug调试器启动调试没有发现问题
   猜想:SizeOfCode 值 也许没有用于 PE文件格式的判定、也许PE文件格式的判定过程中这个值不需要按文件对齐值是一样的

实例操作2 :修改 SizeOfCode(DWORD)包含代码节总长度 值为 (0x0000A5FF,因为0x0000A5FF与0x0000A800按文件对齐值是不一样的)

   结果:notepad.exe 正常启动,MDebug调试器启动调试没有发现问题
   猜想:SizeOfCode 值 应该没有用于 PE文件格式的判定

实例操作3 :修改 SizeOfCode(DWORD)包含代码节总长度 值为 (0)

   结果:notepad.exe 正常启动,MDebug调试器启动调试没有发现问题
   猜想:SizeOfCode 值 肯定没有用于 PE文件格式的判定、也不影响PE加载器对PE文件的加载

实例操作4 :修改 SizeOfCode(DWORD)包含代码节总长度 值为 (0x0000A801,因为0x0000A801与0x0000A800按文件对齐值是不一样的)

   结果:notepad.exe 正常启动,MDebug调试器启动调试没有发现问题

**1 - 4实例操作结论:SizeOfCode 值 肯定没有用于 PE文件格式的判定、也不影响PE加载器对PE文件的加载,它什么值应该都可以的,应该也不会影响调试器调试程序的,这个字段应该是被废弃了

实例操作5 :修改 SizeOfInitializedData(DWORD)已初始化的数据总长度 值为 (0x00022201,因为0x00022201与0x00022400按文件对齐值是一样的)

   结果:notepad.exe 正常启动,MDebug调试器启动调试没有发现问题
   猜想:SizeOfInitializedData 值 也许没有用于 PE文件格式的判定、也许PE文件格式的判定过程中这个值不需要按文件对齐值是一样的

实例操作6 :修改 SizeOfInitializedData(DWORD)已初始化的数据总长度 值为 (0x000221FF,因为0x000221FF与0x00022400按文件对齐值是不一样的)

   结果:notepad.exe 正常启动,MDebug调试器启动调试没有发现问题
   猜想:SizeOfInitializedData 值 也许没有用于 PE文件格式的判定、也许PE文件格式的判定过程中这个值不需要按文件对齐值是一样的

实例操作7 :修改 SizeOfInitializedData 值为 (0)

   结果:notepad.exe 正常启动,MDebug调试器启动调试没有发现问题
   猜想:SizeOfInitializedData 值 肯定没有用于 PE文件格式的判定、也不影响PE加载器对PE文件的加载

实例操作8 :修改 SizeOfInitializedData 值为 (0x00022401,因为0x00022401与0x0000A800按文件对齐值是不一样的)

   结果:notepad.exe 正常启动,MDebug调试器启动调试没有发现问题

**5 - 8实例操作结论:SizeOfInitializedData 值 肯定没有用于 PE文件格式的判定、也不影响PE加载器对PE文件的加载,它什么值应该都可以的,应该也不会影响调试器调试程序的,这个字段应该是被废弃了

实例操作9 :修改 SizeOfUninitializedData(DWORD)未初始化的数据总长度 值为 (0x00030001 比PE内存中的映像尺寸还大)

   结果:notepad.exe 正常启动,MDebug调试器启动调试没有发现问题
   猜想:SizeOfUninitializedData 值 肯定没有用于 PE文件格式的判定、也不影响PE加载器对PE文件的加载,这个字段应该是被废弃了

**9实例操作结论:SizeOfUninitializedData 这个字段应该是被废弃了。

实例操作10 :修改 AddressOfEntryPoint(DWORD)程序入口RVA 值为 (0)

   结果:notepad.exe 启动错误,“xxx 指令引用的 xxx 内存。该内存不能为写”。MDebug调试器启动调试直接停在ntdll.dll领空调用RtlImageNtHeaderEx 后的反汇编代码处,加载的模块列表只有notepad.exe和ntdll.dll
   猜想:AddressOfEntryPoint 值不影响PE文件格式的判断,它应该不只用于它的本意,PE加载器应该有判断这个RVA的是否存在,因为他是EXE文件。

实例操作11 :修改 AddressOfEntryPoint(DWORD)程序入口RVA 值为 (0x0000C000 这个是数据节的RVA)

   结果:notepad.exe 启动错误,“xxx 指令引用的 xxx 内存。该内存不能为写”。MDebug调试器启动调试直接打印加载模块一闪就关闭了。用OD打开就可以显示入口反汇编指令了。
   猜想:程序应该在 AddressOfEntryPoint 处执行到指令错误了。

**10 - 11 实例操作结论:AddressOfEntryPoint(DWORD)程序入口RVA,对于EXE必须存在、不管值是指向什么属性的节。(这个猜测有待进一步验证)   

实例操作12 :修改 BaseOfCode(DWORD)代码的第一个字节的RVA 值为 (0或1)

   结果:notepad.exe 正常启动,MDebug调试器启动调试没有发现问题
   猜想:BaseOfCode 值 肯定没有用于 PE文件格式的判定、也不影响PE加载器对PE文件的加载,这个字段应该是被废弃了

实例操作13 :修改 BaseOfData(DWORD)数据的第一个字节的RVA 值为 (0或1)

   结果:notepad.exe 正常启动,MDebug调试器启动调试没有发现问题
   猜想:BaseOfData 值 肯定没有用于 PE文件格式的判定、也不影响PE加载器对PE文件的加载,这个字段应该是被废弃了

**12 - 13 实例操作结论:BaseOfCode 和 BaseOfData 应该是都被废弃了

查看.text 节头数据
   Misc.VirtualSize     值:0x0000A68C 原始节数据长度
   VirtualAddress       值:0x00001000 节的RVA(DWORD)
   SizeOfRawData        值:0x0000A800 节在文件中对齐后大小
   PointerToRawData     值:0x00000400 节在文件中的偏移地址(DWORD)

实例操作14 :修改.text 节头数据 Misc.VirtualSize 为

   结果:notepad.exe 正常启动。
   猜想:因为0x0000A68C和0x0000A800按内存对齐的值是一样的,所以只要有一个可以让PE加载器算出该节的正确内存映像尺寸即可。

实例操作15 :恢复Misc.VirtualSize数据,修改.text 节头数据 SizeOfRawData 为 0
   结果:错误对话框提示 notepad.exe 程序无法正常启动,MDebug调试器没有办法启动调试
   猜想:PE加载器应该是没有怀疑PE文件格式有问题,但是在把.text 节数据读进映像时发现没有数据

实例操作16 :修改.text 节头数据 SizeOfRawData 为 0x00003689 - 0x00001000 = 0x00002689

   结果:还是错误对话框提示 notepad.exe 程序无法正常启动,MDebug调试器没有办法启动调试
   猜想:PE加载器应该是没有怀疑PE文件格式有问题,但是在把.text 节数据读进映像时发现什么不对了呢?

实例操作17 :修改.text 节头数据 SizeOfRawData 为 0x00003000(比0x00002689大一点看看,但是按内存对齐值是一样的)

   结果:还是错误对话框提示 notepad.exe 程序无法正常启动,MDebug调试器没有办法启动调试
   猜想:PE加载器应该是没有怀疑PE文件格式有问题,但是在把.text 节数据读进映像时可能是发现 SizeOfRawData 值并按文件对齐后的值加上 PointerToRawData 的和值不等于后面一个节.data的 PointerToRawData ,所以节头表需要有最后一项全部为0

实例操作18 :修改.text 节头数据 SizeOfRawData 为 0x0000A601(0x0000A601 与 0x0000A800 按文件对齐的值是一样的)
   结果:notepad.exe 正常启动。菜单功能我没有发现问题。MDebug调试器调试时查看内存.text节的偏移0x0000A601以后的0x200数据证明是从文件中读取的。
   说明:实例操作4 的猜想是对的。

**14 - 18 实例操作可以确定结果:PE加载器在把一个节数据读进映像时,需要检查 SizeOfRawData 按文件对齐后加上 PointerToRawData 必须等于后面一个节的 PointerToRawData ,PE加载器是要重新计算 SizeOfRawData 按文件对齐后的长度,然后把文件节数据读进映像内存。而对于 Misc.VirtualSize 的值是多少已经不重要了,应该只要不大于 SizeOfRawData 值即可,是 0 都无所谓了。

再往下查看.data 节头数据
    Misc.VirtualSize     值:0x00002164 原始节数据长度(DWORD)此字段已经不准确
    VirtualAddress       值:0x0000C000 节的RVA(DWORD)
    SizeOfRawData        值:0x00001000 节在文件中对齐后大小(DWORD)
    PointerToRawData     值:0x0000AC00 节在文件中的偏移地址(DWORD)

发现 Misc.VirtualSize 的值尽然大于 SizeOfRawData 的值 ?
计算一下 0x00002164 按内存对齐的大小是 0x00003000 。加上 VirtualAddress 正好等于下一个节.rsrc 节的 VirtualAddress (0x0000F000) 。关注 SizeOfRawData 按内存对齐的大小是 0x00001000 而不是 0x00003000 ,好就来看看实例操作6 。

实例操作19 :修改.data 节的 Misc.VirtualSize 为 0x00001FFF (因为 0x00001FFF 的内存对齐值只有 0x00002000)

    结果:notepad.exe 就没有办法启动,错误提示:notepad.exe不是有效的 Win32 应用程序
    说明:PE加载器应该在判断一个PE格式文件的时候一定有检查:在 Misc.VirtualSize 与 SizeOfRawData 之间取大值,然后按内存对齐的值加上 VirtualAddress 必须等于后面节的 VirtualAddress ,否则判定不是有效的 Win32 应用程序。如果到最后一个节会怎么样?不用猜测 肯定是: 最后一个节的 VirtualAddress + (Misc.VirtualSize 与 SizeOfRawData 之间取大并按内存对齐值) == SizeOfImage(DWORD)PE内存中的映像尺寸,如果这个条件不成立,肯定判定不是有效的 Win32 应用程序。

**总结14 - 19实例操作得出最后结论只有3个:

    1.PE加载器判定为有效的 Win32 应用程序一定至少检查:每一个节的 VirtualAddress + (Misc.VirtualSize 与 SizeOfRawData 之间取大并按内存对齐值) == 后面节的 VirtualAddress ,对于最后一个节:最后一个节的 VirtualAddress + (Misc.VirtualSize 与 SizeOfRawData 之间取大并按内存对齐值) == SizeOfImage(DWORD)PE内存中的映像尺寸

    2.PE加载器从文件节读取数据到映像节的数据长度是:SizeOfRawData 按文件对齐后的长度

    3.各个节的 Misc.VirtualSize 值不必是按内存对齐的值 , 各个节的 SizeOfRawData 值也不必是按文件对齐的值,只要他们的组合符合如下两个公式即可:
     Misc.VirtualSize 与 SizeOfRawData 取大后并按内存对齐的值 == 该节在内存中的实际映像尺寸
     SizeOfRawData 按文件对齐的值 == 该节数据在PE文件中占用的实际字节数


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 5
支持
分享
最新回复 (2)
雪    币: 357
活跃值: (3378)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
2
你这属于瞎fuzz,直接逆向不就清楚,整个完整的过程,要不然用od,ida干嘛
2013-6-13 13:16
0
雪    币: 267
活跃值: (438)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
3
干活老是挖地道,我觉得太累。再说:PE加载器又不是一成不变的。
2013-6-13 13:26
0
游客
登录 | 注册 方可回帖
返回
//