关于文件的保护的话题,笔记在前几期的黑防中进行了一些个人的分析,根据IRP的下
发流程,从系统的文件驱动ntfs.sys到atapi.sys的dispatch hook和深度的AtapiStartIo
hook,共记三篇。可以说,从 IRP 发送到文件驱动开始,到下发至 atapi 的 dispatch,以
及 atapi 的一些内部处理都大致讲了一遍。
如果读者没有忘记前面几期的内容,那么应该知道 atapi 后是在 HAL.DLL 中进行端口
IO 的处理了,那么本次笔者就带大家来初步的了解 HAL 中所做的一些工作,以及如何自己
实现直接的端口IO,从而绕过 atapi这层驱动。
如果读者还记得第6期《Atapi的深度 HOOK》一文的内容,那么就会知道IdeReadWrite
这个函数起着“承上启下”的作用,这个函数的“下方”就是IO端口的操作了,而“上方”
则是 atapi 层。那么要了解如何实现直接端口 IO,这个函数对我们来说是至关重要的。首
先这个函数的原型是:
NTSTATUS IdeReadWrite(UCHAR devExt_ach, PVOID Srb)
下面给出一些关键的汇编代码:
.text:00011239 push dword ptr [esi+24h] ; 0x1F7,状态
寄存器
.text:0001123C call ds:__imp__READ_PORT_UCHAR@4 ;
.text:00011242 test al, al
.text:00011244 jns short loc_1124D
……
.text:0001124D loc_1124D: ; CODE XREF:
.text:0001124D test al, 40h ; 测试第6位(准备
位)
.text:0001124F jnz short loc_11263
……
.text:00011263
.text:00011263 loc_11263: ; CODE XREF:
IdeReadWrite(x,x)+3Dj
.text:00011263 mov eax, [edi+18h] ; 设备可以接受命令
.text:00011266 mov [esi+84h], eax
.text:0001126C mov eax, [edi+10h]
.text:0001126F mov [esi+88h], eax
.text:00011275 mov byte ptr [esi+0C4h], 1
.text:0001127C mov eax, [edi+10h] ;
Srb.DataTransferLength
.text:0001127F add eax, 1FFh
.text:00011284 shr eax, 9 ; 除以 512,扇区大
小
.text:00011287 push eax ; Value
.text:00011288 push dword ptr [esi+10h] ; Port = 0x1F2
.text:0001128B call ebx ; WRITE_PORT_UCHAR(x,x) ; 写
扇区计数寄存器
……
.text:000112A7 mov dword ptr [ebp+devExt_ach], eax ;
从 CDB指令中算出起始扇区 |