1. 程式人生 > >windbg查找Kernel32.dll基址

windbg查找Kernel32.dll基址

ima 代碼 lis png err class 指向 mod 字段

一、首先準備好一個程序,運行起來,用windbg進行附加調試,由於每個windows下的程序都會加載kernel32.dll,因此,找基址的過程是一樣的;

技術分享圖片

技術分享圖片

二、查看PEB地址;

法一、r $peb

技術分享圖片

法二、通過TEB獲取,r $teb

技術分享圖片

獲取到teb地址後,對_TEB結構體解析dt _TEB 3ca000

技術分享圖片

法三、通過fs寄存器獲取,我們知道fs:[0]就是TEB結構體的首地址,但是,在windbg裏dd fs:[0]時,地址卻做了隱藏:

技術分享圖片

那該怎麽辦呢,其實,這就要看下TEB的結構了

技術分享圖片

在TEB結構的0x18偏移處,存放的其實就是TEB的地址,和fs:[0]是一樣的;

另外,在TEB結構的0x30偏移處,存放的就是PEB的地址,我們再來看下:

技術分享圖片

和上面兩種方法,得到的結果都是一致的,這也驗證了我們的想法;

三、接下來,既然PEB的地址找到了,就對PEB進行解析:

首先找到LDR:

技術分享圖片

接下來,解析LDR:

技術分享圖片

這裏,也許有人會有疑問:那個_LIST_ENTRY後面,怎麽有兩個值,是什麽含義呢?加個-b,就看出來了:

技術分享圖片

typedef struct _LIST_ENTRY {
   struct _LIST_ENTRY *Flink;
   struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;

其實,內核數據結構中,比較常見,使用的這個雙向鏈表;

我們就選取InLoadOrderModuleList這個鏈;對它的Flink進行解析,

通過查閱MSDN,知道,這個Flink指向的具體的數據結構類型是:_LDR_DATA_TABLE_ENTRY

技術分享圖片

繼續遍歷InLoadOrderLinks的Flink字段:

技術分享圖片

還不是Kernel32.dll,繼續走:

技術分享圖片

到此,通過遍歷InLoadOrderLinks鏈,我們找到了KERNEL32.DLL,取出基址就比較容易了,在0x18偏移處;

取出這個基址,我們就可以解析PE導出表,找到我們需要的函數的地址了;

四、代碼

int GetKernel32Base() {
    int nAddress = 0
; _asm { push eax; mov eax, fs:[0x30]; // PEB mov eax, [eax + 0xC] // LDR mov eax, [eax + 0xC] // InLoadOrderModuleList, exe mov eax, [eax]; // nt.dll mov eax, [eax]; // kernel32.dll mov eax, dword ptr ds:[eax + 0x18]; // BaseAddr; mov nAddress, eax; pop eax; } return nAddress; }

附錄:

參考MSDN:https://msdn.microsoft.com/en-us/library/windows/desktop/aa813708%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

windbg查找Kernel32.dll基址