INLINE HOOK過簡單驅動保護的理論知識和大概思路、、
這裏的簡單驅動保護就是 簡單的 HOOK 掉內核API的現象、、、
找到被HOOK的函數的當前地址在此地址處先修改頁面保護屬性然後寫入5個字節、5個字節就是一個簡單的JMP指令、
這裏說一下JMP、如下、、
001 JMP 002 這樣我們就會跳到
001 (在此地址寫入JMP指令)+ 002(我們要寫入的JMP操作數) +5(jmp指令的字節數)這裏、
就是說如果你要跳回NtOpenProcess的原地址、
就應該向被HOOK後的地址處寫入這樣的指令 JMP ( NtOpenProcess的原地址 - 被HOOK後的地址 - 5 )
不是很亂思路清晰一些就明白了、、
這裏有一個修改頁面保護屬性的過程、、這裏有以下幾種方法、、
1 修改註冊表相應的鍵值這樣改、
HKLM\SYSTEM\CurrentControlset\Control\SessionManger\MemoryManagement\
EnforceWriteProtection=0
與
HKLM\SYSTEM\CurrentControlset\Control\SessionManger\MemoryManagement\
DisablePagingExecutive=1
2 一個寄存器cr0,32位寄存器、
它的第17位(WP位)如果爲1、表示開啓頁面保護0則是去掉頁面保護、
__asm //去掉頁保護
{
Cli //表示將處理器標誌寄存器的中斷標誌位清0,不允許中斷
mov eax,cr0
and eax,not 10000h //and eax,0FFFEFFFFh
mov cr0,eax
}
__asm //恢復頁保護
{
mov eax,cr0
or eax,10000h //or eax,not 0FFFEFFFFh
mov cr0,eax
sti
}
3通過內核API函數Memory Descriptor List(MDL)-正規做法 通過它來描述某一塊內存可讀或可寫、、
現在說一下寫入JMP指令注意的知識點、、、
1 彙編寫入
2 指針寫入 將其定義成一個結構體如下
typedef struct _JMPCODE
{
BYTE Jmp_Code;
ULONG Jmp_Addr;
}JMPCODE,*PJMPCODE;
(這裏就需要 修改對齊方式 #pragma pack(1) 、、、 恢復#pragma pack())
對齊標誌改爲1 本來是4、如果是4偏移就要加8、、本來我們是加5的、、
部分代碼如下
PJMPCODE Real_Jmp;//保存寫入的JMP信息
JMPCODE Save_Jmp;//保護改成之前的指令
Cur_ADDR = GetSSDT_Cur_ADDR();//獲取當前的SSDT中函數的地址
Old_ADDR = GetSSDT_Old_ADDR(); //獲取函數原地址
if (Cur_ADDR != Old_ADDR) //說明被HOOK了
{
Real_Jmp = (PJMPCODE) Cur_ADDR; //初始化結構體爲要改寫的地址處、
//下邊先保存一下要改寫的地址處的內容、用於在Unload驅動的的時候恢復它、、、
Save_Jmp. Jmp_Code = Real_Jmp -> Jmp_Code;//用指針讀取1字節
Save_Jmp. Jmp_Addr = Real_Jmp -> Jmp_Addr;//4字節
__asm //去掉頁保護
{
Cli //表示將處理器標誌寄存器的中斷標誌位清0,不允許中斷
mov eax,cr0
and eax,not 10000h //and eax,0FFFEFFFFh
mov cr0,eax
}
Real_Jmp-> Jmp_Code =E9;
Real_Jmp-> Jmp_Addr = Old_ADDR - Cur_ADDR -5; //這兩條代碼就是INLINE HOOK的核心代碼、、
__asm //恢復頁保護
{
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
}
在Unload裏恢復如下也需要更改頁面保護、、
然後反寫之前保護時的語句即可、、
Real_Jmp-> Jmp_Code = Save_Jmp. Jmp_Code;
Real_Jmp-> Jmp_Addr = Save_Jmp. Jmp_Addr; //恢復原地址處的指令、、、
思路大致這樣、、不是很難理解、、