易语言API HOOK DeviceIOControl修改磁盘序列号

DeviceIoControl

.版本 2
.DLL命令 DeviceIoControl, 逻辑型, "kernel32", "DeviceIoControl"
    .参数 hDevice, 整数型
    .参数 dwIoControlCode, 整数型
    .参数 lpInBuffer, 整数型
    .参数 nInBufferSize, 整数型
    .参数 lpOutBuffer, 整数型
    .参数 nOutBufferSize, 整数型
    .参数 lpBytesReturned, 整数型
    .参数 lpOverlapped, 整数型

参数:

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 = 160
    sip.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 % 21)
    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)
.如果结束
返回 (真)

注入器

视频教程采用了EIP注入方式,注入后,磁盘序列号会随机生成。

511遇见

教程获取下载:


发布日期:

所属分类: 易语言 标签: