YJX_Driver_011_驱动保护原理实战__IDA

1、

【00:28】认识Win32子系统

  【02:02】WinAPI 一般分为3类:USER函数、GDI函数、Kernel函数

    【02:38】GDI --> 物理设备上执行绘图操作 --> win32k.sys

    【02:55】win32k.sys 一般我们很少用到,常用的是 ntkrnlpa.exe 和 ntkrnlpa.lib (kernel32.dll)。在开发NT式驱动的时候 就需要 这个库(ntkrnlpa.lib)。管理 进程、线程、文件、内存 相关的一些操作。kernel32.dll 是用户层的,ntkrnlpa.lib 是内核层的

 

【03:41】SSDT

  相当于架起了用户层到内核层的桥梁,把 ring3 和 ring0 的API联系起来

 

【04:10】以 OpenProcess 为例

  【04:35】打开OD调试器,附加到一个notepad.exe进程

  【04:37】OD里面 转到(即 "输入要跟随的表达式") (ZC:他是直接用快捷键来调出这个窗口的,窗口中要跟随的是"OpenProcess","VA/API" 是选中的,当前OD是notepad.exe的领空)

    【04:42】转了之后,就到了 kernel32 的领空了

  【05:18】xx.dll/xx.exe -->kernel32.dll  OpenProcess

      【05:35】往下看,看到OD提示ntdll.NtOpenProcess ntdll.ZwOpenProcess,右击-->复制到剪切板

      【06:03】用户层下 这两个函数ntdll.NtOpenProcess、ntdll.ZwOpenProcess等价,指向的地址是一样的

        但是 ZwOpenProcess 是一个导出函数,我们在OD中可以直接"转到",NtOpenProcess 不是导出函数 OD中不能直接"转到" 转不过去

        【06:30】转到 ZwOpenProcess 之后,复制前面几行的代码

        【06:40】在ZwOpenProcess函数的第3行 有一个CALL 但是它(OD)没有给出导出函数的名字

          【06:47】但是 看一下ZwOpenProcess函数的第2行 里面的 立即数 7FFE0300,然后 OD中执行"dd 7FFE0300"(ZC:这里,我的OS和教程里面的OS不同,估计会有差别)

             这里我们在数据窗口就能看到 实际上是调用更深层的CALL ntdll.KiFastSystemCall。但是这个函数是一个公用的接口函数,几乎所有的API函数最终都会调用这个函数

             【07:38】看到 各个调用 ntdll.KiFastSystemCall 时 参数EAX是不同的,这里的 7A、7B、7C就跟我们的SSDT连系起来

            【08:12】它是如何切换到内核的呢?我们继续跟,数据窗口 ntdll.KiFastSystemCall 上 右击-->"反汇编窗口跟随",于是又跟随到新的地方。第2行 有一个 SYSENTER指令 这是一个软中断,通过这个软中断 它就切换到内核,切换到内核 之后 它就会去查询SSDT(System Services Descriptor Table),它就进入到内核了 【08:56】进入到内核后 我们这里看不到(用OD看不到了 ∵它转到内核里面了,OD不是内核调试器)

   【09:12】此时 把 ntkrnlpa.exe 和 ntkrnlpa.idb 单独复制出来了,并使用 ntkrnlpa.idb来进行逆向,(双击ntkrnlpa.idb 弹出来的是 IDA)

    【09:33】IDA 进行静态的逆向 是非常强的。∵ 驱动不可能被加壳 ∴可以直接反汇编掉

    【10:10】 ntdll.ZwOpenProcess 应该最后调用的是 NtOpenProcess 【10:12】看IDA中ntkrnlpa.idb的导出函数

      【10:43】看到 里面有 ZwOpenProcess(x,x,x,x)函数  【11:07】找到 NtOpenProcess(x,x,x,x)函数

  【11:40】如果在上面这一连串的函数调用链里面 任选一个函数来进行 内联hook(inline hook)的话,就可以做一些手脚,以保护我们自己的游戏的进程之类的(进程)

    【11:57】如果我们要过这个保护的话,我们可以恢复原来的代码,但是游戏一般会反复的检测,∴ 恢复的话,一般来说 是不行的

  【12:25】我们把它整理一下

    访问通道:

      应用层:xx.dll/xx.exe --> (kernel32.dll)OpenProcess --> ntdll.NtOpenProcess/ntdll.ZwOpenProcess

      内核 ntkrnlpa.ZwOpenProcess --> SSDT --> ntkrnlpa.NtOpenProcess

 

