搜索API函数地址

实验 3    PE 病毒分析与清除(二)

3.1 实验名称

PE 病毒分析与清除

3.2 实验目的

1)  了解 PE 病毒的基本原理

2)  熟悉 PE 病毒中的部分关键技术

3)  学会清除 PE 病毒

3.3 实验步骤及内容

第一阶段:

 熟悉 Masm32

1)    安装 masm32v11

2)    熟悉 masm32 的基本环境

3)    写一个最简单的 HelloWorld 程序,并编译成功

4)    对得到的可执行文件进行反汇编, 比较其反汇编代码和最初的汇编代码有 哪些异同?

5)    查看并理解 masm32\bin 下各个批处理程序,了解它们的大致功能

第二阶段:

 熟悉病毒重定位的基本思路和方法

  在 HelloWorld.exe 中添加一段代码, 该段代码满足以下几个条件:

该段代码弹出一个对话框(标题: 武大信安病毒重定位,内容: 姓 名+学号后四位)

该段代码同时包括代码和字符串数据。

该段代码可以插入到.text  节的任意指令之间,而不需要修改该段代 码中的任何字节。

第三阶段:

 搜索 API 函数地址

  用 ollydbg  打开 HelloWorld.exe ,获取 kernel32.dll  模块基地址,定位到

kernel32.dll 模块。

  从内存中的 kernel32.dll 模块获取函数 LoadLibraryA 和 GetProcAddress 的函

数地址,并实际检验获得的地址是否正确

第四阶段: PE 病毒感染分析与清除

 编译教材中的感染例子程序-bookexample-old.rar

使用该感染例子对 HelloWorld.exe 进行感染。思考以下问题:

  该病毒在感染文件时具体做了哪些操作?

  该病毒如何返回 HOST?

找出该病毒程序存在的一些问题,并解决这些问题。

编译教材中的感染例子程序-bookexample-new.rar

使用该感染例子对计算器 calc.exe 进行感染。

手工恢复被感染的 calc.exe  (功能恢复)。

课后习题思考:

 对 Win10 下的在 32 位及 64 位程序来说, 如何通过 PEB 获取 kernel32 基地址? 32 位和 64 程序有何差异?

 尝试编写一个程序,可用来搜索指定目录下的所有 exe 文件,用 MessageBox 显示每 一个被搜索到的 exe 文件名。

 编写课本中病毒感染程序的病毒清除程序,其可以用来恢复被感染的任何文件

 课程提供的病毒感染例子程序在 64 位系统中无法正常感染, 请定位其原因, 并给出 解决方案。

3.4 实验关键过程、数据及其分析

搜索 API 函数地址

NT内核系统中FS寄存器指向TEB结构,TEB+0x30处指向PEB结构,PEB+0x0C处指向PEB_LDR_DATA结构。

PEB_LDR_DATA+0x1c处是一个叫InInitialzationOrderModuleList的成员,指向LDR_MODULE双向链表结构,存放一些动态链接库地址:第一个指向ntdl.dll,第二个就是kernel32.dll。

使用Ollydbg打开helloworld.exe。更改数据窗口的显示模式->长型->地址,这样数据窗口数值就能和地址相对应。

搜索API函数地址_第1张图片

找到FS地址,对其30的偏移量,跳转转到 7FFDF030,并在数据窗口中跟随PEB中的数据。

搜索API函数地址_第2张图片

搜索API函数地址_第3张图片

然后再加一个0C的偏移量,再进行数据窗口跟随找到PEB_LDR_DATA结构。

搜索API函数地址_第4张图片

接下来再有一个1C的偏移量,再次进行数据窗口跟随,找到了双向链表的结构。

搜索API函数地址_第5张图片

结构中,第一个值是指向下一个指针,第二个值是指向上一个指针。可以看到双向链表中第一个值是ntdll模块的地址0x7C920000。根据双向链表的结构,跟随第一个指针,找到可链表的下一个节点。

搜索API函数地址_第6张图片

这样可以找到kernel32的基地址0x7C800000。验证一下,第二个指针也确实指向上一个也就是ntdll的地址。再验证一下,选择查看内存,可以看到两个库函数的基地址均正确。

搜索API函数地址_第7张图片

找到基地址后,我们还需要找到函数地址。

首先需要找到kernel32模块的导出表结构。导出表结构如下图所示,AddressOfNames在偏移0x20处。

搜索API函数地址_第8张图片

搜索API函数地址_第9张图片

   通过导出表获取函数地址分为以下三步:1.AddressOfNames字段里存放着函数名的地址,遍历匹配函数名,找到后返回一个该函数名地址的索引index_name;2.再查看AddressOfNameOrdinals字段中index_name处存放的值,设为index_i;3.最后查找AddressOfFunctions字段中index_i处存放的地址,这就是我们要找的函数地址。

搜索API函数地址_第10张图片

首先,找到kernel32模块的基地址并双击进入,找到导出表的地址偏移为0x262C(基地址是0x7C80000)。

搜索API函数地址_第11张图片

跳转到0x7C80262C,再找到偏移为0x20的地方,就是AddressOfNames的地址。

搜索API函数地址_第12张图片

搜索API函数地址_第13张图片

接下来继续跳转到AddressOfNames处,记得要加上整体的偏移0x7C80000。

搜索API函数地址_第14张图片

可以看到函数名所在的RVA地址是0x00004BA5,跳转过去到达ExportNames可以看到所有函数名称。

搜索API函数地址_第15张图片

接下来到将第2步,我们不使用比较查找索引的方式,而是直接使用命令行的查找命令“?LoadLibraryA”以及“?GetProcAddress”查找函数地址。
 

在反汇编窗口进行跳转,可以看到如下图两个函数的具体内容。

搜索API函数地址_第16张图片

搜索API函数地址_第17张图片

之所以要找这两个函数的地址,是因为LoadLibraryA函数可以加载任意的动态链接库,而GetProcAddress可以找到函数的地址,通过这两个函数,我们就可以摘到任意的函数地址。

  

你可能感兴趣的:(软件安全,网络,网络安全,安全,系统安全,安全架构,安全威胁分析,web安全)