本文例項簡述了實現inline hook的原理及應用,對於大家更好的理解inline hook原理及其應用有很大的幫助。具體內容如下:
一、inline hook簡介:
1.inline hook原理:
inline hook通過硬編碼的方式向核心api的記憶體空間(通常是開始的一段位元組,且一般在第一個call之前,這麼做是為了防止堆疊混亂)寫入跳轉語句,這樣,該api只要被呼叫,程式就會跳轉到我們的函式中來,我們在自己寫的函式裡需要完成3個任務:
1)重新調整當前堆疊。程式流程在剛剛跳轉的時候,核心api並沒有執行完,而我們的函式需要根據其結果來進行資訊過濾,所以我們需要保證核心api能在順利執行完畢後返回到我們的函式中來,這就要求對當前堆疊做一個調整。
2)執行遺失的指令。我們向核心api地址空間些如跳轉指令(jmp ******xx)時,勢必要覆蓋原先的一些彙編指令,所以我們一定要保證這些被覆蓋的指令能夠順利執行(否則,你的及其就要bsod了,呵呵 screen of death)。關於這部分指令的執行,一般是將其放在我們的函式中,讓我們的函式“幫助”核心api執行完被覆蓋的指令,然後再跳回核心api中被覆蓋內後後的地址繼續執行剩餘內容。跳回去的時候,一定要算好是跳回到什麼地址,是核心api起始地址後的第幾個位元組。
3)資訊過濾。這個就不用多說了,核心api順利執行並返回到我們的函式中,我們自然要根據其結果做一些資訊過濾,這部分內容因被hook的api以及hook目的的不同而不同。
2.inline hook的工作流程:
1)驗證核心api的版本(特徵碼匹配)。
2)撰寫自己的函式,要完成以上三項任務。
3)獲取自己函式的地址,覆蓋核心api記憶體,供跳轉。
簡而言之,inlinehook的原理就是,修改函式,使其跳轉到我們指定的地方。
常見的有改函式入口,也有改函式尾,函式中間的
比如,通常函式開頭的彙編**都是這樣:mov edi,edi;push esp;mov ebp,esp,而我們便可以通過修改這裡進行hook。
二、示例**(該示例摘自看雪)
#include
#include
ulong g_kiinsertqueueapc;
ulong g_ucr0;
byte g_hookcode[5] = ; //jmp near
byte g_origcode[5] = ; // 原函式的前位元組內容
byte jmp_orig_code[7] = ; //jmp far
bool g_bhooked = false;
void
fake_kiinsertqueueapc (
pkapc apc,
kpriority increment
);void
proxy_kiinsertqueueapc (
pkapc apc,
kpriority increment
);void wpoff()
; g_ucr0 = uattr; //儲存原有的 cro 屬性
}void wpon();}
//// 停止inline hook
//void unhookkiinsertqueueapc ()
//// 開始inline hook -- kiinsertqueueapc
//void hookkiinsertqueueapc ()
//dbgprint("開始inline hook -- kiinsertqueueapc\n");
dbgprint( "kiinsertqueueapc的地址t0x%08x\n", (ulong)g_kiinsertqueueapc );
dbgprint( "fake_kiinsertqueueapc的地址t0x%08x\n", (ulong)fake_kiinsertqueueapc );
// 儲存原函式的前位元組內容
rtlcopymemory (g_origcode, (byte*)g_kiinsertqueueapc, 5);
//jmp指令,此處為短跳,計算相對偏移,同時,jmp ******這條指令佔了5個位元組
*( (ulong*)(g_hookcode + 1) ) = (ulong)fake_kiinsertqueueapc - (ulong)g_kiinsertqueueapc - 5;
// 禁止系統防寫,提升irql到dpc
wpoff();
oldirql = keraiseirqltodpclevel();
rtlcopymemory ( (byte*)g_kiinsertqueueapc, g_hookcode, 5 );
*( (ulong*)(jmp_orig_code + 1) ) = (ulong) ( (byte*)g_kiinsertqueueapc + 5 );
rtlcopymemory ( (byte*)proxy_kiinsertqueueapc, g_origcode, 5);
rtlcopymemory ( (byte*)proxy_kiinsertqueueapc + 5, jmp_orig_code, 7);
// 恢復防寫,降低irql
kelowerirql(oldirql);
wpon();
g_bhooked = true;}//
// 跳轉到我們的函式裡面進行預處理,裸函式,有呼叫者進行堆疊的平衡
//__declspec (naked)
void
fake_kiinsertqueueapc (
pkapc apc,
kpriority increment
)}//
// **函式,負責跳轉到原函式中繼續執行
//__declspec (naked)
void
proxy_kiinsertqueueapc (
pkapc apc,
kpriority increment
)}ulong getfunctionaddr( in pcwstr functionname)
//根據特徵值,從keinsertqueueapc搜尋中搜尋kiinsertqueueapc
ulong findkiinsertqueueapcaddress()
; ulong addr_kiinsertqueueapc = 0;
addr_keinsertqueueapc = (char *) getfunctionaddr(l"keinsertqueueapc");
for(i = 0; i < 100; i ++)
}return addr_kiinsertqueueapc;
}void onunload( in pdriver_object driverobject )
ntstatus driverentry( in pdriver_object thedriverobject, in punicode_string theregistrypath )
本文標題: c++實現inline hook的原理及應用例項
本文地址:
synchronize的實現原理
但這顯然並不是最好的一種方法,不掛起執行緒的代價就是該執行緒會一直佔用處理器。如果鎖被佔用的時間很短,自旋等待的效果就會很好,反之,自旋會消耗大量處理器資源。因此,自旋的等待時間必須有一定的限度,如果超過限度還沒有獲得鎖,就要掛起執行緒,這個限度預設是10次,可以使用 xx preblockspin...
Hive Group By的實現原理
select rank,isonline,count from city group by rank,isonline 將groupby的欄位組合為map的輸出key值,利用mapreduce的排序,在reduce階段儲存lastkey區分不同的key。mapreduce的過程如下 當然這裡只是說明...
ThreadLocal 的實現原理和應用場景
threadlocal 是一個執行緒內部的資料儲存類,通過它可以在指定的執行緒中儲存資料,資料儲存以後,只有在指定執行緒中可以獲取到儲存的資料,對於其他執行緒來說則無法獲取到資料 可以理解成執行緒本地變數或執行緒本地儲存,threadlocal 為變數在每個執行緒中都建立了一個副本,那麼每個執行緒可...
C 實現IDL原碼研究
include include include include include using namespace std class nulltype class iparameter class imethod template struct in public iparameter void pr...
簡單的INLINE HOOK檢測
desc 目前只檢測最簡單的兩種inline hook,對iat hook,call hook和深層次的inline hook沒檢測。desc 最好的恢復方法是先恢復iat hook,然後從函式所在檔案中提取函式機器碼與記憶體中對比,不同則恢復之 param1 in dwproc 函式地址 bool...
C 引用加原創 C 實現kalman濾波
最近為了專案,同事讓我幫他做一個硬體版的kalman濾波器,實現對裝置的kalman濾波,以驗證他的理論演算法。猶豫了好幾天,用dsp吧,我的kalman濾波演算法比較簡單,有點大材小用。剛好手裡有一塊arm除錯版,也裝了wince系統,就準備在.net環境下編一個kalman濾波器。雖說學的是導航...
Dubbo Monitor 實現原理?
consumer 端在發起呼叫之前會先走 filter 鏈 provider 端在接收到請求時也是 先走 filter 鏈,然後才進行真正的業務邏輯處理。預設情況下,在 consumer 和 provider 的 filter 鏈中都會有 monitorfilter。1 monitorfilter ...
okhttp中的Okio實現原理
你的打賞是我奮筆疾書的動力!okhttp中使用到的okio對io的操作進行了自己的封裝,okio擁有自己的快取,okio的讀寫都會經過自己的快取,而okio的快取採用了池化的思想,也就是並不是用完了分配的記憶體就立即釋放,在頻繁讀寫的時候,提高了一定的效能。okio的主要類圖如下 okio主要類的方...
zookeeper服務的實現原理
1.zookeeper是什麼?zookeeper是分散式應用程式協調服務,是叢集的管理者,監視著叢集中各個節點的狀態根據節點提交的反饋進行下一步合理操作 2.zookeeper提供了什麼?1 檔案系統 2 通知機制 3.zookeeper檔案系統 每個子目錄項如 nameservice 都被稱作為z...
oracle rac 負載的實現原理
rac的負載均衡主要是指新會話連線到rac資料庫時,如何判定這個新的連線要連到哪個節點進行工作。在rac中,負載均衡分為兩種,一種是基於客戶端連線的,另外一種是基於伺服器端的。客戶端的負載均衡配置相對簡單,只需要在tnsnames.ora中新增load balance on這麼一個選項即可。比如下面...