Win32 XP 下和WIN7下获取Kernel32基址的方法
;xp下使用
_GetKernelBase proc
local @dwRet
pushad
assume fs:nothing
mov eax,fs:[30h] ;获取PEB所在地址
mov eax,[eax+0ch] ;获取PEB_LDR_DATA 结构指针
mov esi,[eax+1ch] ;获取InInitializationOrderModuleList 链表头
;第一个LDR_MODULE节点InInitializationOrderModuleList成员的指针
lodsd ;获取双向链表当前节点后继的指针
mov eax,[eax+8] ;获取kernel32.dll的基地址
mov @dwRet,eax
popad
mov eax,@dwRet
ret
_GetKernelBase endp
;XP 和win7下皆可用
_GetKernelBasew proc _lpAddress
local @Ret
mov edi,_lpAddress
and edi,0ffff0000h
.repeat
.if word ptr [edi] == IMAGE_DOS_SIGNATURE
mov esi,edi
add esi,[esi+3ch]
.if word ptr [esi] == IMAGE_NT_SIGNATURE
mov @Ret,edi
.break
.endif
.endif
sub edi,010000h
.break .if edi < 070000000h
.until FALSE
mov eax,@Ret
ret
_GetKernelBasew endp
1 ;=======================
2 ;函数根据操作系统默认分配SEH处理程序Kernel32._except_handle
3 ;也就是SEH一开始指向一个处理函数是位于
4 ;kernel32中的
5 ;注意 : 测试在Win7下不可用,wen7下SEH处理程序是在ntdll中,尼玛伤不起
6 ;函数功能:获取Kernel32基址
7 ;返回值:Kernel32基址
8 ;=======================
9 _GetKernel32Basex proc
10 local lRet
11 pushad
12 assume fs: nothing
13 mov eax,fs:[0] ;获取到指ExceptionList默认节点,ExceptionList每个节点是个结构是EXCEPTION_REGISTRATION
14 mov esi, eax ;EXCEPTION_REGISTRATION 好多东西都忘了
15 ;EXCEPTION_REGISTRATION 应该有2个成员一个是 Prev ,一个是 hWnd 一个是指向前一个EXCEPTION_REGISTRATION
16 ;另外一个是处理函数地址
17 mov eax,[eax] ;获取到EXCEPTION_REGISTRATION.Prev Prev是指向前一个EXCEPTION_REGISTRATION结构
18 inc eax
19 jne _Ret;这里是判断 是不是最ExceptionList表头第一个EXCEPTION_REGISTRATION
20 lodsd
21 lodsd ;取出默认处理函数地址
22 xor ax,ax ;将低位置0,基址都是是整倍存放
23 jmp loc2
24
25 loc1:
26 sub eax,10000h
27 loc2:
28 cmp dword ptr [eax],905a4dh
29 jne loc1
30 mov lRet,eax
31
32 _Ret:
33 popad
34 mov eax,lRet
35 ret
36 _GetKernel32Basex endp