elva

syser 实战一(分析 nprotect 的 dump_wmimmc.sys)

syser 实战一(分析 nprotect 的 dump_wmimmc.sys)

 我们使用跑跑卡丁车这款游戏来调试 dump_wmimmc.sys 驱动.
通常调试一个程序都要从程序入口开始。当然调试驱动也不例外。
我们可以通过 bpload dump_wmimmc.sys 断点来拦截 dump_wmimmc.sys 的驱动程序入口函数。
(也就是 NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath))

当然了其他的驱动程序都可以通过这种方法来设置断点在驱动入口。但是调试 NP 保护的游戏还是需要一点技巧。
因为 NP 把 syser debugger 列入了黑名单。就是他的应用程序部分在运行时会检测 syser.sys 如果在运行时。
应用程序会直接退出. 如下图

我们首先启动 跑跑卡丁车游戏。在出现如下窗口时

 然后马上启动 syser debugger. 然后 ctrl+f12 呼出
syser debugger 的主窗口,(这里速度要快,要不然会错过 dump_wmimmc.sys 的加载)然后执行 bpload dump_wmimmc.sys 命令,然后 F5 后 x 命令退回到 windows.
随后 当 dump_wmimmc.sys 驱动被加载时调试器被激活,调试器界面如下:
 

这时我们可以使用 driver dump_wmimmc 命令来查看有关这个驱动的信息。
如果我们想要了解这个驱动的详细初始化过程我们可以单步跟踪每条指令,
如果我们只关心应用程序是如何于 dump_wmimmc.sys 交互过程,我们只需要把断点设置在关键函数上就可以。
那我们如何来定位这个关键函数,大家可能都比较熟悉驱动和应用的交互主要通过以下几个 API 来完成。
CreateFile,用来打开这个驱动的文件句柄,DeviceIoControl 用来和驱动交互。 CloseHandle 关闭驱动的句柄。
驱动的 DriverEntry 函数主要是负责 初始化驱动对象,建立一个设备对象,建立一个符号连接,可以让应用程序
使用 CraateFile 这个 api 来打开这个驱动文件的句柄。初始化驱动对象 主要是包括了完成驱动对象中一些函数指针
的初始化。这里就包括了 最重要的 DeviceIoControl 被调用时,驱动程序要执行的函数的指针的初始化。
我们可以通过 p ret 命令,来执行完 DriverEntry 函数, 执行完这个函数后我们在用 driver dump_wmimmc 命令
来看一下 DRIVER_OBJECT 的变化, 这个时候我们从下图可以看到
 

我们把断点设置 IPR_MJ_DEVICE_CONTROL 出来函数所在的地址, 然后 F5 或者 x 命令退回到 windows.
当 syser debugger 再次弹出时,断点在 IRP_MJ_DEVICE_CONTROL 对应的函数上了。
我们发现 MJ_CREATE,MJ_CLOSE,MJ_SHUTDOWN,MJ_DEVICE_CONTROL 这几个函数是一个,其实我们这里只关心应用与驱动的
交互过程,不关系驱动的打开于关闭。这是我们找到 DEVICE_CONTROL 的处理部分,然后在这个处理部分的开始设置一个断点
即可。

我们把断点设置在 IRP_MJ_DEVICE_CONTROL 的处理代码上

dump_wmimmc+3065 处,F5 退回 windows.

Syser 再次被激活时我们可以分析应用与驱动的 DeviceIoControl 调用交互中。
此时的 edx 为 IoControlCode.



此时我们可能关心应用程序在那里调用了 DeviceIoControl API,这时我们只需要通过
几次 F6 或 p ret 命令来跟踪到 应用层即可。通过5,6次的 f6 后,我们看到了下图,
eip 已经回到了 应用层。



这里我们看到 作者并没有直接通过 DeviceIoControl API 来调用。而是自己通过 INT 2e 指令
自己实现了 DeviceIoControl 调用。这样就解释了为什么在 ollydbg 中用 DeviceIoControl 函数
断点停不下来的问题。


这样我们就定位到了应用层的 DeviceIoControl 函数的位置.这样我们就可以把断点设置在这里,哈哈
朋友们很简单吧.
F5 让我们继续吧.

syser 再次在驱动的 IRP_MJ_DEVICE_CONTROL 的断点处被激活。
这次的 IoControlCode = 84020038,我们通过 f8 或 t 命令单步跟踪这个 ioctrl.
我们看到 DeviceIoControl 的 InputBuffer 的长度是 1c 也就是 7 个dword.
我们看一下 InputBuffer 的数据.


再次断到的 IoControlCode = 84020014 ,这个 IoControlCode 的输入数据的长度是6c
我们在数据窗口来查看输入数据,我们可以功过 wd + 命令来增加一个数据窗口, syser debugger
最多支持 10 个数据窗口,同样也可以通过 wc + 命令来增加一个反汇编窗口,syser debugger 最多
支持10个反汇编窗口.



我们使用 ctrl+2 切换到大控制台窗口,



我们再次断到 IoControlCode = 84020020, 我们这时已经是轻车熟路了,看到 InputBufferLength=44
我们来看一些输入数据 ,这个 iocontrolcode 很关键



这部分代码用来防止关键函数被 hook,以及恢复原始的 windows int 1的中断处理函数. 这样就让 ring 0 的调试器失效

所以这部分代码我们要做处理啊. 不然我们就不能继续调试了

[COLOR="Red"]接下来的代码将要对被加密的代码段进行解密。
这里我们就必须耐心的进行分析,经过分析,我们在
dump_wmimmc+1f1d处设置一个断点。 F5 让我们继续把。
对 dump_wmimmc+1892 到 dump_wmimmc+1e3d 这长度是 5ac 的代码进行
解密。[/COLOR](注意: 现在很多程序在解密过成中都会读取一些可能被下断点的关键代码处数据来做
解密密钥,如果你正好在这个地方设置了cc 的代码断点,可能就中招了,当然了这个程序我到没有主要
到作者是否使用了这些技巧,来扰乱跟踪.所以这里我建议大家使用 bpmb[w|d]这种硬件断点的方式来
设置断点)

当断点在次被激活在 dump_wmimmc+1f1d 的时候,我们发现机密已经完成,
这个时候我们就可以把这段被解密的数据用 dump 命令保存到一个文件.
dump 命令会保存这个命令执行之前内存中数据的快照,DUMP命令是延迟执行的,也就是驱动开发中的 dpc 概念,
这个大家可以参考一下DDK的文当,



















待续....



Syser Debugger 1.8 版发布(2007.5.1)

http://www.sysersoft.com

1. 修改了 bpx 命令,bpx createfilea 这类断点在所有进程中有效.
2. 完善了原代码调试中的 Watch 命令。
3. 增加了 watch,file,table 命令,用来支持原代码调试
4. 增加了 MakePE 命令,保存内存中的 PE 到文件中。
5. 增加了 dump 命令,存储内存中的信息到文件中
6. 增加了内存搜索操作对话框
7. 修改了 Syser Loader 中的bug
8. 提供了对 ALPS 触摸板的支持
9. 提供了对 vc2005 的 pdb 文件格式的支持
10. 优化了 sds 符号文件结构,提高性能
11. 修改了 syserboot.sys 文件被 McAfee 误报病毒的问题

posted on 2007-05-14 01:08 叶子 阅读(4630) 评论(0)  编辑 收藏 引用 所属分类: 技术研究


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理