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

分析:

我们可以把这段汇编语言转换为C语言来更进一步分析

首先导入两个库,user32.dll和kernel32.dll

数据段就相当于给char *szText=”HelloWorld”

那么整体变为C

#include<stdio.h>

#include<Windows.h>

int main()

{

char *szText=”HelloWorld”;

MessageBox(NULL,szText,0,MB_OK);

EixtProcess(0);

retrun 0;

}

在逆向中,我们常常会把低级语言转换为我们熟悉的高级语言,进行实现,可以看到以上程序的还原,是基于已有的汇编语言,但是通常在逆向中,我们是利用反汇编工具进行生成的汇编语言,往往那种难度的汇编语言分析才是逆向

2、调试软件OllyDBG

2.1、利用OD软件调试PE文件

将程序导入到OD中我们会看见以下的图

从OD反汇编的结果分析,invoke MessageBox,NULL,offset szText,NULL,MB_OK分解成哪几个指令?

我们可以看到invoke MessageBox,NULL,offset szText,NULL,MB_OK被解析成了如下图红色框勾画出来的5跳指令

其中的原理是,当我们调用一个函数,首先我们会将函数的参数进行压栈,而压栈

通常操作系统选用的是从右往左依次压栈,把参数压入栈后用Call指令调用此函数

当然为什么我们调用MessageBox函数多了个A,这是因为我们采用的是Acsii编码的方式,操作系统还有个宽字符Unicode,但其实用Unicode编码编码方式的API的时候,其底层还是调用的Acsii的方式

问题2.2:怎么理解E8 08000000?

E8对应call的操作码,08000000是要跳转地址的偏移

当使用call指令后,我们可以看到此地址的下一条指令的地址00401010

00401010加上08000000就是00401018,我们可以看到00401018地址的指令是jmp,这里jim就会跳转到MessageBox函数的地址去执行MessageBoxA的地址

问题2.3:F7单步步入和F8单步步过 有什么不同?

F7的步入,那就是进入函数

F8的步过,那就是不进入此函数,直接完这条函数,至于里面内容是什么就直接执行完成

2.4:修改EXE文件字节码

   将messagebox显示的 HelloWorld 修改成 GoodNight,截图显示结果。

最简单的方法就是用winHex打开对那段字符修改后保存,我们先看data段存在文件偏移的地址在哪里

替换掉后进行保存,再次点击运行就可以了

当然还有别的方法,直接在OD里修改指令即可,或者写点hook函数

问题2.5:修改是从文件偏移的什么地方开始的(FOA和VA、RVA分别的多少)?

修改从文件最开始的地方,在winhex里选择从开始地方,再输入Raw Offset的大小就行

这个就是在文件中偏移

FOV为文件的偏移地址800H

RVA为3000H

VA=RVA+基址,也就是在内存中实际运行的地址

3、调试软件W32DASM

利用W32DASM查看HelloWorld.EXE的输入。

问题3.1:该函数用到哪几个DLL,分别用到哪几个函数?

 

可以看到用了user32.dll以及kernerl32.dll分别用到了

User32.dll中的messageBox函数,kernel32.dll的ExitProcess函数

4、FlexHex 或 Winhex

熟悉十六进制编辑软件的使用。

问题4.1:如何初步判断一个文件是PE文件?

如上图,首先先看文件头是不是MZ,在从MZ开始偏移3C的地方看看是多少,图中是B0,那么PE头就是偏移了B0,再从开始位置偏移B0,发现是PE,所以判断出来后才知道这是个PE文件结构

5、利用PEditor查看Hellworld,读出其ImageBase的值,并给出节表(截图)。

问题5.1:画出节表。

问题5.2:某变量的FOA为410H,试分析其位于哪一节(给出分析过程。)?该变量的RVA为多少(给出计算过程)?

首先410H大于400H,其次,又小于600H所以在.text节

RVA为1010H,计算过程为410H-400H=10H,再用1000H+10H=1010H

6、如何判断一个文件是否是EXE文件?