【13:40】游戏例子讲解

  兽血沸腾 国际版,国际版 才有这个保护,而 迅雷版 没有这个保护(ZC:听到的是 迅雷版?)

  【14:00】要过它的保护,可以在驱动加载之前(也就是 游戏的驱动还没有对 API函数 hook之前)。现在我们讲的是 驱动的hook,肯定是 内核函数的hook 那就是 ntkrnlpa.ZwOpenProcess / ntkrnlpa.NtOpenProcess,一般 hook的是 ntkrnlpa.NtOpenProcess。∵ OD调试的过程 是通过 进程ID --> OpenProcess打开调试进程。当然我们可以在 游戏的驱动还没有加载的时候 打开调试进程(ZC: 应该是说 直接用OD来启动调试程序),当然我们现在说的是 在游戏的驱动已经加载后的情况的处理

   【15:05】打开 进入 游戏,用工具来看一下  【15:15】XueTr.exe(ZC:啥工具?教程里面是 XueTr0.29)

     【15:20】看一下"钩子"-->SSDT ,右击 刷新一下,【15:31】这里我们看到 内核里面的 NtOpenProcess 被hook了(ZC:可以看到当前函数所在模块为"C:\Windows\System32\sx.sys")

    ZC: 我有个疑问,为何 游戏"兽血沸腾"加载驱动时,视频里面的 360一点反应都没有?是已经在360的白名单里面了?还是 sx.sys有特殊手法处理?

    【15:57】"钩子"--> "Shadow SSDT" ,看到 游戏驱动 sx.sys hook了5个函数:NtGdiGetPixel(屏幕取点的API函数)

    【16:28】"Shadow SSDT" 和 "SSDT" 是两个不同的结构,前面讲的时候忘了讲

      【16:35】通过 kernel函数(kernel32.dll)访问 经过的应该是 SSDT,如果是GDI的函数(gdi32.dll)访问 经过 win32k.sys  经过的就是 ShadowSSDT(它是另外的一个SSDT结构) 进入内核。两张 SSDT的表

    【18:18】sx.sys hook 了 NtUserMessageCall/NtUserPostMessage,通过hook这两个函数 就屏蔽了 应用层的PostMessage和SendMessage函数

    【18:35】sx.sys hook 了 NtUserSendInput,应用层 键盘方面的模拟也就失效了

    【18:43】sx.sys hook 了 NtUserSetWindowHookEx,这个方式外挂的动态链接库进行注入(ZC:也就是应用层的SetWindowHookEx)

  【19:17】我们要恢复 sx.sys hook的NtOpenProcess的话,XT工具正好提供了这个功能。右击-->恢复一下。ShadowSSDT里面的5个函数 也恢复掉

    【19:39】但是我们一刷新之后,它又变成被 sx.sys hook 的状态了,sx.sys 会不断的进行hook

  【20:27】看一下 XT --> "钩子"--> "系统中断表",它还有一些钩子,选中 某个 在"C:\windows\system32\ntkrnlpa.exe"中的函数 --> 右击 --> "仅显示挂钩函数" --> 出现了8个未知模块的函数,它们也可能是驱动造成的

  【20:53】实际看一下 如何对它进行修复(修复被hook的函数)

    【20:55】原理:自己搭建一个驱动,另外建一个dll,载入到OD里面去,与我们的驱动进行通讯,然后直接调用 NtOpenProcess,这种方法应该是可以的,但是这个方法相对比较复杂。今天我们主要是讲 用工具来过

    【21:26】要用到另外一个工具,直接可以修改内核代码,XT显然是不适用的

      【21:41】可以用KD(ZC:视频中是 "Kernel Detective v1.3.0")或者是 RKU/RK(ZC:视频中是 RKUnhooker3.7),这两个 都可以直接修改内核的代码,今天我们使用 KD

    【22:00】KD --> "系统服务描述表"(ZC: 这里是汉化的,即 SSDT)

      【22:15】恢复之前打开OD,我们根本就找不到 游戏的进程(ZC: 但是我看到一个 名称:"client",路径:"E:\兽血沸腾\client.dat"),是可以看到的,【22:40】只是无法附加,提示信息为:“无法附加进程'client'”

      【23:45】KD --> "系统服务描述表" --> 对 列"模块"排序之后,看到2个被"C:\windows\system32\sx.sys" hook的函数 NtOpenProcess 和 NtWriteVirtualMemory。还有 7个 被spuz.sys hook的函数(ZC:spuz.sys是干嘛的?)

        【24:10】NtWriteVirtualMemory 被 hook之后,用户层的 WriteProcessMemory() 也不能正常的耍了

      【23:45】KD --> "系统服务描述表" --> 列"起源地址" 也就是 以前的地址。把这两个函数的 "当前地址" 和 "起源地址" 都记录下来。  如果是相同的OS,"起源地址" 应该是不会变的。

 ZC: sz.sys hook了这些个函数,它什么时候还原?它不怕进程意外终止 而使得hook的函数无法还原?从而导致系统不能正常的使用?貌似sx.sys也只是做了保护 没有做破坏,系统正常使用应该没问题?

      【25:28】KD --> "系统服务描述表" --> 选中NtOpenProcess那一行 --> 右击 --> 转到当前地址,此时跳转到 "反汇编"选项卡了  【25:55】选中第一条指令--> 右击 --> “汇编+写入” --> 将原来的“mov edi,edi”改为“jmp 0x805CC40A”,看一下结果 看看sx.sys会不会对它的伪NtOpenProcess的首指令进行检测/修复  如果会的话  我们还要将"jmp 0x805CC40A"放到下面一点的指令的地方。  【26:28】如果这里改错了,马上就会蓝屏的 【26:32】点击 按钮"汇编"

