其實所有的HOOK,都基本是一樣道理。就是勾住你的目標函數,實現你自己的功能。只要你掌握了,HOOK的原理。剩下的就是尋找目標函數了。
今天回憶一下 HOOK SYSENTER,目的當然還是繼續充實自己的BLOG,繼續灌水。
一:認識SYSENTER
SYSENTER是一個東西?大家都知道調用門,陷阱門,任務門(這裡沒有照片!_!).。通過他們我們可以從R3到達R0。簡單的說SYSENTER就是他們的替代品。SYSENTER是一個入的
過程,SYSEXIT是他的反過程。
我們以OpenProcess為例,看看他是怎麼從R3-R0
kernel32!OpenProcess -> ntdll!ZwOpenProcess ->
ntdll!KiFastSystemCall -> sysenter -> nt!KiFastCallEntry ->
nt!NtOpenProcess -> nt!KiFastCallEntry> nt!
KiServiceExit -> sysexit -> ntdll!KiFastSystemCallRet -> kernel32!OpenProcess
現在來看看SYSENTER是怎麼樣處理的。
R3-R0需要把相關的工作交給R0層的。包括:設置CS,IP,SS,SP。SYSENTER有三個特殊的寄存器(MSR)來幫助我們完成。
SYSENTER_CS_MSR
SYSENTER_ESP_MSR
SYSENTER_EIP_MSR
他們的地址分別是:0x174,0x175,0x176。我們可以通過指令rdmsr/wrmsr。來讀寫這三個寄存器。相關代碼如下:
_asm
{
mov ecx,0x176
rdmsr
mov OldKiFastCallEntry,eax
}
我們來看看SYSENTER的工作流程。
1. 裝載SYSENTER_CS_MSR 到CS 寄存器,設置目標代碼段
2. 裝載SYSENTER_EIP_MSR到 EIP寄存器,設置目標指令
3. SYSENTER_CS_MSR+8 裝載到SS寄存器 ,設置棧段
4. 裝載SYSENTER_ESP_MSR 到ESP寄存器,設置棧幀
5. 切換RING0.
6. 清除 EFLAGS的 VM標誌
7. 執行RING0例程
SYSEXIT的工作流程
1. SYSENTER_CS_MSR+16裝載到 CS寄存器
2. 將EDX的值送入EIP
3. SYSENTER_CS_MSR+24 裝載到SS寄存器
4. 將ECX的值送入ESP
5. 切換回RING3
6. 執行EIP處的RING3指令
這樣就完成了R3-RO-R3的過程。
二:相關代碼
//////////////////////////////////////////////////
// Hook SysEnter.cpp文件
extern "C"
{
#include <ntddk.h>
}
VOID UnloadDriver(PDRIVER_OBJECT pDriverObj);
ULONG OldKiFastCallEntry;
VOID NewKiFastCallEntry()
{
DbgPrint("一個系統調用...\n");
_asm
{
jmp DWORD PTR[OldKiFastCallEntry]
}
}
// 驅動程序加載時調用DriverEntry例程
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
{
pDriverObj->DriverUnload = UnloadDriver;
//
_asm
{
mov ecx,0x176
rdmsr
mov OldKiFastCallEntry,eax
mov eax,NewKiFastCallEntry
wrmsr
}
// 請視情況返回DriverEntry例程執行結果
return STATUS_SUCCESS;
}
VOID UnloadDriver(PDRIVER_OBJECT pDriverObj)
{
_asm
{
mov ecx,0x176
xor edx,edx
mov eax,OldKiFastCallEntry
wrmsr
}
}
沒有留言:
張貼留言