xx_學驅動 -- INLINE HOOK 過簡單驅動保護、、

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; //恢復原地址處的指令、、、

 

思路大致這樣、、不是很難理解、、

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章