ZC:也就是说,我们刚刚用XT改的那个方法是改的内存里面SSDT表里面的值,而sx.sys又会循环的检测 改回去。这里我们直接改的就是 sx.sys里面的 伪NtOpenProcess的代码,直接跳到真的NtOpenProcess那边去了。

      【26:40】此时,第一条指令 就变成了 "jmp ntkrnlpa.NtOpenProcess"。【26:57】再次 用OD附加 游戏进程,发现我们的OD正常的附加进去了,当然我们不能说 它就能够正常的调试了,实际上 它对内存断点也做了一些保护,但是我们可以用 硬件断点  "he send"就可以成功断下("hd send"删掉硬件断点 继续运行程序),当然我们使用 "bp send"好像是断不下来 进游戏 bp断点果然断不下来

        【28:05】再次在send的函数上设置断点,(ZC:这次直接是按得F2,也是属于内存断点?) 然后 "dd send" 看一下 数据窗口,好像 int3 的指令是没有写入的。【28:32】其实我们可以看到 其实int3是一个0xCC指令 其实int3断点被游戏自己删除掉了,它会检测 函数的开始的指令,我们把断点下在下面一点的地方,同样断不下来,以后再研究。【28:55】断点应该是被游戏检测删除掉了,理论上应该可以将断点设在里面一点的地方(将断点设在send调用的子函数里面),同样断不下来 (ZC:在删除断点的时候,OD提示"断点已损坏!"。【29:15】硬件断点 它删不掉,用硬件断点来调试 【29:35】硬件断点下错了,硬件的执行断点是 "he send",刚才写成了"hr send"(ZC: hr什么意思?)  【29:45】以后再讲,如何反 调试断点,如何恢复调试断点 在以后的课程里面再讲

  【30:20】对于更难的保护 还需要做其他的研究,以后课程再讲

  【30:35】对于 sx.sys 改掉的其他的函数,应该也是可以通过类似的方法改回去的

  【30:55】本节课,我们讲的是通过工具的方式,讲 被修改的代码改回去,那通过编程 怎么弄呢,这里 也讲一下:

    在驱动载入的地方就写入 jmp指令,【31:18】在驱动退出的时候,就 恢复指令。具体写的话,还要涉及到内核的页面保护之类的,这个在以后的课程中讲。

    ZC: 这里没懂,怎么会是在 DriverEntry 和 驱动退出的函数(DDK_Unload) 中去写呢?没明白...

 

 

【31:40】如果是用户层的保护的话,有可能就是 hook前面的这几个函数(kernel32.OPenProcess / ntdll.NtOpenProcess / ntdll.ZwOpenProcess)

【32:02】基本上所有的np(ZC: 听到的是"np"吗?貌似以前在哪里听到过这个缩写),驱动保护 都会有hook,都是通过hook来实现保护的,但是 hook的地方和监测的内容可能不一样,以后的课程中再讨论

 

 

2、

 

posted @ 2016-03-24 14:09  DebugSkill  阅读(1048)  评论(0编辑  收藏  举报