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后,IP到15到了,所以要减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 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; //恢复原地址处的指令 思路大致这样,不是很难理解。 |
INLINE HOOK过驱动保护的理论知识和大概思路
最新推荐文章于 2022-10-31 17:11:55 发布