向的结构的第一个元素值,这一分发过程假设设备驱动是通过KsAllocateObjectHeader 来
对KSDISPATCH_TABLE 和FsContext 进行初始化的。动词“假设”可能让人听起来有点惊讶,
但历史上,很多软件多假设了很多事情,比如固定的缓冲区大小,输入……这些最后都导致
了严重漏洞。
其中KSDISPATCH_TABLE 结构如下:
Typedef struct{
PDRIVER_DISPATCH DeviceIoControl; // IRP_MJ_DEVICE_CONTROL
PDRIVER_DISPATCH Read; // IRP_MJ_READ
PDRIVER_DISPATCH Write; // IRP_MJ_WRITE
PDRIVER_DISPATCH Flush; // IRP_MJ_FLUSH
PDRIVER_DISPATCH Close; // IRP_MJ_CLOSE
PDRIVER_DISPATCH QuerySecurity; // IRP_MJ_QUERY_SECURITY
PDRIVER_DISPATCH SetSecurity; // IRP_MJ_SET_SECURITY
PFAST_IO_DEVICE_CONTROL FastDeviceIoControl; //
DriverObject.FastIoDispatch.FastIoDeviceControl
PFAST_IO_READ FastRead; // DriverObject.FastIoDispatch.FastRead
PFAST_IO_WRITE FastWrite; // DriverObject.FastIoDispatch.FastWrite
}KSDISPATCHTABLE, *PKSDISPATCHTABLE;
KsSetMajorFunctionHandler(
IN PDRIVER_OBJECT DriverObject,
IN ULONG MajorFunction
);
KsSetMajorFunctionHandler 十分简单,它为MajorFunction>=0安装合适的 IRP handler,
否则安装FastIo handler。
module ks.sys
[...]
PAGE:00026FA2
PAGE:00026FA2 loc_26FA2: ; CODE XREF: KsSetMajorFunctionHandler(x,x)+6Bj
PAGE:00026FA2 mov ecx, offset _DispatchRead@8 ; DispatchRead(x,x)
PAGE:00026FA7 jmp short loc_26FE4
PAGE:00026FA9 ;
---------------------------------------------------------------------------
PAGE:00026FA9
PAGE:00026FA9 loc_26FA9: ; CODE XREF: KsSetMajorFunctionHandler(x,x)+68j
PAGE:00026FA9 mov ecx, offset _DispatchClose@8 ; DispatchClose(x,x)
PAGE:00026FAE jmp short loc_26FE4
PAGE:00026FB0 ;
---------------------------------------------------------------------------
PAGE:00026FB0
PAGE:00026FB0 loc_26FB0: ; CODE XREF: KsSetMajorFunctionHandler(x,x)+64j
PAGE:00026FB0 mov ecx, offset _DispatchCreate@8 ;
DispatchCreate(x,x)
PAGE:00026FB5 jmp short loc_26FE4
PAGE:00026FB7 ;
---------------------------------------------------------------------------
PAGE:00026FB7
PAGE:00026FB7 loc_26FB7: ; CODE XREF: KsSetMajorFunctionHandler(x,x)+5Dj
PAGE:00026FB7 mov ecx, offset _DispatchFlush@8 ; DispatchFlush(x,x)
PAGE:00026FBC jmp short loc_26FE4
[...]
PAGE:00026FE4 mov edx, [ebp+DriverObject]
PAGE:00026FE7 mov [edx+eax*4+38h], ecx
; DrvObj->MajorFunction[IRP_MJ_XXX] = DispatchXXXXX
[...]
PAGE:00026F74 mov eax, [ebp+DriverObject]
PAGE:00026F77 mov eax, [eax+28h] ; DriverObject->FastIoDispatch
PAGE:00026F7A mov dword ptr [eax+8], offset _DispatchFastRead@32 ;
DispatchFastRead(x,x,x,x,x,x,x,x)
[...]
最有趣的部分当属安装的IRP handler:DispatchRead,DispatchWrite…
下面看个例子:
module: ks.sys
PAGE:0002B578 _DispatchWrite@8 proc near ; DATA XREF:
KsSetMajorFunctionHandler(x,x)+70o
PAGE:0002B578
PAGE:0002B578 PDEVICE_OBJECT = dword ptr 8
PAGE:0002B578 PIRP = dword ptr 0Ch
PAGE:0002B578
PAGE:0002B578 mov edi, edi
PAGE:0002B57A push ebp
PAGE:0002B57B mov ebp, esp
PAGE:0002B57D mov ecx, [ebp+PIRP]
PAGE:0002B580 mov eax, [ecx+60h]; Irp->CurrentStackLocation
PAGE:0002B583 mov eax, [eax+18h]; IrpSp->FileObject
PAGE:0002B586 mov eax, [eax+0Ch]; FileObject->FsContext
PAGE:0002B589 mov eax, [eax] ; *FsContext
PAGE:0002B58B mov eax, [eax] ; KSDISPATCH_TABLE
PAGE:0002B58D push ecx
PAGE:0002B58E push [ebp+PDEVICE_OBJECT]
PAGE:0002B591 call dword ptr [eax+8];KsDsp->Write(pDev,pIrp);
PAGE:0002B594 pop ebp
PAGE:0002B595 retn 8
PAGE:0002B595 DispatchWrite@8 endp
这些处理函数仅仅通过使用 KSKISPATCH_TABLE 的封装函数来路由 IRP。现在再回头看
下 MSDN 所描述的:
The dispatching assumes the table and FsContext structure are initialized by the
device using KsAllocateObjectHeader.
如果设备驱动因某些原因而无法正确地初始化 FsContext 那会发生什么呢?
EAX==NULL。因此通过向已知设备驱动发送I/O请求(Read,Write,DeviceIoControl…),那 |