逆向一个直接IO硬盘的驱动

【文章标题】: 逆向一个直接IO硬盘的驱动
【文章作者】: prince
【作者邮箱】: cracker_prince@163.com
【作者QQ号】: 812937
【软件名称】: SectorOperator.sys
【下载地址】: http://bbs.pediy.com/showthread.php?s=&threadid=30708
【加壳方式】: 无
【编写语言】: ---
【使用工具】: IDA 5.0
【操作平台】: WINDOWS XP
【软件介绍】: 利用驱动直接IO硬盘
【作者声明】: 水平有限,了解不多,仅作参考。
--------------------------------------------------------------------------------
【前言】
  对直接IO硬盘比较感兴趣,找到了这个程序看了看,作者的办法有限制,只能正确操作第1-63个sector,原因未知,希望哪位大侠可以指点一下。现在的硬盘已经逐渐突破了几个级别容量的限制,所以新的协议应该也可以利用来正确IO硬盘,大家可以研究研究。本人纯属入门级选手,所以各位看到有什么解释的不妥或者直接让您喷饭地方,还请不吝赐教,

谢谢。
 
【详细过程】
  IDA载入驱动,可以很清楚地找到关键部分,其他地方见源码:

---------------------------------------------------------------------------
.text:004010F9 ; *************** S U B R O U T I N E ***************************************
.text:004010F9
.text:004010F9 ; Attributes: bp-based frame
.text:004010F9
.text:004010F9 ; int __stdcall sub_4010F9(int,PIRP Irp)
.text:004010F9 sub_4010F9     proc near           ; DATA XREF: start+24o
.text:004010F9
.text:004010F9 var_438       = dword ptr -438h
.text:004010F9 var_434       = byte ptr -434h
.text:004010F9 var_430       = byte ptr -430h
.text:004010F9 var_42C       = dword ptr -42Ch
.text:004010F9 var_22C       = dword ptr -22Ch
.text:004010F9 var_228       = byte ptr -228h
.text:004010F9 var_224       = byte ptr -224h
.text:004010F9 var_220       = dword ptr -220h
.text:004010F9 var_20       = dword ptr -20h
.text:004010F9 var_1C       = dword ptr -1Ch
.text:004010F9 var_18       = dword ptr -18h
.text:004010F9 var_14       = dword ptr -14h
.text:004010F9 var_10       = dword ptr -10h
.text:004010F9 var_C       = dword ptr -0Ch
.text:004010F9 var_8       = dword ptr -8
.text:004010F9 var_4       = dword ptr -4
.text:004010F9 Irp         = dword ptr 0Ch
.text:004010F9
.text:004010F9           push   ebp
.text:004010FA           mov   ebp, esp
.text:004010FC           sub   esp, 438h
.text:00401102           push   ebx
.text:00401103           push   esi
.text:00401104           push   edi
.text:00401105           mov   [ebp+var_18], 0C0000010h ; var_18 = STATUS_INVALID_DEVICE_REQUEST (0xC0000010)
.text:0040110C           mov   eax, [ebp+Irp]
.text:0040110F           mov   ecx, [eax+60h] ; ecx = IrpStack
.text:0040110F                           ; from wdm.h:
.text:0040110F                           ; #define IoGetCurrentIrpStackLocation( Irp ) ( (Irp)->Tail.Overlay.CurrentStackLocation )
.text:00401112           mov   [ebp+var_8], ecx ; var_8 = IrpStack
.text:00401115           mov   edx, [ebp+var_8]
.text:00401118           mov   eax, [edx+0Ch] ; eax = IrpStack->Parameters.DeviceIoControl.IoControlCode
.text:0040111B           mov   [ebp+var_4], eax ; var_4 = dwControlCode
.text:0040111E           mov   ecx, [ebp+Irp]
.text:00401121           mov   edx, [ecx+0Ch] ; edx = Irp->AssociatedIrp.SystemBuffer
.text:00401124           mov   [ebp+var_1C], edx ; var_1C = Irp->AssociatedIrp.SystemBuffer
.text:00401127           mov   eax, [ebp+var_8]
.text:0040112A           mov   ecx, [eax+8]   ; ecx = IrpStack->Parameters.DeviceIoControl.InputBufferLength
.text:0040112D           mov   [ebp+var_14], ecx ; var_14 =
.text:0040112D                           ; IrpStack->Parameters.DeviceIoControl.InputBufferLength
.text:00401130           mov   edx, [ebp+var_8]
.text:00401133           mov   eax, [edx+4]   ; eax =
.text:00401133                           ; IrpStack->Parameters.DeviceIoControl.OutputBufferLength
.text:00401136           mov   [ebp+var_C], eax ; var_C =
.text:00401136                           ; IrpStack->Parameters.DeviceIoControl.OutputBufferLength
.text:00401139           mov   byte ptr [ebp+var_10], 1 ; var_10 = 1
.text:00401139                           ; 读写操作标志
.text:0040113D           mov   ecx, [ebp+var_4] ; ecx = dwControlCode
.text:00401140           mov   [ebp+var_438], ecx ; var_438 = dwControlCode
.text:00401146           cmp   [ebp+var_438], 2220C0h ; dwControlCode == 0x2220c0 ? (写操作)
.text:00401150           jz     short loc_401167 ; 相等则跳走
.text:00401150
.text:00401152           cmp   [ebp+var_438], 2220C4h ; dwControlCode == 0x2220c4 ? (读操作)
.text:0040115C           jz     loc_401216     ; 相等则跳走
.text:0040115C
.text:00401162           jmp   loc_4012C7     ; 直接跳走返回
.text:00401162
.text:00401167 ; ---------------------------------------------------------------------------
.text:00401167
.text:00401167 loc_401167:                   ; CODE XREF: sub_4010F9+57j
.text:00401167           cmp   [ebp+var_14], 202h ; InputBufferLength == 0x202 ?
.text:0040116E           jnz   loc_401211     ; 不相等则跳走返回
.text:0040116E
.text:00401174           cmp   [ebp+var_C], 0 ; OutputBufferLength == 0 ?
.text:00401178           jnz   loc_401211     ; 不相等则跳走返回
.text:00401178
.text:0040117E           mov   edx, [ebp+var_1C]
.text:00401181           mov   [ebp+var_20], edx ; var_20 = Irp->AssociatedIrp.SystemBuffer
.text:00401184           mov   eax, [ebp+var_20]
.text:00401187           mov   cl, [eax]
.text:00401189           mov   [ebp+var_224], cl ; var_224 = SystemBuffer中的数据
.text:0040118F           mov   edx, [ebp+var_20]
.text:00401192           movsx   eax, byte ptr [edx+1] ; 下面的写操作部分不写注释了,参见读过程
.text:00401196           neg   eax
.text:00401198           sbb   eax, eax
.text:0040119A           and   eax, 10h
.text:0040119D           add   eax, 0A0h
.text:004011A2           mov   [ebp+var_228], al
.text:004011A8           mov   esi, [ebp+var_20]
.text:004011AB           add   esi, 2
.text:004011AE           mov   ecx, 80h
.text:004011B3           lea   edi, [ebp+var_220]
.text:004011B9           rep movsd
.text:004011BB           mov   dx, 1F6h
.text:004011BF           mov   al, [ebp+var_228]
.text:004011C5           out   dx, al       ; AT hard disk controller:
.text:004011C5                           ; Drive & Head.
.text:004011C5                           ; Read/Write: bits indicate head, drive for operation
.text:004011C6           mov   dx, 1F2h
.text:004011CA           mov   al, 1
.text:004011CC           out   dx, al       ; AT hard disk controller:
.text:004011CC                           ; Sector count.
.text:004011CC                           ; Read/Write count of sectors for operation
.text:004011CD           mov   dx, 1F3h
.text:004011D1           mov   al, [ebp+var_224]
.text:004011D7           out   dx, al       ; AT hard disk controller:
.text:004011D7                           ; Sector number.
.text:004011D7                           ; Read/Write current/starting logical sector number
.text:004011D8           mov   dx, 1F4h
.text:004011DC           mov   al, 0
.text:004011DE           out   dx, al       ; AT hard disk controller:
.text:004011DE                           ; Cylinder high (bits 0-1 are bits 8-9 of 10-bit cylinder number)
.text:004011DF           mov   dx, 1F5h
.text:004011E3           out   dx, al       ; AT hard disk controller:
.text:004011E3                           ; Cylinder low (bits 0-7 of 10-bit cylinder number)
.text:004011E4           mov   dx, 1F7h
.text:004011E8           mov   al, 30h
.text:004011EA           out   dx, al       ; AT hard disk
.text:004011EA                           ; command register:
.text:004011EA                           ; 1?H = Restore to cylinder 0
.text:004011EA                           ; 7?H = Seek to cylinder
.text:004011EA                           ; 2?H = Read sector
.text:004011EA                           ; 3xH = Write sector
.text:004011EA                           ; 50H = Format track
.text:004011EA                           ; 4xH = verify read
.text:004011EA                           ; 90H = diagnose
.text:004011EA                           ; 91H = set parameters for drive
.text:004011EA
.text:004011EB
.text:004011EB loc_4011EB:                   ; CODE XREF: sub_4010F9+F5j
.text:004011EB           in     al, dx       ; AT hard disk
.text:004011EB                           ; status register bits:
.text:004011EB                           ; 0: 1=prev cmd error
.text:004011EB                           ; 2: Corrected data
.text:004011EB                           ; 3: Data Request. Buffer is busy
.text:004011EB                           ; 4: Seek completed
.text:004011EB                           ; 5: Write fault
.text:004011EB                           ; 6: Drive ready (unless bit 4=0)
.text:004011EB                           ; 7: Busy
.text:004011EC           test   al, 8
.text:004011EE           jz     short loc_4011EB
.text:004011EE
.text:004011F0           xor   ecx, ecx
.text:004011F2           mov   cx, 100h
.text:004011F6           lea   esi, [ebp+var_220]
.text:004011FC           mov   dx, 1F0h
.text:00401200           cli
.text:00401201           cld
.text:00401202           rep outsw
.text:00401205           sti
.text:00401206           mov   [ebp+var_18], 0 ; status = NT_SUCCESS (0)
.text:0040120D           mov   byte ptr [ebp+var_10], 0 ; var_10 = 0
.text:0040120D                           ; 表示是写操作
.text:0040120D
.text:00401211
.text:00401211 loc_401211:                   ; CODE XREF: sub_4010F9+75j
.text:00401211                           ; sub_4010F9+7Fj
.text:00401211           jmp   loc_4012C7
.text:00401211
.text:00401216 ; ---------------------------------------------------------------------------
.text:00401216
.text:00401216 loc_401216:                   ; CODE XREF: sub_4010F9+63j
.text:00401216           cmp   [ebp+var_14], 2 ; InputBufferLength == 2 ?
.text:0040121A           jnz   loc_4012C7     ; 不相等则跳走返回
.text:0040121A
.text:00401220           cmp   [ebp+var_C], 200h ; OutputBufferLength == 0x200 ?
.text:00401227           jnz   loc_4012C7     ; 不相等则跳走返回
.text:00401227
.text:0040122D           mov   ecx, [ebp+var_1C] ; ecx = Irp->AssociatedIrp.SystemBuffer
.text:00401230           mov   [ebp+var_22C], ecx ; var_22C = Irp->AssociatedIrp.SystemBuffer
.text:00401236           mov   edx, [ebp+var_22C] ; edx = Irp->AssociatedIrp.SystemBuffer (InputBuffer)
.text:0040123C           mov   al, [edx]     ; edx = *InputBuffer (要读取的扇区号码)
.text:0040123E           mov   [ebp+var_430], al ; var_430 = 目标扇区号
.text:00401244           mov   ecx, [ebp+var_22C]
.text:0040124A           movsx   edx, byte ptr [ecx+1] ; 取InputBuffer的第2个字节 (硬盘号?)
.text:0040124E           neg   edx         ; 取edx补码
.text:00401250           sbb   edx, edx     ; 带借位减法
.text:00401252           and   edx, 10h     ; edx &= 0x10
.text:00401255           add   edx, 0A0h     ; edx += 0xA0
.text:0040125B           mov   [ebp+var_434], dl ;
.text:00401261           mov   al, [ebp+var_434]
.text:00401267           mov   dx, 1F6h     ; 指定0x1f6端口
.text:0040126B           out   dx, al       ; 将计算结果写入0x1f6端口中
.text:0040126B                           ;
.text:0040126B                           ; 1f6h----低四位是起始LBA的bit24-bit27,
.text:0040126B                           ; 第五位是设备选择,0是master,1是slave.
.text:0040126B                           ; 我们读的是master,应设为0,第七位设为1表示使用LBA,
.text:0040126B                           ; 现在硬盘都使用LBA,应置起来。其他两个bit要求为1
.text:0040126B                           ;
.text:0040126B                           ; AT hard disk controller:
.text:0040126B                           ; Drive & Head.
.text:0040126B                           ; Read/Write: bits indicate head, drive for operation
.text:0040126B                           ;
.text:0040126B                           ;
.text:0040126C           mov   al, 1       ; al = 1
.text:0040126E           mov   dx, 1F2h     ; 指定0x1f2端口
.text:00401272           out   dx, al       ; 1f2h----操作的扇区个数
.text:00401272                           ;
.text:00401272                           ; AT hard disk controller:
.text:00401272                           ; Sector count.
.text:00401272                           ; Read/Write count of sectors for operation
.text:00401272                           ;
.text:00401272                           ;
.text:00401273           mov   al, [ebp+var_430] ; al = 目标扇区号
.text:00401279           mov   dx, 1F3h     ; 1f3h----起始LBA的bit0-bit7
.text:0040127D           out   dx, al       ; 设置目标扇区号
.text:0040127D                           ;
.text:0040127D                           ; AT hard disk controller:
.text:0040127D                           ; Sector number.
.text:0040127D                           ; Read/Write current/starting logical sector number
.text:0040127D                           ;
.text:0040127D                           ;
.text:0040127E           xor   al, al       ; al = 0
.text:00401280           mov   dx, 1F4h     ; 1f4h----起始LBA的bit8-bit15
.text:00401284           out   dx, al       ; AT hard disk controller:
.text:00401284                           ; Cylinder high (bits 0-1 are bits 8-9 of 10-bit cylinder number)
.text:00401284                           ;
.text:00401284                           ;
.text:00401285           mov   dx, 1F5h     ; 1f5h----起始LBA的bit16-bit23
.text:00401289           out   dx, al       ; AT hard disk controller:
.text:00401289                           ; Cylinder low (bits 0-7 of 10-bit cylinder number)
.text:00401289                           ;
.text:00401289                           ;
.text:0040128A           mov   al, 20h       ; al = 0x20
.text:0040128C           mov   dx, 1F7h     ; 1F7 disk 0 status
.text:00401290           out   dx, al       ; AT hard disk
.text:00401290                           ; command register:
.text:00401290                           ; 1?H = Restore to cylinder 0
.text:00401290                           ; 7?H = Seek to cylinder
.text:00401290                           ; 2?H = Read sector
.text:00401290                           ; 3xH = Write sector
.text:00401290                           ; 50H = Format track
.text:00401290                           ; 4xH = verify read
.text:00401290                           ; 90H = diagnose
.text:00401290                           ; 91H = set parameters for drive
.text:00401290
.text:00401291
.text:00401291 loc_401291:                   ; CODE XREF: sub_4010F9+19Bj
.text:00401291           in     al, dx       ; 读取0x1f7端口数据
.text:00401291                           ;
.text:00401291                           ; AT hard disk
.text:00401291                           ; status register bits:
.text:00401291                           ; 0: 1=prev cmd error
.text:00401291                           ; 2: Corrected data
.text:00401291                           ; 3: Data Request. Buffer is busy
.text:00401291                           ; 4: Seek completed
.text:00401291                           ; 5: Write fault
.text:00401291                           ; 6: Drive ready (unless bit 4=0)
.text:00401291                           ; 7: Busy
.text:00401292           test   al, 8       ; 是否完成?
.text:00401294           jz     short loc_401291
.text:00401294
.text:00401296           xor   ecx, ecx     ; ecx = 0
.text:00401298           mov   cx, 100h     ; cx = 0x100
.text:0040129C           mov   dx, 1F0h     ; 1F0--存有结果数据
.text:004012A0           lea   edi, [ebp+var_42C]
.text:004012A6           cli               ; 关中断
.text:004012A7           cld               ; 清除方向标志
.text:004012A7                           ;
.text:004012A8           rep insw          
.text:004012A8                           ;
.text:004012AB           sti               ; 开中断
.text:004012AC           mov   ecx, 80h     ; ecx = 0x80
.text:004012B1           lea   esi, [ebp+var_42C] ; esi指向读出的数据
.text:004012B7           mov   edi, [ebp+var_1C] ; var_1C = Irp->AssociatedIrp.SystemBuffer
.text:004012BA           rep movsd           ; 将数据拷贝到SystemBuffer中
.text:004012BC           mov   [ebp+var_18], 0 ; status = NT_SUCCESS (0)
.text:004012C3           mov   byte ptr [ebp+var_10], 1 ; var_10 = 1
.text:004012C3                           ; 表示是读操作
.text:004012C3
.text:004012C7
.text:004012C7 loc_4012C7:                   ; CODE XREF: sub_4010F9+69j
.text:004012C7                           ; sub_4010F9:loc_401211j
.text:004012C7                           ; sub_4010F9+121j
.text:004012C7                           ; sub_4010F9+12Ej
.text:004012C7           cmp   [ebp+var_18], 0 ; 判断操作是否成功?
.text:004012CB           jnz   short loc_4012E4 ; 不成功则跳走
.text:004012CB
.text:004012CD           mov   eax, [ebp+var_10] ; eax = var_10
.text:004012CD                           ; 根据读写操作设置Information长度
.text:004012D0           and   eax, 0FFh
.text:004012D5           neg   eax
.text:004012D7           sbb   eax, eax
.text:004012D9           and   eax, 200h
.text:004012DE           mov   ecx, [ebp+Irp]
.text:004012E1           mov   [ecx+1Ch], eax ; 指定拷贝到User buffer的buffer size
.text:004012E1                           ; Irp->IoStatus.Information =
.text:004012E1
.text:004012E4
.text:004012E4 loc_4012E4:                   ; CODE XREF: sub_4010F9+1D2j
.text:004012E4           mov   edx, [ebp+Irp]
.text:004012E7           mov   eax, [ebp+var_18]
.text:004012EA           mov   [edx+18h], eax ; Irp->IoStatus.Status = status
.text:004012ED           xor   dl, dl       ; PriorityBoost
.text:004012EF           mov   ecx, [ebp+Irp] ; Irp
.text:004012F2           call   ds:IofCompleteRequest ; complete Irp
.text:004012F8           mov   eax, [ebp+var_18] ; 返回status
.text:004012FB           pop   edi
.text:004012FC           pop   esi
.text:004012FD           pop   ebx
.text:004012FE           mov   esp, ebp
.text:00401300           pop   ebp
.text:00401301           retn   8
.text:00401301
.text:00401301 sub_4010F9     endp


