个人认为Hook这个东西还是要总结一下,最近在公司里做个东西被破解了,别人挂起了我的程序,和保护的程序,用OD调试一下,发现那个程序Hook了一些windowAPI,那个程序有几个线程,线程的函数都是用了windowAPI做的函数,看了它会一直监视这几个函数,而且线程的函数还是不断变的,我就想自己HOOK一些函数,此篇就作为个人对HOOK技术的总结篇。
大体就分两类:
用户模式的HOOK、内核模式HOOK ,用户模式HOOK也就是在ring3环境下hook kenerl32.dll、User3.dll、Gui32.dll、Advapi.dll、导出的函数
内核模式就是HOOK只有ring0级别环境下才能操作写入改变的内核对象如(ssdt系统服务描述符表)和内核函数地址的改变等等,为什么叫内核模式就是我要ring0才有这个权限去做这些事情呀。
windowapi函数调用的流程如下:
1.用户写的程序调用 kenerl32.dll 的FindFirstFile 或则FindNextFile 函数
2.然后会调用到Ntdll.dll ,而Ntdll.dll会在eax寄存器中写入内核中对应的就是SSDT表中的代表函数地址的索引值,因为我们要在SSDT表中查询这个函数当然要索引啦,就像查一个数据库表,你要有个标志才知道你要查什么呀。还要在edx寄存器中写入函数参数在用户模式下的地址,当然你要调用一个函数有地址你还要有参数不是。通过int 0x2E 或则sysenter指令内陷到内核模式,对了接下来就是内核模式下的事情咯。(这里我要额外说明一下,一般Nt开头的在NtDLL.DLL的函数叫 Native api,它是通过软件中断以后进入内核的大门钥匙而已,有人通过LoadLibrary Ntdll.dll就认为是用了内核模式的函数是不对的)
3.内核模式中了,kiSystemService函数开始了用eax寄存器的索引在SSDT找到函数地址,然后将edx寄存器地址中的函数参数从用户模式堆栈复制到内核模式堆栈。
4.然后是ntoskrnl.exe这个东西咯,这个ntoskrnl.exe可以看做一个容器,它就是ssdt函数的地址标明的函数的实体,现在感觉ntoskrnl.exe就像一个DLL了呵呵,同时ntoskrnl.exe可以细分的看做是一个个windows执行体组件,每个执行体组件都由一些共同特性的函数组成。一般的执行体有:I/O管理器、对象管理器、进程管理器、虚拟内存管理器、配置管理器等等记得还有别的啊,我也记不了(这里要说一下,kernel32.ell 对应的是ntoskrnl.exe 而user32.dll 、GDI32.DLL对应的是 WIN32.SYS)
5.现在就是到了驱动程序了详细不介绍了,会有很多对应上面组件的设备驱动程序
6.下面就是到了内核,内核主要是对线程调度,恩这里对线程不像上面的那个进程管理器windows执行体组件只是对进程的调度没那么细呀、 对中断的处理、错误陷进、提供一些硬件特殊功能的支持、多处理器支持、内核对象支持这个是当然的了;(这里再次强调,进入内核模式和,window内核不是两个同样的概念啊,人家说内核是执行在最高的特权级别上的,可又说它可以被更高级别的中断请求级别打断, 我估计是硬件中断,电源关机等吧)
7.硬件抽象层,这个东西就是使windows系统能很好的在各种不同硬件上运行,不同的总线结构,PCI USB ISA等等,(这里说明一下对硬件抽象层操作的不单单是只有内核、有的驱动程序也直接操作这一层)
哈哈好了基本的调用流程就是这个样子的了