(zhouhongyun1978_at_gmail.com)
探索ndis hook新的實現方法(2)
---inline hook實現ndis hook
前面講述了如何通過獲取ndis_protocol_block來實現ndis hook,這裡講述第二種方法,那就是inline hook方法。說起inline hook,也不是什麼新鮮玩意,無非是在乙個函式的首部嵌入乙個jmp機器指令,在該函式執行有效**前就跳到我們的**函式,在我們的**函式裡做了必要的處理以後,再跳回原來的函式,接著執行原函式的指令。
既然tcpip.sys是標準的ndis協議驅動,那麼收包函式顯然應該是在tcpip.sys內部實現的,我們直接找到這兩個收包函式,然後對其inline hook不就可以了嗎?經過逆向分析,我找到了這兩個函式,本人安裝了兩個xp系統,其中乙個匯出了這兩個函式,另乙個系統卻沒匯出,所以我們仍然需要用特徵碼搜尋這兩個函式,這兩個函式宣告如下:
ndis_status
arprcv (ndis_handle bindcontext,
ndis_handle maccontext,
uchar* headbuffer,
ulong headsize,
uchar* buffer,
ulong buffersize,
ulong packetsize);
int
arprcvpacket (ndis_handle bindcontext,
pndis_packet packet);
搜尋這兩個函式位址的**如下:
//以下全域性變數儲存兩個函式的位址
void* arprcv=null;
void* arprcvpacket=null;
void searchprotocolroutine()
;uchar arprcvpacketbytes=;
//獲取tcpip.sys模組的基位址,該函式在前一節已經提供給大家
char* base=findmodule("tcpip.sys");
while(arprcv==null||arprcvpacket==null)
else if(arprcvpacket==null&&
rtlcomparememory(arprcvpacketbytes,base,10)==10)
base++;}}
各種編譯器所編譯的函式,前幾個指令都是幾乎一樣的,用來建立堆疊幀,這些指令叫函式的序言。
在win2000上是三位元組
push ebp
mov ebp, esp
到了winxp以及後續系統上,則變成了五位元組
mov edi, edi
push ebp
mov ebp, esp
而乙個近跳轉指令剛好是五位元組,在xp上剛好覆蓋了函式的序言,所以在xp上掛鉤也相對容易一點,這裡著重說明如何對arprcv進行掛鉤,我們在arprcv內部插入乙個jmp指令,將跳到arprcvprox函式,該函式是個裸函式,函式實現如下:
_declspec(naked) arprcvprox()//跳板函式
}在該函式內部,又呼叫了newarprcv函式,原型和arprcv保持一致,也必須由我們自己實現:
ndis_status
newarprcv(
in ndis_handle protocolbindingcontext,
in ndis_handle macreceivecontext,
in pvoid headerbuffer,
in uint headerbuffersize,
in pvoid lookaheadbuffer,
in uint lookaheadbuffersize,
in uint packetsize
)同樣的原理,我們在arprcvpacket裡面插入jmp指令,將跳轉到arprcvpacketprox裸函式,該函式實現如下:
_declspec(naked) arprcvpacketprox()
}在該函式內部,將會呼叫newarprcvpacket,函式實現如下:
int
newarprcvpacket(ndis_handle bindcontext,
pndis_packet ndispacket)
請仔細閱讀以上**的注釋,接下來,我們還必須提供乙個函式實現安裝和解除安裝掛鉤功能
void patcharprcv(boolean ispatch)//ispatch為true表示安裝掛鉤,為false表示解除安裝掛鉤。
;//即將用以下五個位元組覆蓋arprcvpacket函式前五個位元組
uchar patchbytes2[5]=;
//儲存原始函式的前五個位元組,方便以後恢復掛鉤
uchar restorebytes[5]=;
/*
以下兩行**計算跳轉的偏移量
*/int offset=(char*)arprcvprox-(char*)arprcv-5;
int offset2=(char*)arprcvpacketprox-(char*)arprcvpacket-5;
//修正patchbytes和patchbytes2中的相對位址
memcpy(patchbytes+1,&offset,4);
memcpy(patchbytes2+1,&offset2,4);
if(ispatch)
else
}因為arprcv和arprcvpacket函式處於唯讀頁,所以必須先禁用寫保護才能向其中插入**,禁用寫保護和開啟寫保護**如下:
void
disablewriteprotect()
}void
enablewriteprotect()
}注意這些**暫時只適用xp系統,在win2000和win2003上都需要少許改動。
探索NDIS HOOK新的實現方法 2
inline hook實現ndis hook 前面講述了如何通過獲取ndis protocol block來實現ndis hook,這裡講述第二種方法,那就是inline hook方法。說起inline hook,也不是什麼新鮮玩意,無非是在乙個函式的首部嵌入乙個jmp機器指令,在該函式執行有效 前...
探索多型的實現 虛表
上次說到了多型,可是多型在編譯器裡到底是如何實現的呢?下面我們就來探索一下它深層的實現機制 我們可以從監視視窗來看一下 這張表解決了繼承 虛函式 重寫 的問題 有虛函式就有虛表 從父類繼承就自動生成了 虛函式表就像乙個路標,指明了實際應該呼叫哪個虛函式 還是用我最喜歡的圖示來說明,下圖 我們還是來看...
分類演算法的探索與實現
有監督與無監督 1 有監督學習 通過已有的訓練樣本去訓練得到乙個最優模型,再利用這個模型將所有的輸入對映為相應的輸出,對輸出進行簡單的判斷從而實現 和分類的目的,也就具有了對未知資料進行 和分類的能力。就如有標準答案的練習題,然後再去考試,相比沒有答案的練習題然後去考試準確率更高。又如我們小的時候不...