静态恶意代码逃逸(第七课)

倾旋
倾旋
技术分享|2020-10-23|最后更新: 2023-6-22|
type
status
date
slug
summary
tags
category
icon
password
URL

0x01 导入地址表(IAT)

Import Address Table 由于导入函数就是被程序调用但其执行代码又不在程序中的函数,这些函数的代码位于一个或者多个DLL 中,当PE 文件被装入内存的时候,Windows 装载器才将DLL 装入,并将调用导入函数的指令和函数实际所处的地址联系起来(动态连接),这操作就需要导入表完成.其中导入地址表就指示函数实际地址。 - 来源百度百科
如下图所示:
notion image
在PE结构中,存在一个导入表,导入表中声明了这个PE文件会载入哪些模块,同时每个模块的结构中又会指向模块中的一些函数名称。这样的组织关系是为了告诉操作系统这些函数的地址在哪里,方便修正调用地址。
站在反病毒的角度提出假想:既然所有的PE文件都有导入表,并且声明了一些模块,并且还能通过模块找到导入函数的名称,那么是否能够作为一个文件的风险值的评估方向?
方法论:
如果一个文件的文件大小在300KB以内,并且导入函数又有Virtual AllocCreateThread,且VirtualAlloc的最后一个参数是0x40,那么此文件是高危文件。
0x40被定义在winnt.h中:
看一下第一课代码编译出来的PE导出表:
notion image
根据这个猜想,我们开始尝试在PE文件中抹去导入函数名称。

0x02 GetProcAddress获取函数地址

GetProcAddress这个API在Kernel32.dll中被导出,主要功能是从一个加载的模块中获取函数的地址。
函数声明如下:
FARPROC被定义在了minwindef.h中,声明如下:
跟进它的声明能够发现是一个函数指针,也就是说GetProcAddress返回的是我们要找的函数地址。

0x03 自己动手获取函数地址

我们拿第一课的代码来尝试修改。
分析第一课的代码,主要流程:
这几个函数是比较明显的,并且都在kernel32.dll中导出,我们尝试自己定义他们的函数指针,然后利用GetProcAddress获取函数地址,调用自己的函数名称。
新建一个C/C++项目,定义如下:
然后在main函数中,定义四个函数指针来存放这些函数的地址。
完整代码如下:
编译后能够正常执行,并且我们查看一下导入表,我们自己定义的函数已经不在导入表中了:
notion image
Virus Total一下看看:
notion image
目前这个程序仅仅只是在一个函数中进行调用,并且还有字符串硬编码的问题,下一课着重分享如何解决字符串硬编码的问题。
©2021-2024 倾旋. All rights reserved.