关于IOCTL_HID_GET_STRING和ProbeForWrite

用户模式也就是通常说的应用程序调用以下函数:

HidD_GetManufacturerString

HidD_GetProductString

HidD_GetSerialNumberString

会生成对应IRP给内核模式的hidclass.sys,其CTL_CODE分别为

IOCTL_HID_GET_MANUFACTURER_STRING

IOCTL_HID_GET_PRODUCT_STRING

IOCTL_HID_GET_SERIALNUMBER_STRING

而后hidclass.sys会调用mini驱动,CTL_CODE均为

IOCTL_HID_GET_STRING

这是老衲跟踪调试发现的. 不过有个问题,很多文献,材料,书籍,stuff,what ever,都用类似的方法:

PIO_STACK_LOCATION IrpStack;
USHORT wStrId = ((PUSHORT)IrpStack->Parameters.DeviceIoControl.Type3InputBuffer)[0];
LANGID wLngId = ((PUSHORT)IrpStack->Parameters.DeviceIoControl.Type3InputBuffer)[1];    // also USHORT

当我执行是,我得到了这个,很完美,性感,让人热血澎湃的画面:

蓝屏代码 0x0000008E微软的MSDN说明是: KERNEL_MODE_EXCEPTION_NOT_HANDLED 内核模式异常未处理

代码 0xC0000005则是STATUS_ACCESS_VIOLATION, 这个在用户模式下一般是弹出一个 xxxx指令引用 xxxx内存 该内存不能为xxxx

几经挣扎, 回头仔细查看MSDN发现了答案, 思想里又回想多年前战地二小队长的无线电: 不能这么做!

Parameters.DeviceIoControl.Type3InputBuffer in the I/O stack location of the IRP contains a composite value. The two most significant bytes contain the language ID of the string to be retrieved. The two least significant bytes contain one
of the following three constant values:

  • HID_STRING_ID_IMANUFACTURER
  • HID_STRING_ID_IPRODUCT
  • HID_STRING_ID_ISERIALNUMBER

这个并不是一个指针, 而是两个WORD合成的DWORD, 比如HidD_GetProductString的Type3InputBuffer:

// 0x0409000F   0F 00 09 04 : HID_STRING_ID_IPRODUCT(0x000F) English American ENU(0x0409,MSDN)

于是有了前面的兴奋, 下面就不敢乱来了,至少要确认老婆不在家, 于是我使用内存指针之前都Probe

结果还是异常, 不过可以通过dbgView查看,而不用导致虚拟机崩溃, 使用代码

ProbeForWrite(Irp->UserBuffer, xxx, x);

仍然是0xC0000005 STATUS_ACCESS_VIOLATION, 狠心不Probe居然没有错,中文资料都像金元宝一样噎着藏着等下崽

我只好跑去微软了,结果

Do not use this routine on kernel-mode addresses; it will raise an exception.

If Irp->RequestorMode = KernelMode, the
Irp->AssociatedIrp.SystemBuffer
and Irp->UserBuffer fields do not contain user-mode addresses, and a call to
ProbeForWrite to probe a buffer pointed to by either field will raise an exception.

If Length = 0, ProbeForWrite does no checking of the address. In this case, the routine does not raise an exception for an address that is misaligned or is outside the range of valid user addresses.

还是那句话, 不能这么做!

具体我就不翻译了, 只能传一个用户模式的地址 0x80000000以前的,而不能传递一个内核模式的地址

虽然hidclass的CTL_CODE都是METHOD_NEITHER即直接内存访问,但是传递的地址是内核模式的地址,调试显示0xf7bc5830

看来,这种事情,老婆不在家也不能做啊.

2014-12-01 01:53:09.

大家不要紧张,这只是一个笔记!

时间: 2024-11-03 21:36:40

关于IOCTL_HID_GET_STRING和ProbeForWrite的相关文章

深入学习APC

在NT中,有两种类型的APCs:用户模式和内核模式.用户APCs运行在用户模式下目标线程当前上下文中,并且需要从目标线程得到许可来运行.特别是,用户模式的APCs需要目标线程处在alertable等待状态才能被成功的调度执行.通过调用下面任意一个函数,都可以让线程进入这种状态.这些函数是:KeWaitForSingleObject, KeWaitForMultipleObjects, KeWaitForMutexObject, KeDelayExecutionThread. 对于用户模式下,可以

IRP 与 派遣函数

