本文禁止转载
经过多日探索,暂时找到了两种比较可靠的提取驱动IOCTL code的途径,以下对具体执行过程进行简介,并针对优缺点进行分析:
- IDA逆向sys方式
操作流程:IDA反汇编具体的.sys文件,使用IDA插件win_driver_plugin可以精确定位至DispatchFunction,然后通过阅读代码提取出IOCTL code.
优点:理论上可以提取出所有的有效IOCTL code值。
缺点:如何通过一个设备名或符号链接名具体定位到sys文件(我是通过内核调试找),另外对于汇编水平以及IDA的操作也有一定要求,对于一些比较复杂的sys文件,本方法查找起来比较困难。 - 脚本遍历
操作流程:调用DeviceIOControl方法对IOCTL Code从0x0-0xffffffff进行遍历,通过检查返回值来判定IOCTL Code是否有效。实践证明本方法可以获得绝大多数有效IOCTL code.
优点:脚本执行,等待即可,操作简便。
缺点:由于某些IOCTL Code的执行对于inputbuffer或者outputbuffer有一定要求,本方法不一定能获得全部的有效IOCTL code值。另外执行时间比较长,我尝试一次遍历大概需要五个多小时(这一点可以在后续对代码进行优化,考虑通过异步IO等方式对代码进行优化,一定程度上应该能节省很多时间)
最后附上遍历脚本:
import ctypes, sys
from ctypes import *
kernel32 = windll.kernel32
hevDevice = kernel32.CreateFileA("\\\\.\\SymbolicNameofDriver", 0xC0000000, 0, None, 0x3, 0, None)
if not hevDevice or hevDevice == -1:
print("*** Couldn't get Device Driver handle.")
sys.exit(0)
inbuf = 'A'*16
outbuf = 'A'*16
bufLength = len(inbuf)
iofile = open("ioctl.txt","wb")
i = 0xffffffff
while i > 0:
a = kernel32.DeviceIoControl(hevDevice, i, inbuf, bufLength, outbuf, bufLength, byref(c_ulong()), None)
if(a != 0):
iofile.write("0x%x"%i)
i-=1
iofile.close()
网友评论