好友
阅读权限 40
听众
最后登录 1970-1-1
ps520
发表于 2009-12-31 23:28
[ 破文标题 ] OllyDbg 提取驱动调用信息[LCG]
[ 破文作者 ] Luck[LCG]
[ 作者邮箱 ] admin@sooluck.cn
[ 作者主页 ] www.sooluck.cn
[ 破解 工具 ] OllyDbg
[ 破解平台 ] Win xp Sp2
-----------------------------------------------------
[ 破解过程 ]-----------------------------------------
本文主要讲解了提取驱动调用所需信息并为我所用的过程。
首先,我们要了解驱动的加载机制。
以易语言驱动加载模块的标准模式为例[驱动加载方式还有另一种,这里我们不做介绍。]。易语言的加载流程:
.版本 2
hSCManager = OpenSCManagerA (字符 (0), 字符 (0), #SC_MANAGER_CREATE_SERVICE)
.如果真 (hSCManager = 0)
返回 (-1)
.如果真结束
hService = CreateServiceA (hSCManager, 服务名, 显示名, #SERVICE_START, #SERVICE_KERNEL_DRIVER, #SERVICE_DEMAND_START, #SERVICE_ERROR_IGNORE, 驱动路径, 0, 0, 0, 0, 0)
.如果真 (hService = 0)
hService = OpenServiceA (hSCManager, 服务名, #SERVICE_START)
.如果真 (hService = 0) ' 调用CreateService注册服务失败!
CloseServiceHandle (hSCManager)
返回 (-1)
.如果真结束
.如果真结束
StartServiceA (hService, 0, 0)
CloseServiceHandle (hService)
CloseServiceHandle (hSCManager)
hDevice = CreateFileA (驱动名, #GENERIC_READ + #GENERIC_WRITE, 0, 0, #OPEN_EXISTING, 0, 0)
返回 (hDevice) ' 返回驱动句柄
可以看出,其实我们只需要填写:
驱动路径、服务名、显示名、驱动名
在调用Api CreateServiceA 的时候,提供了服务名、显示名、驱动路径,驱动名是由CreateFileA提供的。于是基本了解如何加载驱动了。
OllyDbg加载被提取的EXE文件,然后bp CreateFileA和CreateServiceA。F9。
首先被拦截下的是:
CreateServiceA
0012FBA8 00404156 /CALL to CreateServiceA from 穿墙挂.00404151
0012FBAC 0016F380 |hManager = 0016F380
0012FBB0 0040316C |ServiceName = "ialdnwxf" ;服务名
0012FBB4 0040316C |DisplayName = "ialdnwxf" ;显示名
0012FBB8 00000010 |DesiredAccess = SERVICE_START
0012FBBC 00000001 |ServiceType = SERVICE_KERNEL_DRIVER
0012FBC0 00000003 |StartType = SERVICE_DEMAND_START
0012FBC4 00000000 |ErrorControl = SERVICE_ERROR_IGNORE
0012FBC8 00164298 |BinaryPathName = "C:\Documents and Settings\Administrator\",D7,"烂鎈beep.sys" ;驱动路径
0012FBCC 00000000 |LoadOrderGroup = NULL
0012FBD0 00000000 |pTagId = NULL
0012FBD4 00000000 |pDependencies = NULL
0012FBD8 00000000 |ServiceStartName = NULL
0012FBDC 00000000 \Password = NULL
取消断点,再F9。
0012FBC0 0040427A /CALL to CreateFileA from 穿墙挂.00404275
0012FBC4 0040315F |FileName = "\\.\ialdnwxf" ;驱动名
0012FBC8 C0000000 |Access = GENERIC_READ|GENERIC_WRITE
0012FBCC 00000000 |ShareMode = 0
0012FBD0 00000000 |pSecurity = NULL
0012FBD4 00000003 |Mode = OPEN_EXISTING
0012FBD8 00000000 |Attributes = 0
0012FBDC 00000000 \hTemplateFile = NULL
这样我们就过了驱动加载的这关。
别激动,这才是最简单的一步!
接下来就是最麻烦的了……因为有个地方对我而言有点难。
加载成功了,我们就需要对调用驱动的地方进行收拾了。
DeviceIoControl是用来调用驱动功能的,所以,我们再bp DeviceIoControl。
我们需要在DeviceIoControl里提取的有两个,A是控制码,B是输入数据。
0012F608 00404960 /CALL to DeviceIoControl from 穿墙挂.0040495B
0012F60C FFFFFFFF |hDevice = FFFFFFFF
0012F610 00222005 |IoControlCode = 222005 ;控制码
0012F614 0016C8C8 |InBuffer = 0016C8C8 ;输入数据
0012F618 0000000C |InBufferSize = C (12.) ;输入数据长度
0012F61C 00000000 |OutBuffer = NULL
0012F620 00000000 |OutBufferSize = 0
0012F624 00000000 |pBytesReturned = NULL
0012F628 001723B8 \pOverlapped = 001723B8
IoControlCode是16进制,用计算器转换下就OK了,但是0016C8C8这里却是一个地址。让你郁闷了吧?
的确,我当初也不知道怎么过,知道写这篇文章时才想到可以这样来提取。
Let's Go!
让我们看看驱动调用的源码。
.版本 2
内存结构.进程ID = 进程ID
内存结构.内存地址 = 内存地址
内存结构.欲写入值 = 转换十六到十 (欲写入值)
内存结构地址 = lstrcpyn_内存结构 (内存结构, 内存结构, 0)
.如果 (与驱动程序通信_ (设备句柄, 2236421, 内存结构地址, 12, 0, 0) ≠ 0)
返回 (真)
.否则
返回 (假)
也就是说在驱动调用之前将要输入的数据通过一个数据类型全部入栈,然后通过lstrcpyn取变量的地址。我们就可以由此推出,找到调用驱动写内存的call,往上一定有数据入栈的信息,那么一顶可以通过Pid等信息来模拟出那个数据类型。
再bp DeviceIoControl。
0012F608 00404960 /CALL to DeviceIoControl from 穿墙挂.0040495B
Call来自0040495B。所以取消断点,F9.Ctrl+G,输入0040495B。
向上翻,果然有push。
哈哈,在最前面下断,然后再次执行。
断下后一步一步,关注堆栈窗口的数据输出。请注意,这时候所有的数据全都为16进制,还需要通过自己翻译为十进制。
这样我们就成功提取了所有的调用驱动所需信息,我们也就可以自己写程序调用这个驱动了。我们的教程也到此为止。
大家可以自己找个加载驱动了的程序来反汇编。用OD提取关键信息,然后自己调用!
[ 破解总结 ]-----------------------------------------
对于加载驱动的, 要搞清楚它的加载模式。
比如我们这个就是常规的加载方法,有的却很猥琐……
总结下断点:
A.bp CreateServiceA ;获取服务名、显示名、驱动路径
B.bp CreateFileA ;获取驱动的驱动名
C.bp DeviceIoControl ;获取控制码及输入数据。通过Call from追溯数据的类型
呵呵,最后祝各位元旦快乐!
LCG小菜鸟:Luck
-----------------------------------------------------
[ 版权声明 ] 本文原创作者为:Luck[LCG],转载请注明作者和来源。谢谢合作!
-----------------------------------------------------
免费评分
查看全部评分
发帖前要善用【论坛搜索 】 功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。