2010年12月4日 星期六

Hook SYSENTER

  其實所有的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


}


}


 


沒有留言:

張貼留言