|
| |
精品推荐 |
 |
|
| |
|
|
|
|
恶意代码的亲密接触之文件搜索和API导址
|
日期:2007年5月3日 作者: 查看:[大字体
中字体 小字体]
|
在前一篇文章中介绍了病毒的相关基础知识后,从本文开始我们就要深入病毒内部,开始看一些具体的病毒编码片断,在本文中我们会看到API函数搜索以及文件搜索的技术,为后面更加深入的探讨打下良好的基础,如果你已经准备好了,就让作者带你进入这无所不用其极的病毒技术世界吧。
获取Kernel32.DLL 基址
获取Kernel32.DLL基址的方法很多,最常见的一种是搜索法,如果已知Kernel32.DLL加载的大致地址,那么可由该地址向高地址或低地址进行搜索可以找到其基址。另外一种方法是搜索NT PEB 结构中的模块列表获取Kernel32.DLL的准确加载基址。下面看一下具体的实现代码。
方法1:暴力搜索获取Kernel32.DLL 的基址
最初的病毒是指定一个大致的加载地址,比如根据实验在9X 下其加载地址是0xBFF70000;在Windows 2000下加载基址是0x77E80000;在XP 和2003 下其加载基址是0x77E60000,因此在NT系统下就可以从0x77e00000开始向高地址搜索,在9X 下可以从0xBFF00000 开始向高地址搜索,如果搜索到Kernel32.DLL的加载地址,其头部一定是“MZ”标志,由模块起始偏移0x3C的双字确定的PE头部标志必然是“PE”标志,因此可根据这两个标志判断是否找到了模块加载地址,也许有人认为该方法不可靠,因为如果恰好有某段数据符合这两个特征,那么找到的基址可能就是错误的,但经实验证明,该判断方法非常可靠,基本不会出现错误。有一点需要注意的是,在所有版本的Windows系统下Kernel32.DLL的加载基址都是按照0x10000对齐的,根据这一特点可以不必逐字节搜索,按照64K 对齐的边界地址搜索即可。
从大致的一个地址开始搜索Kernel32.DLL基址可能会出现读写到未映射内存区域的情况,因此需要和SEH 配合使用。如果有在各个版本下准确获取Kernel32.DLL中某地址的通用方法,那么就可以更可靠地从该地址开始向低地址搜索,显然会更加通用。事实上,这种方法是存在的。在系统加载PE文件跳转到PE入口点第一条指令的时候,堆栈顶保存的就是Kernel32.DLL 中的某个地址,Elkern中采用的就是这种方法:
_start: pushfd ;If some flags,especial DF,changed,some APIs can crash down!!! pushad _start_@1 equ $ ;...... mov ebx,[esp+9*4] ;前面已经由pushfd 和pushad 压入了9 个双字 and ebx,0ffe00000h ;该地址为Kernel32.dll 模块下方的某个地址 ;先减去0x100000 确保该地址处于Kernel32.dll 的下方 ;向高地址搜索如果将来Windows 的发行版本中Kernel32.dll ;大小和代码结构发生变化,该方法可能无效 ebx 中现在已经是Kernel32.DLL 基址之前某个地址了,后续代码可以向高地址搜索其基址。该方法有一个缺点,就是必须明确知道程序入口的堆栈指针值,或间接可计算出该值,对于那些在程序入口获取控制权的病毒代码而言,是可以的,但对于采用EPO 技术的病毒而言,该方法则不适用。事实上还有另外一种更加通用的方法,我们知道在Win32 程序执行过程中fs 段寄存器的基址总是指向进程的TEB,TEB 的第一个成员指向SEH 链表,该链表每个节点都是一个EXCEPTION_REGISTRATION 结构,该结构定义如下:
struct EXCEPTION_REGISTRATION{ struct EXCEPTION_REGISTRATION *prev; void* handler; }; 在Windows 下SEH 链表最后一个成员的handler 指向Kernel32.DLL中函数UnhandledExceptionFilter的起始地址,利用这一特性我们可以写出更通用的代码:
xor esi,esi lods dword [fs:esi];取得SEH 链表的头指针 @@: inc eax ;是否是最后一个SEH 节点,检查prev 是 否为0xFFFFFFFF je @F dec eax xchg esi,eax LODSD ;下一个SEH 节点 jmp near @B @@: LODSD ;取得Kernel32.dll中UnhandledExceptionFilter的地址 在有的病毒直接以0x7FFDE000 作为TEB 的指针值,其原因在于在Windows 2003 SP1、Windows XP SP2以前的NT类系统上,该值是固定的,这样的确可以节省一两个字节。但是在Windows 2003 SP1、Windows XP SP2中,情况已经发生了变化,出于安全性的考虑,Windows系统开 始动态映射TEB 了,也就是说,指向TEB 的指针值不再固定,因此这种硬编码的方法也就走到了尽头。此时可以按照前面的方法向低地址搜索判断直到找到Kernel32.dll的基址为止。Elkern中判断是否找到了Kernel32.dll基址的相关代码如下:
上一篇:亲密接触恶意代码之文件感染和内存驻留
下一篇:病毒编程技术之恶意代码的亲密接触
|
| 恶意代码的亲密接触之文件搜索和API导址 相关文章: |
|
|
|
| 恶意代码的亲密接触之文件搜索和API导址 相关软件: |
|
|
|
|