我们都知道,GetProcAddress函数就是从系统文件kernel32.dll中导出的,而kernel32.dll是系统的基础链接库,每一个程序都会加载kernel32.dll的,我们只要得到kernel32.dll的基址就可以找到GetProcAddress函数的地址了。而获取kernel32.dll的加载基址的方法有3种,第一种就是通过特征匹配的暴力搜索,第二种就是利用系统的SEH机制找到kernel32.dll并搜索出加载基址,第三种就是通过线程环境块TEB的信息逐步找到kernel32.dll的加载地址。
这里介绍第三种办法:
1.通过段选择字FS在内存中得到当前线程环境块TEB的地址。
2.TEB偏移为0x30处是指向进程环境块PEB的指针。
3.PEB偏移为0x0c处是指向PEB_LDR_DATA结构的指针。
4.PEB_LDR_DATA偏移为0x1c处是模块初始化链表的头指针InInitializationOrderModuleList。
5.InInitializationOrderModuleList中按顺序存放着这个进程初始化模块的信息,第一个节点是ntdll.dll基址,第二个就是kernel32.dll基址。
DWORD GetKernel32Base()
{
DWORD dwKernel32Base=0;
_asm
{
push eax
mov eax,dword ptr fs:[0x30]
mov eax,[eax+0x0c]
mov eax,[eax+0x1c]
mov eax,[eax]
mov eax,[eax+0x08]
mov dwKernel32Base,eax
pop eax
}
return dwKernel32Base;
}