.text:000104D2 ; void __stdcall DeferredRoutine(struct _KDPC *,PVOID,PVOID,PVOID)
.text:000104D2 DeferredRoutine proc near ; DATA XREF: start+15Co
.text:000104D2 xor ecx, ecx
.text:000104D4 cmp dword_12220, ecx
.text:000104DA jz short locret_104EE
.text:000104DC mov eax, Event
.text:000104E1 cmp eax, ecx
.text:000104E3 jz short locret_104EE
.text:000104E5 push ecx ; Wait
.text:000104E6 push ecx ; Increment
.text:000104E7 push eax ; Event
.text:000104E8 call ds:KeSetEvent
.text:000104EE
.text:000104EE locret_104EE: ; CODE XREF: DeferredRoutine+8j
.text:000104EE ; DeferredRoutine+11j
.text:000104EE retn 10h
.text:000104EE DeferredRoutine endp
这是上面 KeInitializeDpc 例程设置延迟调用过程, 第二个参数为NULL, 再该例程中如果 dword_12220 不为 0, 就设置事件,这个event 变量是全局。
if (dword_12220 != 0)
{
if (g_event != NULL)
{
KeSetEvent(g_event, NULL, NULL);
}
}
//--------------------下面是 IRP_MJ_CREATE 对应的例程--------------------------
.text:000103DC SDbgMsgCreate: ; DATA XREF: start+31o
.text:000103DC mov ecx, [esp+8]
.text:000103E0 and dword ptr [ecx+18h], 0
.text:000103E4 xor dl, dl
.text:000103E6 mov dword ptr [ecx+1Ch], 1
.text:000103ED call ds:IofCompleteRequest
.text:000103F3 xor eax, eax
.text:000103F5 retn 8
NTSTATUS SDbgMsgCreate(PDEVICE_OBJECT pDeviceObject, PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 1;
//
// IofCompleteRequest 例程是 _fastcall 调用方式
// 采用 ecx 和 edx 传递参数
//
IoCompleteRequest( ecx , edx );
return Irp->IoStatus.Status ;
}
//--------------------下面是 IRP_MJ_READ 对应的派遣例程-------------------------
下面的代码是由 IDA 自动生成, SDbgMsgRead 是我根据在 DriverObject 例程中的分析得处的该例程对应着 IRP_MJ_READ
; int __stdcall SDbgMsgRead(int,KIRQL NewIrql)
.text:00010646 SDbgMsgRead proc near ; DATA XREF: start+37o
.text:00010646
.text:00010646 NewIrql = byte ptr 18h
.text:00010646
.text:00010646 push ebx
.text:00010647 push ebp
.text:00010648 push esi
.text:00010649 push edi
.text:0001064A mov edi, dword ptr [esp+NewIrql]
.text:0001064E mov ebp, [edi+60h]
.text:00010651 mov ebx, offset SpinLock
.text:00010656 mov ecx, ebx ; SpinLock
.text:00010658 xor esi, esi
.text:0001065A call ds:KfAcquireSpinLock
.text:00010660 mov [esp+NewIrql], al
.text:00010664 mov eax, dword_12220
.text:00010669 test eax, eax
.text:0001066B jz short loc_106BB
.text:0001066D mov esi, [ebp+4]
.text:00010670 inc eax
.text:00010671 cmp esi, eax
.text:00010673 jle short loc_10677
.text:00010675 mov esi, eax
.text:00010677
// 上面的反汇编代码可能又有问题: NewIrql 是从哪来得?
从
MOV edi, dword ptr [esp+NewIrql]
MOV ebp, [edi+60h]
可以猜测出, 第二个参数应该是 Irp 才对, 这样Irp偏移量为 60H是 CurrentStackLocation
ULONG UlLength;
PVOID SystemBuffer = NULL ;
ebp = IoGetCurrentIrpStackLocation(Irp);
KfAcquireSpinLock(&g_SpinLock); // __fastcall 调用方式
UlLength = ebp->Parameters.Read.Length;
if (dword_12220 != 0)
{
if ( ebp->Parameters.Read.Length > dword_12220+1 )
{
UlLength = dword_12220+1; // 应该是和存放读取数据的缓冲区有关, 取小值
}
if (UlLength == 0)
{
; 完成 Irp
; 退出
}
// 取得读取数据的缓冲区
pSystemBuffer = Irp->AssociatedIrp.SystemBuffer ;
.text:00010677 loc_10677: ; CODE XREF: SDbgMsgRead+2Dj
.text:00010677 test esi, esi ; 比较 pSystemBuffer 是否为 NULL
.text:00010679 jz short loc_106BB
.text:0001067B mov eax, [edi+0Ch]
.text:0001067E test eax, eax
.text:00010680 jz short loc_106BB
if ( pSystemBuffer == NULL)
{
; 完成 Irp
; 退出
}
.text:00010682 push esi ; 读取数据的长度
.text:00010683 push dword_12224
.text:00010689 push eax ; 存放数据缓冲区的地址
.text:0001068A call sub_1050E
// 从数据存放的缓冲区中读取指定大小的字节
retValue = sub_1050E( pSystemBuffer, dword_12224, UlLength);
.text:0001068F cmp esi, dword_12220
.text:00010695 jge short loc_106B4
.text:00010697 mov eax, dword_12224
.text:0001069C lea ecx, [eax+esi-1]
.text:000106A0 push ecx
.text:000106A1 push eax
.text:000106A2 call sub_104F2
if (esi < dword_12220)
{
sub104f2_Retvalue = sub_104F2 (dword_12224 , dword_12224+esi-1 );
.text:000106A7 xor eax, eax
.text:000106A9 inc eax
.text:000106AA sub eax, esi
.text:000106AC add dword_12220, eax
.text:000106B2 jmp short loc_106BB
sub104f2_Retvalue = 1;
sub104f2_Retvalue -= UlLength;
dword_12220 += eax;
}else
{
.text:000106B4 loc_106B4: ; CODE XREF: SDbgMsgRead+4Fj
.text:000106B4 and dword_12220, 0
dword_12220 = 0;
}
label :loc_106BB:
.text:000106BB loc_106BB: ; CODE XREF: SDbgMsgRead+25j
.text:000106BB ; SDbgMsgRead+33j ...
.text:000106BB mov dl, [esp+NewIrql] ; NewIrql
.text:000106BF mov ecx, ebx ; SpinLock
.text:000106C1 call ds:KfReleaseSpinLock
KfReleaseSpinLock(g_SpinLock);
.text:000106C7 and dword ptr [edi+18h], 0
.text:000106CB xor dl, dl
.text:000106CD mov ecx, edi ; Irp
.text:000106CF mov [edi+1Ch], esi ; esi 实际读取了多少字节的数据
.text:000106D2 call ds:IofCompleteRequest
.text:000106D8 pop edi
.text:000106D9 pop esi
.text:000106DA pop ebp
.text:000106DB xor eax, eax
.text:000106DD pop ebx
.text:000106DE retn 8
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = esi ; // 实际读取了多少字节的数据
IofCompleteRequest(Irp, 0);
}