发布时间:2025-12-09 16:51:48 浏览次数:5
hook的是DeviceIoControl,DeviceIoControl 将控制代码直接发送到指定的设备驱动程序,使相应的设备执行相应的操作,我们先看看这个API参数
.版本 2.DLL命令 DeviceIoControl, 逻辑型, "kernel32", "DeviceIoControl".参数 hDevice, 整数型.参数 dwIoControlCode, 整数型.参数 lpInBuffer, 整数型.参数 nInBufferSize, 整数型.参数 lpOutBuffer, 整数型.参数 nOutBufferSize, 整数型.参数 lpBytesReturned, 整数型.参数 lpOverlapped, 整数型注入器
视频教程采用了EIP注入方式,注入后,磁盘序列号会随机生成。
参数:
hDevice [in]
需要执行操作的设备句柄。该设备通常是卷,目录,文件或流,使用 CreateFile 函数打开获取设备句柄。具体的见备注
dwIoControlCode [in]
操作的控制代码,该值标识要执行的特定操作以及执行该操作的设备的类型,有关控制代码的列表,请参考备注。每个控制代码的文档都提供了lpInBuffer,nInBufferSize,lpOutBuffer和nOutBufferSize参数的使用细节。
lpInBuffer [in, optional]
(可选)指向输入缓冲区的指针。这些数据的格式取决于dwIoControlCode参数的值。如果dwIoControlCode指定不需要输入数据的操作,则此参数可以为NULL。
nInBufferSize [in]
输入缓冲区以字节为单位的大小。单位为字节。
lpOutBuffer [out, optional]
(可选)指向输出缓冲区的指针。这些数据的格式取决于dwIoControlCode参数的值。如果dwIoControlCode指定不返回数据的操作,则此参数可以为NULL。
nOutBufferSize [in]
输出缓冲区以字节为单位的大小。单位为字节。
lpBytesReturned [out, optional]
(可选)指向一个变量的指针,该变量接收存储在输出缓冲区中的数据的大小。如果输出缓冲区太小,无法接收任何数据,则GetLastError返回ERROR_INSUFFICIENT_BUFFER,错误代码122(0x7a),此时lpBytesReturned是零。
如果输出缓冲区太小而无法保存所有数据,但可以保存一些条目,某些驱动程序将返回尽可能多的数据,在这种情况下,调用失败,GetLastError返回ERROR_MORE_DATA,错误代码234,lpBytesReturned指示接收到的数据量。您的应用程序应该再次使用相同的操作调用DeviceIoControl,指定一个新的起点。
如果lpOverlapped为NULL,则lpBytesReturned不能为NULL。 即使操作没有返回输出数据并且lpOutBuffer为NULL,DeviceIoControl也会使用lpBytesReturned。在这样的操作之后,lpBytesReturned的值是没有意义的。
如果lpOverlapped不为NULL,则lpBytesReturned可以为NULL。 如果此参数不为NULL并且操作返回数据,则在重叠操作完成之前,lpBytesReturned是无意义的。要检索返回的字节数,请调用GetOverlappedResult,如果hDevice与I / O完成端口相关联,则可以检索通过调用GetQueuedCompletionStatus返回的字节数。
lpOverlapped [in, out, optional]
(可选)指向OVERLAPPED结构的指针,
如果在未指定FILE_FLAG_OVERLAPPED的情况下打开hDevice,则忽略lpOverlapped。
如果使用FILE_FLAG_OVERLAPPED标志打开hDevice,则该操作将作为重叠(异步)操作执行。在这种情况下,lpOverlapped必须指向包含事件对象句柄的有效OVERLAPPED结构。 否则,该功能将以不可预知的方式失败。
对于重叠操作,DeviceIoControl会立即返回,并在操作完成时通知事件对象。 否则,该功能在操作完成或发生错误之前不会返回。
返回值:
如果操作成功完成,DeviceIoControl将返回一个非零值。
如果操作失败或正在等待,则DeviceIoControl返回零。 要获得扩展的错误信息,请调用GetLastError。
磁盘序列号获取
我们先封装一个模块,然后采用这个命令来获取磁盘序列号
.版本 2.子程序 取磁盘序列号, 文本型, 公开.参数 硬盘序号, 字节型, , 硬盘的序号,从0开始。.局部变量 hDisk, 整数型, , , 设备打开后的句柄.局部变量 cBR, 整数型.局部变量 sip, SCIP.局部变量 sop, 字节型, , "532".局部变量 bDM, 字节型.局部变量 序列号, 文本型.局部变量 i, 整数型hDisk = CreateFile (“\\.\PhysicalDrive” + 到文本 (硬盘序号), -1073741824, 0, 0, 3, 0, 0).如果 (hDisk ≠ -1)sip.irDriveRegs.bDriveHeadReg = 160sip.irDriveRegs.bCommandReg = 236' 对设备进行操作.如果真 (DeviceIoControl (hDisk, 508040, sip, 32, sop [1], 528, cBR, 0) ≠ 0)' 复制内存CopyMemory (DiskInfo, sop [1], 90)' 取序列号.变量循环首 (1, 取数组成员数 (DiskInfo.sSerialNumber), 2, i)序列号 = 序列号 + 字符 (DiskInfo.sSerialNumber [i + 1])序列号 = 序列号 + 字符 (DiskInfo.sSerialNumber [i])处理事件 ().变量循环尾 ()' 对取出的序列号进行处理序列号 = 删全部空 (序列号).如果真结束CloseHandle (hDisk).否则信息框 (“打开硬盘失败,请以管理员权限运行本程序!”, #错误图标, “错误”, ).如果结束' 关闭打开的设备CloseHandle (hDisk)' 将序列号返回给调用方返回 (序列号)
注入hook
我们采用注入的方式
h.安装Hook (“kernel32.dll”, “DeviceIoControl”, 到整数 (&MyDeviceDisk))h.开始Hook ()MyDeviceDisk回调函数
.版本 2.子程序 MyDeviceDisk, 逻辑型, 公开.参数 hDisk, 整数型.参数 dwIoControlCode, 整数型.参数 lpInBuffer, 整数型.参数 nInBufferSize, 整数型.参数 lpOutBuffer, 整数型.参数 nOutBufferSize, 整数型.参数 lpBytesReturned, 整数型.参数 lpOverlapped, 整数型.局部变量 tmp, 字节型, , "20".局部变量 i, 整数型j = j + 1.如果 (j % 2 = 1)h.停止Hook ()DeviceIoControl (hDisk, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped)h.开始Hook ().否则重定义数组 (tmp, 假, 20).计次循环首 (20, i)tmp [i] = 取代码 (取文本中间 (“0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ”, 取随机数 (1, 36), 1), ).计次循环尾 ()h.停止Hook ()DeviceIoControl (hDisk, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped)h.开始Hook ()' 上面必须重新调用一次DeviceIoControl这个API,因为原程序后面的代码中有用到lpOutBuffer偏移0X6和偏移0X78里的数值,如果不调用这个API而是直接写内存,那么会导致程序出错引起SEH弹出信息框,所以必须先填充好lpOutBuffer,再改变需要改变的地方写到内存 (tmp, lpOutBuffer + 40, 20).如果结束返回 (真)源码:http://www.511yj.com/eyuyan-hook-81.html