所用工具:windbg、ollydbg
恶意代码行为:载入需要的DLL及获取该DLL中相关函数地址
为什么要找到Kernel32.DLL在哪儿?
其中2个重要的函数: LoadLibraryA,GetProcAddress
附上一张重要的图,待会会围绕这张图来分析。
getkernel.exe源码,这是一个获取kernel32.dll基址的程序
void __noreturn sub_401010()
{
unsigned int v0; // eax
unsigned int retaddr; // [esp+0h] [ebp+0h]
v0 = retaddr & 0xFFFF0000;
while ( *(_WORD *)v0 != 23117 )
{
v0 -= 0x10000;
if ( v0 < 0x70000000 )
goto LABEL_6;
}
if ( *(_WORD *)(*(_DWORD *)(v0 + 60) + v0) == 17744 )
{
wsprintfA(Text, "%X", v0);
MessageBoxA(0, Text, Caption, 0);
}
LABEL_6:
ExitProcess(0);
}
运行效果
1.windbg调试
首先使用windbg调试,打开getkernel.exe
在命令输入框中输入命令dt_teb进入teb模块,通过图片可以知道在teb中偏移0x30处是PEB
TEB(Thread Environment Block,线程环境块):系统在此TEB中保存频繁使用的线程相关的数据。可通过CPU的FS寄存器来访问该段,一般存储在[FS:0]
PEB(Process Environment Block,进程环境块)存放进程信息,每个进程都有自己的PEB信息。位于用户地址空间。可在TEB结构地址偏移0x30处获得PEB的地址位置。
输入命令dt_peb进入peb块,
在peb中偏移0x0c处是ldr
输入命令dt_PEB_LDR_DATA
然后输入命令!peb查看LDR地址,注意此次感叹号是英文的感叹号
输入命令dt _PEB_LDR_DATA 770389c0查看三个list地址,红色部分地址是LDR地址
然后输入命令dt _LDR_DATA_TABLE_ENTRY 0x5b54a0-8,从偏移0x14处取出地址0X5b54a0,进入该地址也就是LDR_MODULE里,减8是因为让程序进入栈顶处,这里面就是getkernel.exe程序自己的内容,可以对应图片中的相关信息。
例如偏移0x18处存储的是基址BaseAddress,值为00400000,偏移0x1c处存储的是该程序的入口地址为00401005,然后0x20处是大小,0x24处是该文件的全名,包括文件存放的路径。
上图中可以看到偏移0x08处是指向它的前向指针也就是LDR_ MODULE (ntlI.dI),所以输入命令dt _LDR_DATA_TABLE_ENTRY 0x5b5388-8进入里面,减8同样是使其进入栈顶。这里面是ntdll.dll的相关信息。
最后输入命令dt _LDR_DATA_TABLE_ENTRY 0x5b5898-8进入第三个数组LDR_ MODULE (kernel32.dll)。可以看到偏移0x18处就是kernel32.dll的基址,为759e0000,与该程序运行后的效果也一致。
2.ollydbg调试
使用OD随便打开一个exe文件,因为都会调用kernel32.dll,所以随便一个exe文件都可以。这里我还是调试getkernel.exe。发现程序入口在00401005,与前面使用windbg调试查找到的程序入口是一致的。
根据该图片,我们需要从FS偏移0x30处进入PEB模块,根据上图,可以看到FS为361000,偏移至361000+30=361030
在左下角右键转到表达式361030,进入PEB
然后在偏移0x0C处获得LDR的入口地址,转到表达式0035E000+0C=0035E00C处
在地址0035E00C处,储存着数值770389C0,这里指向的是PEB_ LDR_ DATA的地址,我们转到该地址处可以进入PEB_ LDR_ DATA
现在就进入了PEB_ LDR_ DATA块,可以对照着右图分析一下数据。
我们要取InMemoryOrderModuleList里的Flink指针里的地址值,也就是006F2A08,转到该处,进入LDR_ _MODULE ()。可以看到getkernel.exe的入口地址00401005,基址00400000等。
在LDR_ _MODULE ()中偏移0x08处的指针指向LDR_ MODULE (ntdll.dII),偏移0x08处也就是006F2A08,里面存储的006F2910就是LDR_ MODULE (ntdll.dII)中偏移0x08的位置,我们转到此处。
同理可以分析出ntdll.dll的基址、入口地址等。我们再转到006F8878处可以进入到LDR_ MODULE (kernel32.dIl),就可以看到kermel32.dll的基址是759E0000,这与我们前面用windbg调试得到的数值一致,也与getkercel.exe程序运行的结果一致。