在應用層可以設定的鉤子方法有許多種,其中經典的鉤子是訊息鉤子,訊息鉤子分為兩種,一種是系統級全域性鉤子,另外一種是執行緒級區域性鉤子,它們都是通過下面這一組函式來實現訊息勾取,實現相對簡單。
設定鉤子: setwindowshookex
釋放鉤子: unhookwindowshookex
繼續鉤子: callnexthookex
除此之外,還可以利用修改目標程序空間中pe檔案的iat表中的指定api的位址,使它指向自定的dll函式的api位址來達到api勾取的目的,在自定的api執行完畢之後,為了保證程式的正確執行,又要把相關的修改的地方還原,其中需要注意的是修改iat中的位址的時候需要先通過virtualprotect()函式獲得對相關記憶體的讀寫許可權。
bool virtualprotect(
lpvoid lpaddress, // 目標位址起始位置
dword dwsize, // 大小
dword flnewprotect, // 請求的保護方式
pdword lpfloldprotect // 儲存老的保護方式
);
其中實現的原理如下圖(參考逆向工程核心原理332頁)
下面直接引用書上的源**
injectdll.exe
#include "stdio.h"
#include "windows.h"
#include "tlhelp32.h"
#include "winbase.h"
#include "tchar.h"
void usage()
bool injectdll(dword dwpid, lpctstr szdllname)
premotebuf = virtualallocex(hprocess, null, dwbufsize, mem_commit, page_readwrite);
writeprocessmemory(hprocess, premotebuf, (lpvoid)szdllname, dwbufsize, null);
pthreadproc = (lpthread_start_routine)getprocaddress(getmodulehandle(l"kernel32.dll"), "loadlibraryw");
hthread = createremotethread(hprocess, null, 0, pthreadproc, premotebuf, 0, null);
waitforsingleobject(hthread, infinite);
closehandle(hthread);
closehandle(hprocess);
return
true;
} bool ejectdll(dword dwpid, lpctstr szdllname)
; lpthread_start_routine pthreadproc;
if( invalid_handle_value == (hsnapshot = createtoolhelp32snapshot(th32cs_snapmodule, dwpid)) )
return
false;
bmore = module32first(hsnapshot, &me);
for( ;bmore ;bmore = module32next(hsnapshot, &me) )
}if( !bfound )
if( !(hprocess = openprocess(process_all_access, false, dwpid)) )
pthreadproc = (lpthread_start_routine)getprocaddress(getmodulehandle(l"kernel32.dll"), "freelibrary");
hthread = createremotethread(hprocess, null, 0, pthreadproc, me.modbaseaddr, 0, null);
waitforsingleobject(hthread, infinite);
closehandle(hthread);
closehandle(hprocess);
closehandle(hsnapshot);
return
true;
}dword _enablentprivilege(lpctstr szprivilege, dword dwstate)
closehandle(htoken);
}return dwrtn;
}dll注入以及提權的**和普通dll注入的一樣,沒有變化,在這裡有乙個問題,dll注入之後就可以直接實現執行自定義**,又何必費力去勾取特定函式?我思考之後發現原因可能有二:
1、從惡意**的角度考慮,它是防止殺軟檢測的一種手段(具體原因還沒有搞清楚)
2、從函式監控或者函式補丁的角度來看它顯然用處明顯
int _tmain(int argc, tchar* argv)
// adjust privilege
_enablentprivilege(se_debug_name, se_privilege_enabled);
// injectdll.exe
if( !_tcsicmp(argv[1], l"i") )
injectdll((dword)_tstoi(argv[2]), argv[3]);
else
if(!_tcsicmp(argv[1], l"e") )
ejectdll((dword)_tstoi(argv[2]), argv[3]);
return
0;}
hookiat.dll
// include
#include "stdio.h"
#include "wchar.h"
#include "windows.h"
// typedef
typedef
bool (winapi *pfsetwindowtextw)(hwnd hwnd, lpwstr lpstring);
// globals
farproc g_porgfunc = null;
// 自定用於勾取的替代函式
bool winapi mysetwindowtextw(hwnd hwnd, lpwstr lpstring)
; int i = 0, nlen = 0, nindex = 0;
nlen = wcslen(lpstring);
for(i = 0; i < nlen; i++)
}// user32!setwindowtextw() api
return ((pfsetwindowtextw)g_porgfunc)(hwnd, lpstring);
}// hook_iat
bool hook_iat(lpcstr szdllname, proc pfnorg, proc pfnnew)}}
}return
false;
}bool winapi dllmain(hinstance hinstdll, dword fdwreason, lpvoid lpvreserved)
return
true;
}
小結:
整個思路不算複雜,但是實際程式設計中有一些需要注意的細節不能出錯,否則就會是函式勾取失敗,比如dll注入中額提權操作一定是不能遺忘,還有在iat位址替換的過程中通過查詢iid結構,再一步一步查詢iat中的函式位址也是需要很熟悉pe檔案結構才能準確查詢的,對iid查詢流程中的編碼我現在也不太明白**如下,是比較通用查詢流程
// hmod, paddr = imagebase of calc.exe
// = va to mz signature (image_dos_header)
hmod = getmodulehandle(null);
paddr = (pbyte)hmod;
// paddr = va to pe signature (image_nt_headers)
paddr += *((dword*)&paddr[0x3c]);
// dwrva = rva to image_import_descriptor table
dwrva = *((dword*)&paddr[0x80]);
// pimportdesc = va to image_import_descriptor table
pimportdesc = (pimage_import_descriptor)((dword)hmod+dwrva);
for( ; pimportdesc->name; pimportdesc++ )
u1;
} image_thunk_data32;
forwarderstring 指向乙個轉向者字串的rva;
function 被輸入的函式的記憶體位址;
ordinal 被輸入的api的序數值
addressofdata 指向image_import_by_name
iid結構的查詢在記憶體中彙編表現為[edi+3c]、[edi+eax+80],只要看到此特徵,就能猜測它正在查詢iid,整個過程到此結束,對於程式設計過程中的一些細節以後還需要花時間去整理,對此項技術與其他技術的結合使用也還需要進一步去探索,離找工作時間有限,先了解核心思想為先、、、
Dll注入技術之訊息鉤子
黑客反病毒 dll注入技術之訊息鉤子注入 訊息鉤子注入原理是利用windows 系統中setwindowshookex 這個api,他可以攔截目標程序的訊息到指定的dll中匯出的函式,利用這個特性,我們可以將dll注入到指定程序中。主要流程如下圖所示 1 準備階段 需要編寫乙個dll,並且顯式匯出m...
Dll注入技術之訊息鉤子
dll注入技術之訊息鉤子注入 訊息鉤子注入原理是利用windows 系統中setwindowshookex 這個api,他可以攔截目標程序的訊息到指定的dll中匯出的函式,利用這個特性,我們可以將dll注入到指定程序中。主要流程如下圖所示 1 準備階段 需要編寫乙個dll,並且顯式匯出mymessa...
鉤子注入撥出與隱藏DLL視窗
mfc dll.cpp 定義 dll 的初始化例程。include stdafx.h include mfc dll.h include wgdlg.h include ifdef debug define new debug new endif cwgdlg gameform null hwnd ...