博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Ring 0 Inline Hook
阅读量:5101 次
发布时间:2019-06-13

本文共 3846 字,大约阅读时间需要 12 分钟。

本文讲 用inline hook的方式修改NtOpenKey函数的一个例子

hook 计算机里面一般是指 挂钩某函数,也可以是替换掉原来的函数。

inline hook 是直接在以前的函数替里面修改指令,用一个跳转或者其他指令来达到挂钩的目的。 这是相对普通的hook来说,因为普通的hook只是修改函数的调用地址,而不是在原来的函数体里面做修改。

一般来说 普通的hook比较稳定使用。 inline hook 更加高级一点,一般也跟难以被发现。所以很多人比如病毒制作者都比较推崇inline hook。

SSDT的全称是System Services Descriptor Table,系统服务描述符表

一般来说此表与链接系统内核的API密切相关,对此有一项应用就是杀毒软件的主动防御,当然病毒也可以通过修改主动防御的SSDT来绕过杀软的主动防御。SSDT hook一般是用来隐藏进程运行程序的,前面已经讲了。

 

在函数头部inline hook太容易被发现, 在函数中间inline 不容易被发现, 下面demo实现在函数中间inline

hook NtOpenFile函数, 使用PCHunter查看, 发现NtOpenFile已经被QQ的QQFrmMgr.sys hook了
取ssdt表NtOpenFile的当前地址(QFrmMgr.sys hook地址), 在函数头+48的地方替换5个字节的 机器码 来跳转, 在QFrmMgr.sys里面加了一个inline hook
模块执行流程 ntkrnlpa.exe ---> QQFrmMgr.sys ---> myinline.sys

先用PCHunter查看下NtOpenKey的序号

 

 

 

完整代码

1 #include "ntddk.h" 2  3  4 extern "C"     5 { 6 #pragma pack(1) 7     typedef struct ServiceDescriptorEntry { 8         unsigned int *ServiceTableBase; 9         unsigned int *ServiceCounterTableBase; //仅适用于checked build版本10         unsigned int NumberOfServices;11         unsigned char *ParamTableBase;12     } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;13 #pragma pack()14     __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;15     void PageProtectOn()//恢复内存保护  16     {17         __asm18         {19             mov  eax,cr020             or   eax,10000h21             mov  cr0,eax22             sti23         }24     }25 26     void PageProtectOff()//去掉内存保护27     { 28         __asm{29             cli30                 mov  eax,cr031                 and  eax,not 10000h32                 mov  cr0,eax33         }34     }35     ULONG    g_ntopenkey;36     ULONG    g_jmp_orig_ntopenkey;37     UCHAR    g_orig_funcode[5];38 39     char *pp="my de inline hook";40     void FilterNtOpenFile(char* p1)41     {42         KdPrint(("kk:%s",pp));43         KdPrint(("kk:%s",(char*)PsGetCurrentProcess()+0x16c));44     }45     46     //__declspec(naked) 告诉编译器函数代码的汇编语言为自己的所写,不需要编译器添加任何汇编代码47     __declspec(naked) void NewNtOpenFile()48     {49         __asm{50                     PUSHAD//保存所有寄存器51                     push pp52                     call    FilterNtOpenFile53                     POPAD//还原所有寄存器54                     xor        ecx,ecx55                     mov     eax,esi56                     inc     ecx57                     jmp        g_jmp_orig_ntopenkey58             }59     }60 61     void HookNtOpenKey()62     {63         UCHAR    jmp_code[5]="";//存放修改指令的数组64         ULONG changeva=48;//相对于函数入口偏移48的位置hook65         g_ntopenkey = KeServiceDescriptorTable.ServiceTableBase[179];//NtOpenKey的入口地址66         g_jmp_orig_ntopenkey = g_ntopenkey + changeva+ 5;//调回的地址, 29从入口地址偏移29的地方改写指令, 指令长度567         ULONG u_jmp_temp = (ULONG)NewNtOpenFile - g_ntopenkey - changeva - 5;//计算 newNtOpenKey相对于NtOpenKey的偏移量68         jmp_code[0] = 0xE9;//0xE9对应jmp指令。  (上一篇使用E8(call)指令跳转, 需要在pop eax, jmp不需要)69         *(ULONG*)&jmp_code[1] = u_jmp_temp;//生成完整的修改指令70         PageProtectOff();//解锁内存71         RtlCopyMemory(g_orig_funcode,(PVOID)(g_ntopenkey+changeva), 5);//备份 原始指令, 已便还原72         RtlCopyMemory((PVOID)(g_ntopenkey+changeva), jmp_code, 5);//修改指令73         PageProtectOn();//锁定内存74     }75 76     void UnHookOpenFile()77     {78         PageProtectOff();79         RtlCopyMemory((PVOID)(g_ntopenkey+48),g_orig_funcode,5);//还原指令, 卸载hook80         PageProtectOn();81     }82 83     VOID MyUnload(PDRIVER_OBJECT pDriverObject)84     {85         UnHookOpenFile();//卸载86     }87 88     NTSTATUS DriverEntry(PDRIVER_OBJECT    pDriverObject,PUNICODE_STRING Reg_Path)89     {90         HookNtOpenKey();91         g_ntopenkey = KeServiceDescriptorTable.ServiceTableBase[179];//179==NtOpenFile 函数的 ssdt表的数组下标92         pDriverObject->DriverUnload = MyUnload;93         return STATUS_SUCCESS;94     }95 }

 

转载于:https://www.cnblogs.com/mayingkun/p/5151539.html

你可能感兴趣的文章
CodeChef - METEORAK Meteor
查看>>
andorid月总结
查看>>
iis部署错误:HTTP 错误 500.21 - Internal Server Error
查看>>
Linux系统知识汇总
查看>>
spring mvc 提供的几个常用的扩展点
查看>>
Spring对字段和集合的注入---依赖注入
查看>>
Java 学习 day09
查看>>
P4345 [SHOI2015]超能粒子炮·改
查看>>
暂且解决INSTALL_FAILED_SHARED_USER_INCOMPATIBLE错误
查看>>
Windows10下安装MySQL8.0
查看>>
点分治
查看>>
判断游戏对象是否在摄像机视口的一个方法
查看>>
[POJ1830] 开关问题
查看>>
linux下find查找命令用法
查看>>
《Head First设计模式》
查看>>
CentOS 配置网络yum源
查看>>
UVALive 7274 Canvas Painting (优先队列)
查看>>
HTML中常用的列表标签
查看>>
【Java Saves!】Session 2:我的意图
查看>>
jQuery-4.动画篇---动画基础隐藏和显示
查看>>