INLINE HOOK过简单驱动保护的理论知识和大概思路

这里的简单驱动保护就是简单的HOOK掉内核API的现象

找到被HOOK的函数的当前地址在此地址处先修改页面保护属性然后写入5个字节。5个字节就是一个简单的JMP令。这里说一下JMP指令,如下:

001 JMP 002 这样我们就会跳到

001 (在此地址写入JMP指令)+ 002(我们要写入的JMP操作数) +5(jmp指令的字节数)这里、

就是说如果你要跳回NtOpenProcess的原地址,就应该向被HOOK后的地址处写入这样的指令   JMP ( NtOpenProcess的原地址-HOOK后的地址 - 5 ) 

为什么要减5呢?

这么考虑,原地址为0,现在HOOK后为10,当你在HOOK的地址处写处JMP 0后,IP15到了,所以要减5                            

不是很乱思路清晰一些就明白了:

 

这里有一个修改页面保护属性的过程。这里有以下几种方法:

 

1  修改注册表相应的键值这样改

 HKLM\SYSTEM\CurrentControlset\Control\SessionManger\MemoryManagement\

EnforceWriteProtection=0

HKLM\SYSTEM\CurrentControlset\Control\SessionManger\MemoryManagement\

DisablePagingExecutive=1

一个寄存器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 xxx指令

JMPCODE   Save_Jmp//保护改成之前的5个字节的内容

Cur_ADDR = GetSSDT_Cur_ADDR();//获取当前的SSDT中函数的地址

Old_ADDR = GetSSDT_Old_ADDR(); //获取函数原地址

 

 if (Cur_ADDR  !=  Old_ADDR)   //说明被HOOK

{

//先保存要替换的5个字节的内容

Real_Jmp = (PJMPCODE) Cur_ADDR;  

Save_Jmp. Jmp_Code  =  Real_Jmp -> Jmp_Code

Save_Jmp. Jmp_Addr  =  Real_Jmp -> Jmp_Addr

 

__asm    //去掉页保护

              {

                     Cli  //表示将处理器标志寄存器的中断标志位清0,不允许中断

                     mov eax,cr0

                     and eax,not 10000h //and eax,0FFFEFFFFh

                     mov cr0,eax

 

              }

Real_Jmp-> Jmp_Code =E9;//E9就是jmp的机器码

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; //恢复原地址处的指令

思路大致这样,不是很难理解。

你可能感兴趣的:(OO)