一 使用Win32汇编的PE信息查看小工具查看和研究PE文件
PE信息查看工具有多种。下面先使用在《Windows PE权威指南》中所附带的用Win32汇编编写的PE信息查看小工具来查看PE信息。此处可下载《Windows PE权威指南》所附带源码:
http://pan.baidu.com/s/1o6Odgl8
该程序用Win32汇编写成,可执行文件仅有9K,当作一个PE信息查看工具挺不错的;
以下用上面说的peinfonor.exe打开PE文件;
1 查看一个Win32汇编写的窗口程序,该程序有窗口和菜单;
PE文件结构中区段表也称节表,其作用相当于一本书中的目录;此程序有四个节;.text为代码段;.rdata为只读数据区段;.data为可读写的数据段;.rsrc为资源区段。
导入了Windows自身的动态链接库user32和kernel32;导入表在.rdata节;
2 打开一个纯SDK所写的窗口程序,该程序实现了简单键盘钩子功能,有菜单;
节的数量为6;.idata为导入数据区段;.reloc区段包含重定位信息;
导入表在.idata节;导入了Windows的三个核心动态库:user32, kernel32,gdi32;
PE文件基址重定位(Base Relocation),程序编译时每个模块有一个优先加载地址ImageBase,这个值是连接器给出的,因此连接器生成的指令中的地址是在假设模块被加载到ImageBase前提之下生成的,那么一旦程序没有将模块加载到ImageBase时,那么程序中 的指令地址就需要重新定位,例如:假设一个可执行文件,基址是0x400000,在这个image偏移0x1234处是一个指针,指向一个字符串,字符串始于实际地址0x404002处,所以指针应该是0x404002,加载文件时,由于种种原因,加载器决定把他加载到0x600000处,连接器假设的地址和实际的地址之差成为delta,上例delta为0x200000,整个位置提高了0x200000,那么字符串位置应该为0x604002,原来指向字符串的指针就错误了,所以要把delta加到指针值中,为了让加载器有这样的能力做调整,可执行文件内含许多个"基址重定位项",给那些存放指针的位置使用,加载器必须把delta加载到各个基址上。本例中应该把0x200000加给原来的指针值,0x404002,并将0x604002写回原处。
3 打开一个VC++的简单单文档程序;编译为debug版本;
节的数量为7;.textbss - 这节是和微软Incremental Linking(增量链接)特性相关的;
导入了两个MFC的DLL;
导入了Windows自带的DLL;
很多的重定位项。
4 打开一个.Net所写的简单程序,一个窗口上面有几个控件;编译为Debug;
节的数量-3;
导入一个mscoree.dll,导入表所处节为.text;没有其他的导入库;这个mscoree.dll应该是和.net运行时相关的;
一旦没有MSCOREE.DLL,.net程序,就算是最简单的Hello World也无法运行;
上述3中打开的VC所写的程序中导入的Windows自身的三个核心动态库所实现的功能,应该是由.Net运行时实现的。
由上述可见,实现大体相同的功能,Win32汇编所写程序最小,SDK写的变大,VC++写的更大;VC++所写除了导入Windows自身的动态库,还导入MFC的动态库;.Net所写的.exe文件虽不太大,但是必须要有.Net运行时的支持;很多的功能由.Net运行时代替实现。