确定kernel32.dll基址的方法

时间:2021-01-08 14:45:12
kernel32.dll这个文件十分重要,它包含很了我们需要使用的函数。比如说,GetProcAdress和LoadLibraryA这个两个函数。想想,通过这两个函数 我们就可以得到所有的函数。如果我们确定了这个动态链接库文件的基址,就可以找到这两个函数的偏移量。怎么确定这个动态链接库的基址呢?这里一共有三个方法
1PEB
peb是process environment block的缩写,每个进程都对应着一个PEB数据结构,通过fs:[30h]可以定位到它。PEB结构包含进程堆信息,二进制镜像信息,还有更重要的三个链接列表,它们与已经映射到进程空间的装载模块有关。从模块装载到模块初始化的序列上,这些链接列表的目的都是不同的。初始化链接列表中最有用的信息是kernel32.dll文件总是作为第二个模块被初始化。通过浏览这个列表的第二个入口点,一个人可以确切地得到kernel32.dll的基址。

代码如下:
         push esi
        xor     eax,eax
        mov  eax,fs:[eax+0x30]  ;fs指向teb结构,teb+0x30地方指向peb结构
        test   eax,eax
        jne    jmp   windows_9x
windows_nt:
        mov  eax,[eax+0x0c]  ;peb+0x0c地方指向PEB_LDR_DATA结构
        mov  esi,[eax+0x1c]  ; PEB_LDR_DATA+0x1c地方就是一些动态连接库的地址了
        lodsd
        mov  eax,[eax+0x08]
        jmp   found:
windows_9x:
        mov eax,[eax+0x34]
        lea   eax,[eax+0x7c]
        mov eax,[eax+0x3c]
found:
        pop  esi
        ret

注:
typedef struct _PEB_LDR_DATA {
ULONG Length;
BOOLEAN Initialized;
PVOID SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;

2通过异常处理函数链表查找kernel32.dll基地址(SEH)
 当一个异常发生时,系统会从fs:[0]处读取异常处理函数链表首指针,开始问所有在应用程序中注册的
异常处理函数,比如上面的"除0异常",系统会把这个异常通知我们的异常处理函数,函数识别出是"除0异常",
并给予了处理(输出了"Can not Divide by Zero!"),并告诉系统"我已经处理过了,不用再问其它函数了".
    如果我们的函数不打算处理这个异常可以交给兄弟节点中异常处理函数指针指向的其它异常处理函数
处理,如果程序中注册的异常处理均不处理这个异常,那么系统将把它发送给当前调试工具,如果应用程序当
前不处在调试状态或是调试工具也不处理这个异常的话,系统将把它发送给kernel32的UnhandledExceptionFilter
函数进行处理,当然它是由程序异常处理链最后一个节点的pfnHandler(参考EXCEPTION_REGISTRATION_RECORD)函数指针成员指向的,该节点的pNext成员将指向0xffffffff.

EXCEPTION_REGISTRATION STRUCT
Prev          dd  ?  ;指向前一个EXCEPTION_REGISTRATION结构的指针
Handle    dd  ?   ;当前异常处理回调函数地址
EXCEPTION_REGISTRATION  ENDS

代码如下:
        push  esi
        push  ecx
        xor       ecx,ecx
        mov    esi,fs[ecx]
        not      ecx
exception_next:
        lodsd
        mov    esi,eax
        cmp    [esi],ecx
        jne      exception_next
        mov    eax,[eax+04h]
jump_down:
        dec     eax
        xor       ax,ax
        cmp    word ptr  [eax],5a4dh
        jnz       jump_down
        pop     ecx
        pop     esi