確定kernel32.dll基址的方法
阿新 • • 發佈:2019-01-09
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
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