1.实验目的和要求
熟悉PE文件格式,通过对PE文件头分析,理解PE文件格式,掌握主要数据结构的定位及其功能,如入口点、节表、节、导入表等。研究如何利用工具对各部分的内容进行读取分析显示,理解RVA、VA、FOA之间的关系;初步掌握汇编程序的调试方法。
2.实验步骤
1、PE可执行文件分析
开发一个源程序 HelloWorld .asm,显示hello world。
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
;数据段
.data
szText db 'HelloWorld',0
;代码段
.code
start:
invoke MessageBox,NULL,offset szText,NULL,MB_OK
invoke ExitProcess,NULL
end start
2、调试软件OllyDBG
2.1、利用OD软件调试PE文件。
从OD反汇编的结果分析,invoke MessageBox,NULL,offset szText,NULL,MB_OK分解成哪几个指令?
PUSH 0
PUSH 0 ; MB_OK 的值
PUSH OFFSET 00403000 ; szText字符串地址
PUSH 0 ; NULL的值
CALL <JMP.&user32.MessageBoxA> ; 调用user32模块中的MessageBox函数
问题2.2:怎么理解E8 08000000?
使用E8调用Call指令,E8后面跟着的是偏移地址,0800 0000应该高位先读,所以是0000 0008;Call指令把它吓一跳指令压栈,0040 1010+0000 0008=0040 1018,跳转到地址0040 1018执行。
问题2.3:F7单步步入和F8单步步过 有什么不同?
F8单步步过每按一次这个键执行一条反汇窗口中的一条指令,遇到CALL等子程序不进入其代码,越过函数实现;
F7单步步入功能与F8类似,区别在于F7遇到CALL等子程序是会进入其中,即进入函数实现。
简单来说就是按F7要一条条执行,按F8就是等同看作一条执行执行下面自己编写的所有连贯命令。
2.4:修改EXE文件字节码
将messagebox显示的 HelloWorld 修改成 GoodNight,截图显示结果。
找到HelloWorld.,选中然后Ctrl+E跳转即可修改,然后再运行就可以了。
问题2.5:修改是从文件偏移的什么地方开始的(FOA和VA、RVA分别的多少)?
用winhex打开可以查看到是在0000 0800,可以知道FOA是0000 0800
.data在Virtual Offset区段在内存中的相对虚拟地址RVA是0000 3000(起始地址)
VA=Image Base+RVA=0040 0000+0000 3000=0040 3000
3、调试软件W32DASM
利用W32DASM查看HelloWorld.EXE的输出。
问题3.1:该函数用到哪几个DLL,分别用到哪几个函数?
使用到user32.ddl、kerne123.ddl和MessageBoxA、exitProcess函数
4、FlexHex 或 Winhex
熟悉十六进制编辑软件的使用。
问题4.1:如何初步判断一个文件是PE文件?
1.使用winhex工具查看文件头是否为0X4D5A;
2.若符合则用e_lfanew指针定位pe头,e_lfanew一般位于0X3C;
3.若符合1、2则判断pe头是否为0X4550;
4.以上三点都符合则是有效PE头。
5、利用PEditor查看Hellworld,读出其ImageBase的值,并给出节表(截图)。
问题5.1:画出节表。
Image Base = 0040 0000
节表:
问题5.2:某变量的FOA为410H,试分析其位于哪一节(给出分析过程。)?该变量的RVA为多少(给出计算过程)?
位于0-1000H的.test节
RVA:1000H +(410H-400H)= 1010H
6、如何判断一个文件是否是EXE文件?
用Winhex打开文件,从文件头4D 5A(MZ)开始跳转3C,读取到数据0000 00B0,再次跳转到0000 00B0,若该地址为50 45 即为EXE文件
7、查阅资料,简述病毒获取Kernel32模块基地址的重要性,即描述其目的是什么?
一般初始化PE文件的时候,ntdll.dll, kernel32.dll是随进程以及线程初始化时候加载的。所以即使程序中我们不引入任何输入表结构,这两个DLL在我们程序进程以及线程初始化时也必须加载。获得kernel32.dll的基地址后,就可以获得LoadLibray函数来继续加载其他的动态链接库,然后再通过我们的GetProcAdress函数来获得相应需要的api函数地址,这样也就做到了可移植性的要求。
8、导入表结构分析。
问题8.1:利用PEditor打开firstwindow.exe,分析该PE的导入表。该PE文件描述导入表的数据目录项的偏移是多少?导入表的VA和大小分别是多少?该EXE用到多少个DLL文件。验证与PEditor中查看到的是否一致?
数据目录项的偏移:2048H
VA:00401000H 大小:50H
用到3个dll文件
一致
问题8.2:理解PE文件的双桥结构,特别是从静态到动态桥2发生的变化。下图为导入表描述符的数据结构。仅填写与Winresult.DLL相关的信息(画出静态、动态两个)图)。