--------------------------------------------------------------------------------
【总结】
    以上是很清晰的0x1f0 - 0x1f7的端口操作过程,未列出的端口或者想了解更详细的信息请自己Google吧。
   源代码见附件。

硬盘篇1-IDE硬盘的直接IO

对硬盘进行操作的常用端口是1f0h~1f7h号端口,各端口含义如下:
端口号 读还是写 具体含义
1F0H 读/写 用来传送读/写的数据(其内容是正在传输的一个字节的数据)
1F1H 读 用来读取错误码
1F2H 读/写 用来放入要读写的扇区数量
1F3H 读/写 用来放入要读写的扇区号码
1F4H 读/写 用来存放读写柱面的低8位字节
1F5H 读/写 用来存放读写柱面的高2位字节(其高6位恒为0)
1F6H 读/写 用来存放要读/写的磁盘号及磁头号
第7位 恒为1
第6位 恒为0
第5位 恒为1
第4位 为0代表第一块硬盘、为1代表第二块硬盘
第3~0位 用来存放要读/写的磁头号
1f7H 读 用来存放读操作后的状态
第7位 控制器忙碌
第6位 磁盘驱动器准备好了
第5位 写入错误
第4位 搜索完成
第3位 为1时扇区缓冲区没有准备好
第2位 是否正确读取磁盘数据
第1位 磁盘每转一周将此位设为1,
第0位 之前的命令因发生错误而结束
写 该位端口为命令端口,用来发出指定命令
为50h 格式化磁道
为20h 尝试读取扇区
为21h 无须验证扇区是否准备好而直接读扇区
为22h 尝试读取长扇区(用于早期的硬盘,每扇可能不是512字节,而是128字节到1024之间的值)
为23h 无须验证扇区是否准备好而直接读长扇区
为30h 尝试写扇区
为31h 无须验证扇区是否准备好而直接写扇区
为32h 尝试写长扇区
为33h 无须验证扇区是否准备好而直接写长扇区
注:当然看完这个表你会发现,这种读写端口的方法其实是基于磁头、柱面、扇区的硬盘读写方法,不过大于8G的硬盘的读写方法也是通过端口1F0H~1F7H来实现的^_^

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值