在IMAGE_FILE_HEADER结构中,去看看Characteristics的值,这个表示文件的属性,通常exe文件这个字段的值一般是 0100h,DLL文件这个字段的值一般是 210Eh。

我们看到helloworld.exe的这个字段

0x010F的十六进制表示对应的二进制是0000 0001 0000 1111,可以看到0x0002 (0000 0010)说明,文件是一个可执行文件(Executable Image)

当然我怕自己眼拙所以还用python输出了一下

7、查阅资料,简述病毒获取Kernel32模块基地址的重要性,即描述其目的是什么?

Kernel32.dll 是Windows操作系统中的一个关键动态链接库,提供了大量基础系统服务和API函数(如内存管理、文件操作、进程控制等)。恶意软件通过获取 Kernel32.dll 的基地址,可以动态调用这些API,执行如创建进程、内存分配、文件操作等功能,而无需直接硬编码函数地址。

许多恶意软件会在运行时解析 Kernel32.dll 中的函数地址,而不是在代码中静态引用它们。通过动态解析,可以避免静态分析工具直接发现恶意行为。例如,恶意软件可能使用 GetProcAddress 动态获取某些函数地址,如 CreateProcess、VirtualAlloc 等,来执行恶意操作

恶意软件常通过 Kernel32.dll 提供的函数(如 VirtualAlloc 和 WriteProcessMemory)实现代码注入到其他进程中。获取 Kernel32.dll 基地址后,病毒可以精确地定位所需的API地址,从而在目标进程中执行恶意代码。

通过调用系统API,恶意软件能够创建持久性机制,比如通过修改注册表、启动项或设置钩子等,来确保其在系统重启后依然能够存活。

8、导入表结构分析。

问题8.1:利用PEditor打开firstwindow.exe,分析该PE的导入表。该PE文件描述导入表的数据目录项的偏移是多少?导入表的VA和大小分别是多少?该EXE用到多少个DLL文件。验证与PEditor中查看到的是否一致?

可以用winhex打开计算偏移去寻找,可以看到没有导出表所以是00000,导入表的地址如下图00002084(小端序),我们还有看到后面写了大小50

用PEditor验证一下

问题8.2:理解PE文件的双桥结构,特别是从静态到动态桥2发生的变化。下图为导入表描述符的数据结构。仅填写与Winresult.DLL相关的信息(画出静态、动态两个图)。

根据以上的信息

我们先跳到导入表的地址

第一个存储的是user.32.dll的OriginalFirstThunk后面紧跟着如下图结构体所示

等user32.dll描述完,后面紧跟着的是kernel32.dll的结构信息最后才是winresult.dll的信息

根据winResult.dll所指向的地址在内存中和文件中我们分别打开

发现了是一样的

以226A为例子,同样分别打开

都是指向了这个函数的编号,以及后面的函数名

我们再去FirstThunk的地址看看204C,同样还是分别打开

这里在文件中(静态)和内存(动态中的值发生了改变)

我们跳到改变的地址去

发现这里执行的就是GetWindowLong的函数以及还有别的函数

如图用红色框勾勒了出来

可能你会觉得很奇怪,为什么第一个是GetWindowLong,我们并没有看见如以下这个图的函数

很简单,这肯定是写程序的人自己编写的dll,在这个dll中又用掉用了别的dll,所以还会看到user32.dll,如下面三幅图,和我猜想的没错

以下是整个过程

3. 实验小结

通过本实验,我们深入了解了 PE 文件的结构,特别是如何分析和操作 PE 文件的头部信息、导入表以及数据段。通过使用调试工具(如 OllyDBG 和 W32DASM)和十六进制编辑工具(如 WinHex),我们学会了如何对 PE 文件进行详细的分析,并修改文件中的内容。此外,通过分析 Kernel32.dll 和 user32.dll,我们了解了恶意软件如何利用动态链接库实现自定义的操作,避免被静态分析工具检测。

Categories:

Tags:

No responses yet

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注