PE的常识知识,温习一下,如果能骗到个邀请码就好了。。。
1、修复节的Roffset
要用IDA分析DUMP出来的PE文件,需要先复习一下PE文件中的虚拟地址偏移Voffset和磁盘文件偏移Roffset的转换:
1、根据PE头中节表的信息计算出所有节的开始Voffset和结束Voffset,判断目标Voffset是属于哪个节的
2、用目标Voffset减去那个节的Voffset,得到Voffset_d
2、Voffset_d加上那个节的Roffset,得到目标Roffset
可见PE头中节表的信息起到了由Voffset计算Roffset的桥梁的作用。
IDA在分析PE文件的时候,会从PE头得到入口点的Voffset,并通过上面的方法计算出磁盘文件中的Roffset,从这个Roffset处开始解析指令。
从内存DUMP出来的文件,是直接从内存中拷贝一份然后存为磁盘文件。节的磁盘文件偏移Roffset实际上等于虚拟地址偏移Voffset,但是原来PE头节表中的信息可能是Voffset!=Roffset,这样IDA在分析的时候会计算出错误的Roffset造成反汇编失败。
解决办法就是修改PE头的节表,将代码节的Roffset的值改为现在的Voffset,IDA就可以从正确的入口处的指令开始解析。节的大小则不用更改。
PS:还有其他解决办法,比如移动磁盘文件中的节使其符合上面的计算过程,但是那样就太麻烦了。
修正代码节的Roffset,IDA就可以正确分析了。实际上IDA按照上面的计算过程分别取得磁盘文件中其他节的数据,因此其他节的文件偏移也应该一并修改。
2、修复映像加载地址
PE头中的映像加载地址是编译器给出的建议加载地址。对于DLL和SYS来说,实际加载地址常常不等于建议加载地址。这个时候就需要用重定位表中的信息进行重定位。
在PE文件中如果某条指令中直接给出了绝对内存地址,那么这样的指令就是需要修正的。
DLL或SYS在内存中时,其访问全局变量的指令是已经经过重定位的。但DUMP下来后扔IDA中分析,这些地址需要“重定向”回去,其实可以间接修改PE头中的建议加载地址为DUMP时的实际加载位置,这样就“重定向回去了”。
PS:“模块中的指令所访问的静态地址必定是在模块中的”,所以当IDA发现某个指令寻址的地址跑模块外去了,就会以红色来标识这是一个有问题的指令,它是怎么样判断指令寻址的地址跑到模块外面去了呢?IDA先取得PE头中建议加载地址和PE在内存中的映像大小,通过这两个值得到指令可能访问到的地址上限和下限,从而判断指令寻址的地址跑到模块外面去了。
修复映像加载地址对IDA分析“对函数、或代码标号的引用”的意义。汇编中的伪指令“offset 函数名/标号”、C语言中的“&函数”名也会被编译成绝对地址,这些经编译后的汇编指令也是需要重定位的对象。
重定位的对象大体有:全局变量的地址作为操作数的指令,函数地址、标号地址作为操作数的指令。要IDA分析出正确的全局变量访问和函数地址引用,就需要修复DUMP下来的PE头中的映像加载地址。
3、关于PE文件中的INIT节
还有一个问题,就是关于驱动的DriverEntry,因为常常会被放到INIT节中,当入口函数返回之后,这个节就会被抛弃,因此DUMP出来的文件常常看不到DriverEntry函数。
另外还有就是导入表也会被放在INIT节中,但导入函数地址表(程序运行期间需要用到)、导出表(别的模块访问导出函数需要用到)都一定会存在的,不可能被抛弃。
凡是放入INIT节中的数据都是不可直接DUMP的,需要采取特殊方法来DUMP,就是在INIT节被丢弃之前DUMP。
【关于导入表的问题】
关于导入表的问题:http://bbs.pediy.com/showthread.php?t=95230
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)