函式鉤子 Dll注入

2021-07-15 10:35:39 字數 4915 閱讀 2655

在應用層可以設定的鉤子方法有許多種,其中經典的鉤子是訊息鉤子,訊息鉤子分為兩種,一種是系統級全域性鉤子,另外一種是執行緒級區域性鉤子,它們都是通過下面這一組函式來實現訊息勾取,實現相對簡單。

設定鉤子: 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 ...