f97a42f6 884517 mov byte ptr [ebp+17h],al
f97a42f9 ff155c947af9 call dword ptr
[atapi!_imp__KeSynchronizeExecution]
………………
CallIdeStartIoSynchronized 将 atapi 生成的设备对像传递给了
KeSynchronizeExecutio 的第三个参数。那么应该不难想到验证 KeSynchronizeExecution
的第三个参数判断是否是atapi生成的设备,从而确定是否是atapi的调用。到这里,我们
离成功已经不远了。
首先,要得到atapi生成的设备对象,这个不难,直接给出代码:
RtlInitUnicodeString( &drv_name, L"\\Driver\\atapi");
status = ObReferenceObjectByName(&drv_name ,
OBJ_CASE_INSENSITIVE ,
NULL ,
0,
*IoDriverObjectType ,
KernelMode ,
NULL ,
(PVOID*)&atapi_drv);
atapi_dev = atapi_drv->DeviceObject;
while( atapi_dev )
{ g_dev[g_dev_count] = (ULONG)atapi_dev;
atapi_dev = atapi_dev->NextDevice;
g_dev_count++;
}
然后要 hook KeSynchronizeExecution,InlineHook的代码这里不给出,详细请看随刊
源码。下面给出KeSynchronizeExecution中的代码:
__asm
{
push eax
push ecx
mov eax, [esp+14h] //KeSynchronizeExecution的第三个参数
xor ecx,ecx
laba1:
cmp eax, [g_dev+ecx*4]
jz laba2
inc ecx
cmp ecx, 4
jz laba3
jnz laba1
laba2:
mov eax, [esp+10h]
mov g_orig_ide_addr, eax
call find_atapi //特征搜索函数
laba3:
pop ecx
pop eax
push ebx
mov ebx,dword ptr [esp+8]
jmp g_orig_ke_addr
}
在 find_atapi里进行特征搜索后,再次调用inlinehook代码对AtapiStartIo进行hook,
同样的,这里略过inlinehook的代码,让我们来看看自己实现的AtapiStartIo代码:
BOOLEAN
fake_AtapiStartIo( PVOID devext_add_ach,
struct _SCSI_REQUEST_BLOCK* srb
)
{
ULONG max,min;
max = 6290256+57;
min = 6290256;
if( srb->QueueSortKey <= max &&
srb->QueueSortKey >= min)
{
KdBreakPoint();
}
return orig_AtapiStartIo(devext_add_ach, srb);
}
如果读者对上期的《atapi层禁止特定扇区的读写》还有印象的话,我想这段代码应该
不难理解了。在对扇区 6290256 开始后的 57 个扇区之内的访问,都会中断下来。而这个扇
区是笔者本地磁盘上的一个文件所在的扇区。关于如何取得文件所在的扇区。
本文所有代码在XPSP3+WDK中编译通过,并在XPSP3上成功运行。另如读者要进行文件
删除保护的话,还要把NTFS中文件对应的MFT保护起来,这于NTFS的结构相关,这里不论。
希望本文起到抛砖引玉的作用,期待更精彩的文章出现。行文仓促,纰漏难免,欢迎批评指
正。
|