什么是派遣函数: 派遣函数是 WIndows 驱动程序中的重要概念.驱动程序的主要功能是负责处理I/O请求,其中大部分I/O请求是在派遣函数中处理的.也就是说,派遣函数是用来处理驱动程序提交过来的 I/O 请求. 那什么是 I/O 请求呢? 上层程序与驱动程序之间通信时,上层会发出I/O请求,即输入输出请求包(I/O Request package) 用户模式下(上层)与所有驱动程序之间的I/O请求,全部由操作系统转化为一个叫 IRP 的数据结构,不同的 IRP 会被派遣到不同的派遣函数(Dis

MiniFilter文件系统学习

Minfilter与legacy filter区别 比sfilter加载顺序更易控制. altitude被绑定到合适的位置. Minfilter在注册表服务项中有一项Altitude值 此值越高位置越靠前 (待考证 每一个minifilter驱动必须有一个叫做altitude的唯一标识符.一个minifilter驱动的altitude定义了它加载时在I/O栈中相对其他minifilter驱动的位置.值越小,栈中位置就越低 FSFilter Anti-Virus 320000-329999 此组包

关于个人防火墙的真相

原文作者:MaD 原文标题:The truth aboutpersonal firewalls电子邮件:[email protected]作者国籍:俄罗斯 声明:1.本人翻译水平有限,有不当之请大家理解.如部分看不懂可以和原文对照.            2.欢迎转载,但请不要漏掉原文作者和翻译者的信息.            3.欢迎大家指出我翻译中的错误,我好改正. 内容:         有多种方式来保护你的计算机免受恶意软件的侵害,比如软件防火墙,病毒和Rootkit检 测软件等.所有这

ring0-内存可读、可写、有效性、指针是否为空、深度校验字符串(随手代码)

http://blog.csdn.net/hgy413/article/details/7907057 1.如在ring3下,则要判断是否可读可写: [cpp] view plaincopy KPROCESSOR_MODE PreviousMode; ULONG PID; PreviousMode = ExGetPreviousMode(); // 如果非内核模式,就要开始检查IN的这些参数都否可读 if (PreviousMode != KernelMode) { try { ProbeFor

由枚举模块到ring0内存结构的初步探索

是由获得进程模块而引发的一系列的问题,首先,在ring3层下枚举进程模块有ToolHelp,Psapi,还可以通过在ntdll中获得ZwQuerySystemInformation的函数地址来枚举,其中ZwQueryInformationProcess相当于是调用系统服务函数,其内部实现就是遍历PEB中的Moudle链表, kd> dt _PEB +0x00c Ldr              : Ptr32 _PEB_LDR_DATA kd> dt _PEB_LDR_DATA nt!_PEB

驱动开发之 用DeviceIoControl实现应用程序与驱动程序通信

Ring3测试程序:http://blog.csdn.net/zj510/article/details/8216321 1.readfile和writefile可以实现应用程序与驱动程序通信,另外一个Win32 API 是DeviceIoControl. 应用程序自定义一中IO控制码,然后调用DeviceIoControl函数,IO管理器会产生一个MajorFunction 为IRP_MJ_DEVICE_CONTROL,MinorFunction 为自己定义的控制码的IRP,系统就调用相应的处

CreateFile DeviceIoControl dwIoControlCode——应用程序与驱动程序通信

在"进程内存管理器中"的一个Ring0,Ring3层通信问题,之前也见过这样的代码,这次拆分出来详细总结一下. 先通过CreateFile函数得到设备句柄,CreateFile函数原型: HANDLE CreateFile( LPCTSTR lpFileName, // 文件名/设备路径 设备的名称 DWORD dwDesiredAccess, // 访问方式 DWORD dwShareMode, // 共享方式 LPSECURITY_ATTRIBUTES lpSecurityAttr

内核漏洞,任意地址写任意数据模型

实验环境 xp sp3 此实验将一个不常用的内核函数置0,然后R3申请了0地址的指针,将shellcode拷到此内存,内核并没有做ProbeForRead /Write检查 直接对传入的数据进行了修改,造成了任意地址写任意数据漏洞 ,提权了R3程序为system权限 R3代码 主要获得一个函数的地址,将函数地址传入R0 R0将此函数地址置0,然后R3申请了一个0地址,将shellcode拷到了申请的内存中,然后调用被置0的函数,触发了shellcode // exploit.cpp : Defi