-
-
[原创]逆向分析:Win10 ObRegisterCallbacks的相关分析
-
发表于: 2025-4-4 22:11 6330
-
写这篇帖子主要是为记录ObRegisterCallbacks函数的相关分析,如有错误,欢迎批评指正。
给出的为C伪代码,仅展示逻辑,不保证安全性。
C的伪代码如下
这是原始汇编代码
逆向ObUnRegisterCallbacks的思路
函数开头保存了一些寄存器的值,包括rbx、rbp、rsi、rdi,以及r12到r15,这说明函数会使用这些寄存器,并在结束时恢复它们。接着分配了0x20字节的栈空间,一般用于局部变量。
然后检查输入参数。这是内核函数的通用操作,可以看一下。
movzx eax, word ptr [rcx],这里rcx是第一个参数,可能是一个指向OB_CALLBACK_REGISTRATION结构的指针。接着用0xFF00进行按位与操作,判断是否设置了特定标志。如果不符合条件,跳转到错误处理部分,返回错误码0xC000000D(STATUS_INVALID_PARAMETER)。
接下来,函数读取r15+2处的字(可能是OperationCount),如果为零,同样跳转到错误处理。这里检查是否有有效的操作类型数量。
然后,函数计算需要分配的内存大小,使用ExAllocatePoolWithTag分配内存,标签是0x6C46624F,可能是'ObCf'的ASCII表示,ObjectCallbackFunction嘛。如果分配失败,返回0xC000009A(STATUS_INSUFFICIENT_RESOURCES)。
分配内存后,用memset清零,这里用RltZeroMemory替代,并设置结构体的各个字段。
然后,通过循环处理每个回调操作,验证每个回调的Altitude和回调函数是否有效,特别是调用MmVerifyCallbackFunctionCheckFlags来验证回调函数的标志位。
在处理每个回调项时,会为每个操作分配一个回调块,并将其插入到全局回调链表中,使用ObpInsertCallbackByAltitude确保按Altitude排序。如果插入失败,函数需要回滚已分配的资源,并返回相应的错误码。
KeEnterCriticalRegion这些就是APC相关函数
内核中也在用ExAllocatePoolWithTag嘛,WDK还非要用ExAllocatePool2:)
几个函数中最引人注目的应该是MmVerifyCallbackFunctionCheckFlags吧,负责对回调合法性的检验,下面有对其分析。
原始汇编代码
分析思路
首先看开头部分。代码开始保存寄存器和分配栈空间,接着初始化esi为0,把rcx(第一个参数)赋值给rbx。比较si和[rbx+2]的值,如果si大于等于的话,跳转到释放内存的部分。这可能是在检查回调项的数量是否处理完毕。
接下来,循环部分处理每个回调项。使用shl rax,6和add rdi,rax来计算每个回调项的位置,大概是每个项的大小为0x40(64字节)。然后调用ExWaitForRundownProtectionRelease,这可能是在等待引用计数归零。然后获取当前线程,减少资源计数,进入临界区,获取PushLock,操作链表来移除回调项,释放锁,离开临界区。循环直到所有项处理完,最后释放内存。
然后看ObpCallPostOperationCallbacks部分。这部分在遍历链表,调用每个回调的后期处理函数。通过比较链表是否为空来决定是否继续。取出链表中的每个节点,进行验证,调用guard_dispatch_icall执行回调函数,释放资源,并释放内存。最后释放对象引用,离开临界区。
这个逆向还原度可能没上一个高。
分析思路
开头是保存寄存器的指令,把rbx、rbp、rsi压入栈中,然后push rdi,接着调整rsp分配栈空间。这些操作通常在函数开头。
接下来,mov edi, edx 和 mov rsi, rcx,这里应该是将传入的参数保存到edi和rsi中,然后调MiGetSystemRegionType,结果保存在eax中。比较eax和1,如果相等就跳转到地址fffff800`23faf75e,将eax清零然后跳转到结尾返回。这说明如果MiGetSystemRegionType返回1,函数直接返回0。
如果比较结果不相等(即eax不等于1),则继续执行后面的代码。这里从地址fffff800`23faf6f3开始,读取gs:[188h],也就是当前线程的KTHREAD结构,保存到rbp。然后xor ebx, ebx,将ebx清零,用来作为返回值或者中间变量。接着对[rbp+1E4h]处的字减1,这可能是线程的某个计数器,比如资源计数或递归计数。然后mov dl,1,准备调用ExAcquireResourceSharedLite,传入rcx为PsLoadedModuleResource,dl为1(表示等待资源可用)。
接下来调用MiLookupDataTableEntry,参数是rsi(原rcx,即第一个参数)和edx(此时为0)。检查返回的rax是否为NULL,如果是,跳到后面释放资源的部分。否则,测试edi(原edx,第二个参数)是否为0,如果是,设置ebx为1。否则,检查rax+68h处的值与edi是否相交,如果相交则ebx保持0,否则设为1。之后释放资源,调用ExReleaseResourceLite,然后恢复线程状态,返回ebx的值。
MiLookupDataTableEntry
MiLookupDataTableEntry的原型返回一个指向数据表条目结构的指针,该结构包含Flags字段在偏移0x68处。
如何确定就是Flags呢?
Windbg里dt一下LDR_DATA_TABLE_ENTRY
只要Flags给一个非0值,就会检查,而ObRegisterCallbacks传的是硬编码0x20,这便是许多帖子都说要将DriverSection的Flag值设为0x20的原因。
因此绕过方法就是Flags值设为0x20。这个更改是通过修改LDR_DATA_TABLE_ENTRY的结构体实现的,后面有分析和示例代码
这个Altitude在微软的说明文档中也是模棱两可,测试开发填321000应该可以吧(怀疑),正式的应该要向微软申请。
Altitude的具体就没逆了
这几个的分析思路和ObRegisterCallbacks一致
以下的结构体完全依照Windbg的符号分析
这便是绕过MmVerifyCallbackFunctionCheckFlags的突破口,将Flags的值设为0x20,示例如下
效果
这个在一些其他函数中有引用,所以分析一下结构即可
这个在ObUnRegisterCallbacks有用到
以上的测试分析基于Win10 build19041进行,欢迎各位指正
NTSTATUS ObRegisterCallbacks(POB_CALLBACK_REGISTRATION CallbackRegistration, PVOID *RegistrationHandle) { POB_CALLBACK_ENTRY CallbackEntry; POB_CALLBACK_HEADER Header; ULONG TotalSize; NTSTATUS Status = STATUS_SUCCESS; ULONG i; //验证基本结构版本和标志位 if ((CallbackRegistration->Version & 0xFF00) != OB_FLT_REGISTRATION_VERSION || CallbackRegistration->OperationCount == 0) { return STATUS_INVALID_PARAMETER; } //计算需要分配的内存大小(Header + 回调项数组) TotalSize = sizeof(OB_CALLBACK_HEADER) + CallbackRegistration->OperationCount * sizeof(OB_CALLBACK_ENTRY); // 分配带标签的内存池 Header = (POB_CALLBACK_HEADER)ExAllocatePoolWithTag(NonPagedPool, TotalSize, 'ObCf'); if (!Header) { return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(Header, TotalSize); // 初始化Header结构 Header->Version = CallbackRegistration->Version; Header->OperationCount = CallbackRegistration->OperationCount; Header->RegistrationContext = CallbackRegistration->RegistrationContext; // 处理每个回调项 for (i = 0; i < CallbackRegistration->OperationCount; i++) { POB_OPERATION_REGISTRATION Operation = &CallbackRegistration->OperationRegistration[i]; CallbackEntry = &Header->Entries[i]; // 验证Altitude和回调函数 if (Operation->Altitude == 0 || !MmVerifyCallbackFunctionCheckFlags(Operation->PreOperation, 0x20) || (Operation->PostOperation && !MmVerifyCallbackFunctionCheckFlags(Operation->PostOperation, 0x20))) { Status = STATUS_INVALID_PARAMETER; break; } // 初始化回调项 CallbackEntry->Altitude = Operation->Altitude; CallbackEntry->PreOperation = Operation->PreOperation; CallbackEntry->PostOperation = Operation->PostOperation; InitializeListHead(&CallbackEntry->Link); // 按Altitude插入全局链表 Status = ObpInsertCallbackByAltitude(CallbackEntry); if (!NT_SUCCESS(Status)) { break; } } // 错误处理:回滚已注册项 if (!NT_SUCCESS(Status)) { for (ULONG j = 0; j < i; j++) { ObpRemoveCallbackEntry(&Header->Entries[j]); } ExFreePoolWithTag(Header, 'ObCf'); return Status; } //设置输出句柄 *RegistrationHandle = Header; return STATUS_SUCCESS;}NTSTATUS ObRegisterCallbacks(POB_CALLBACK_REGISTRATION CallbackRegistration, PVOID *RegistrationHandle) { POB_CALLBACK_ENTRY CallbackEntry; POB_CALLBACK_HEADER Header; ULONG TotalSize; NTSTATUS Status = STATUS_SUCCESS; ULONG i; //验证基本结构版本和标志位 if ((CallbackRegistration->Version & 0xFF00) != OB_FLT_REGISTRATION_VERSION || CallbackRegistration->OperationCount == 0) { return STATUS_INVALID_PARAMETER; } //计算需要分配的内存大小(Header + 回调项数组) TotalSize = sizeof(OB_CALLBACK_HEADER) + CallbackRegistration->OperationCount * sizeof(OB_CALLBACK_ENTRY); // 分配带标签的内存池 Header = (POB_CALLBACK_HEADER)ExAllocatePoolWithTag(NonPagedPool, TotalSize, 'ObCf'); if (!Header) { return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(Header, TotalSize); // 初始化Header结构 Header->Version = CallbackRegistration->Version; Header->OperationCount = CallbackRegistration->OperationCount; Header->RegistrationContext = CallbackRegistration->RegistrationContext; // 处理每个回调项 for (i = 0; i < CallbackRegistration->OperationCount; i++) { POB_OPERATION_REGISTRATION Operation = &CallbackRegistration->OperationRegistration[i]; CallbackEntry = &Header->Entries[i]; // 验证Altitude和回调函数 if (Operation->Altitude == 0 || !MmVerifyCallbackFunctionCheckFlags(Operation->PreOperation, 0x20) || (Operation->PostOperation && !MmVerifyCallbackFunctionCheckFlags(Operation->PostOperation, 0x20))) { Status = STATUS_INVALID_PARAMETER; break; } // 初始化回调项 CallbackEntry->Altitude = Operation->Altitude; CallbackEntry->PreOperation = Operation->PreOperation; CallbackEntry->PostOperation = Operation->PostOperation; InitializeListHead(&CallbackEntry->Link); // 按Altitude插入全局链表 Status = ObpInsertCallbackByAltitude(CallbackEntry); if (!NT_SUCCESS(Status)) { break; } } // 错误处理:回滚已注册项 if (!NT_SUCCESS(Status)) { for (ULONG j = 0; j < i; j++) { ObpRemoveCallbackEntry(&Header->Entries[j]); } ExFreePoolWithTag(Header, 'ObCf'); return Status; } //设置输出句柄 *RegistrationHandle = Header; return STATUS_SUCCESS;}nt!ObRegisterCallbacks:fffff800`243ca320 48895c2408 mov qword ptr [rsp+8],rbxfffff800`243ca325 48896c2410 mov qword ptr [rsp+10h],rbpfffff800`243ca32a 4889742418 mov qword ptr [rsp+18h],rsifffff800`243ca32f 57 push rdifffff800`243ca330 4154 push r12fffff800`243ca332 4155 push r13fffff800`243ca334 4156 push r14fffff800`243ca336 4157 push r15fffff800`243ca338 4883ec20 sub rsp,20hfffff800`243ca33c 0fb701 movzx eax,word ptr [rcx]fffff800`243ca33f 4c8bf9 mov r15,rcxfffff800`243ca342 b900ff0000 mov ecx,0FF00hfffff800`243ca347 33ff xor edi,edifffff800`243ca349 6623c1 and ax,cxfffff800`243ca34c 4c8be2 mov r12,rdxfffff800`243ca34f b900010000 mov ecx,100hfffff800`243ca354 8bdf mov ebx,edifffff800`243ca356 663bc1 cmp ax,cxfffff800`243ca359 0f8532740900 jne nt!ObRegisterCallbacks+0x97471 (fffff800`24461791) Branchnt!ObRegisterCallbacks+0x3f:fffff800`243ca35f 410fb74702 movzx eax,word ptr [r15+2]fffff800`243ca364 6685c0 test ax,axfffff800`243ca367 0f8424740900 je nt!ObRegisterCallbacks+0x97471 (fffff800`24461791) Branchnt!ObRegisterCallbacks+0x4d:fffff800`243ca36d 410fb76f08 movzx ebp,word ptr [r15+8]fffff800`243ca372 448d6f01 lea r13d,[rdi+1]fffff800`243ca376 8bc8 mov ecx,eaxfffff800`243ca378 83c520 add ebp,20hfffff800`243ca37b c1e106 shl ecx,6fffff800`243ca37e 41b84f62466c mov r8d,6C46624Fhfffff800`243ca384 03e9 add ebp,ecxfffff800`243ca386 418bcd mov ecx,r13dfffff800`243ca389 8bd5 mov edx,ebpfffff800`243ca38b 448bf5 mov r14d,ebpfffff800`243ca38e e87dcc1e00 call nt!ExAllocatePoolWithTag (fffff800`245b7010)fffff800`243ca393 488bf0 mov rsi,raxfffff800`243ca396 4885c0 test rax,raxfffff800`243ca399 0f841f730900 je nt!ObRegisterCallbacks+0x9739e (fffff800`244616be) Branchnt!ObRegisterCallbacks+0x7f:fffff800`243ca39f 458bc6 mov r8d,r14dfffff800`243ca3a2 33d2 xor edx,edxfffff800`243ca3a4 488bc8 mov rcx,raxfffff800`243ca3a7 e8d48cc4ff call nt!memset (fffff800`24013080)fffff800`243ca3ac b800010000 mov eax,100hfffff800`243ca3b1 668906 mov word ptr [rsi],axfffff800`243ca3b4 498b4718 mov rax,qword ptr [r15+18h]fffff800`243ca3b8 48894608 mov qword ptr [rsi+8],raxfffff800`243ca3bc 450fb74708 movzx r8d,word ptr [r15+8]fffff800`243ca3c1 412be8 sub ebp,r8dfffff800`243ca3c4 6644894612 mov word ptr [rsi+12h],r8wfffff800`243ca3c9 6644894610 mov word ptr [rsi+10h],r8wfffff800`243ca3ce 8bcd mov ecx,ebpfffff800`243ca3d0 4803ce add rcx,rsifffff800`243ca3d3 48894e18 mov qword ptr [rsi+18h],rcxfffff800`243ca3d7 498b5710 mov rdx,qword ptr [r15+10h]fffff800`243ca3db e8e089c4ff call nt!memcpy (fffff800`24012dc0)fffff800`243ca3e0 8bef mov ebp,edifffff800`243ca3e2 66413b7f02 cmp di,word ptr [r15+2]fffff800`243ca3e7 0f83b6000000 jae nt!ObRegisterCallbacks+0x183 (fffff800`243ca4a3) Branchnt!ObRegisterCallbacks+0xcd:fffff800`243ca3ed 448bf5 mov r14d,ebpfffff800`243ca3f0 49c1e605 shl r14,5fffff800`243ca3f4 4d037720 add r14,qword ptr [r15+20h]fffff800`243ca3f8 8bdd mov ebx,ebpfffff800`243ca3fa 41397e08 cmp dword ptr [r14+8],edifffff800`243ca3fe 0f847c730900 je nt!ObRegisterCallbacks+0x97460 (fffff800`24461780) Branchnt!ObRegisterCallbacks+0xe4:fffff800`243ca404 498b06 mov rax,qword ptr [r14]fffff800`243ca407 488b08 mov rcx,qword ptr [rax]fffff800`243ca40a f6414240 test byte ptr [rcx+42h],40hfffff800`243ca40e 0f846c730900 je nt!ObRegisterCallbacks+0x97460 (fffff800`24461780) Branchnt!ObRegisterCallbacks+0xf4:fffff800`243ca414 498b4e10 mov rcx,qword ptr [r14+10h]fffff800`243ca418 4885c9 test rcx,rcxfffff800`243ca41b 0f84a7720900 je nt!ObRegisterCallbacks+0x973a8 (fffff800`244616c8) Branchnt!ObRegisterCallbacks+0x101:fffff800`243ca421 ba20000000 mov edx,20hfffff800`243ca426 e8a552beff call nt!MmVerifyCallbackFunctionCheckFlags (fffff800`23faf6d0)fffff800`243ca42b 85c0 test eax,eaxfffff800`243ca42d 0f84bf720900 je nt!ObRegisterCallbacks+0x973d2 (fffff800`244616f2) Branchnt!ObRegisterCallbacks+0x113:fffff800`243ca433 498b4e18 mov rcx,qword ptr [r14+18h]fffff800`243ca437 4885c9 test rcx,rcxfffff800`243ca43a 0f85a0720900 jne nt!ObRegisterCallbacks+0x973c0 (fffff800`244616e0) Branchnt!ObRegisterCallbacks+0x120:fffff800`243ca440 48c1e306 shl rbx,6fffff800`243ca444 4883c320 add rbx,20hfffff800`243ca448 4803de add rbx,rsifffff800`243ca44b 488d4b38 lea rcx,[rbx+38h]fffff800`243ca44f 48895b08 mov qword ptr [rbx+8],rbxfffff800`243ca453 48891b mov qword ptr [rbx],rbxfffff800`243ca456 e8f5d4aeff call nt!ExInitializePushLock (fffff800`23eb7950)fffff800`243ca45b 418b4608 mov eax,dword ptr [r14+8]fffff800`243ca45f 488bd3 mov rdx,rbxfffff800`243ca462 894310 mov dword ptr [rbx+10h],eaxfffff800`243ca465 48897318 mov qword ptr [rbx+18h],rsifffff800`243ca469 498b06 mov rax,qword ptr [r14]fffff800`243ca46c 488b08 mov rcx,qword ptr [rax]fffff800`243ca46f 48894b20 mov qword ptr [rbx+20h],rcxfffff800`243ca473 498b4610 mov rax,qword ptr [r14+10h]fffff800`243ca477 48894328 mov qword ptr [rbx+28h],raxfffff800`243ca47b 498b4618 mov rax,qword ptr [r14+18h]fffff800`243ca47f 48894330 mov qword ptr [rbx+30h],raxfffff800`243ca483 e86c000000 call nt!ObpInsertCallbackByAltitude (fffff800`243ca4f4)fffff800`243ca488 8bd8 mov ebx,eaxfffff800`243ca48a 85c0 test eax,eaxfffff800`243ca48c 7815 js nt!ObRegisterCallbacks+0x183 (fffff800`243ca4a3) Branchnt!ObRegisterCallbacks+0x16e:fffff800`243ca48e 6644016e02 add word ptr [rsi+2],r13wfffff800`243ca493 4103ed add ebp,r13dfffff800`243ca496 410fb74f02 movzx ecx,word ptr [r15+2]fffff800`243ca49b 3be9 cmp ebp,ecxfffff800`243ca49d 0f824affffff jb nt!ObRegisterCallbacks+0xcd (fffff800`243ca3ed) Branchnt!ObRegisterCallbacks+0x183:fffff800`243ca4a3 85db test ebx,ebxfffff800`243ca4a5 0f884c720900 js nt!ObRegisterCallbacks+0x973d7 (fffff800`244616f7) Branchnt!ObRegisterCallbacks+0x18b:fffff800`243ca4ab 663b7e02 cmp di,word ptr [rsi+2]fffff800`243ca4af 7316 jae nt!ObRegisterCallbacks+0x1a7 (fffff800`243ca4c7) Branchnt!ObRegisterCallbacks+0x191:fffff800`243ca4b1 8bc7 mov eax,edifffff800`243ca4b3 4103fd add edi,r13dfffff800`243ca4b6 48c1e006 shl rax,6fffff800`243ca4ba 44096c3034 or dword ptr [rax+rsi+34h],r13dfffff800`243ca4bf 0fb74602 movzx eax,word ptr [rsi+2]fffff800`243ca4c3 3bf8 cmp edi,eaxfffff800`243ca4c5 72ea jb nt!ObRegisterCallbacks+0x191 (fffff800`243ca4b1) Branchnt!ObRegisterCallbacks+0x1a7:fffff800`243ca4c7 49893424 mov qword ptr [r12],rsint!ObRegisterCallbacks+0x1ab:fffff800`243ca4cb 8bc3 mov eax,ebxnt!ObRegisterCallbacks+0x1ad:fffff800`243ca4cd 488b5c2450 mov rbx,qword ptr [rsp+50h]fffff800`243ca4d2 488b6c2458 mov rbp,qword ptr [rsp+58h]fffff800`243ca4d7 488b742460 mov rsi,qword ptr [rsp+60h]fffff800`243ca4dc 4883c420 add rsp,20hfffff800`243ca4e0 415f pop r15fffff800`243ca4e2 415e pop r14fffff800`243ca4e4 415d pop r13fffff800`243ca4e6 415c pop r12fffff800`243ca4e8 5f pop rdifffff800`243ca4e9 c3 retnt!ObRegisterCallbacks+0x9739e:fffff800`244616be b89a0000c0 mov eax,0C000009Ahfffff800`244616c3 e9058ef6ff jmp nt!ObRegisterCallbacks+0x1ad (fffff800`243ca4cd) Branchnt!ObRegisterCallbacks+0x973a8:fffff800`244616c8 49397e18 cmp qword ptr [r14+18h],rdifffff800`244616cc 0f84ae000000 je nt!ObRegisterCallbacks+0x97460 (fffff800`24461780) Branchnt!ObRegisterCallbacks+0x973b2:fffff800`244616d2 4885c9 test rcx,rcxfffff800`244616d5 0f84588df6ff je nt!ObRegisterCallbacks+0x113 (fffff800`243ca433) Branchnt!ObRegisterCallbacks+0x973bb:fffff800`244616db e9418df6ff jmp nt!ObRegisterCallbacks+0x101 (fffff800`243ca421) Branchnt!ObRegisterCallbacks+0x973c0:fffff800`244616e0 ba20000000 mov edx,20hfffff800`244616e5 e8e6dfb4ff call nt!MmVerifyCallbackFunctionCheckFlags (fffff800`23faf6d0)fffff800`244616ea 85c0 test eax,eaxfffff800`244616ec 0f854e8df6ff jne nt!ObRegisterCallbacks+0x120 (fffff800`243ca440) Branchnt!ObRegisterCallbacks+0x973d2:fffff800`244616f2 bb220000c0 mov ebx,0C0000022hnt!ObRegisterCallbacks+0x973d7:fffff800`244616f7 663b7e02 cmp di,word ptr [rsi+2]fffff800`244616fb 7370 jae nt!ObRegisterCallbacks+0x9744d (fffff800`2446176d) Branchnt!ObRegisterCallbacks+0x973dd:fffff800`244616fd bdb8000000 mov ebp,0B8hnt!ObRegisterCallbacks+0x973e2:fffff800`24461702 8bc7 mov eax,edifffff800`24461704 4c8d7620 lea r14,[rsi+20h]fffff800`24461708 48c1e006 shl rax,6fffff800`2446170c 4c03f0 add r14,raxfffff800`2446170f 65488b042588010000 mov rax,qword ptr gs:[188h]fffff800`24461718 66ff88e6010000 dec word ptr [rax+1E6h]fffff800`2446171f 498b4e20 mov rcx,qword ptr [r14+20h]fffff800`24461723 33d2 xor edx,edxfffff800`24461725 4803cd add rcx,rbpfffff800`24461728 e8433c9eff call nt!ExAcquirePushLockExclusiveEx (fffff800`23e45370)fffff800`2446172d 498b0e mov rcx,qword ptr [r14]fffff800`24461730 4c397108 cmp qword ptr [rcx+8],r14fffff800`24461734 7554 jne nt!ObRegisterCallbacks+0x9746a (fffff800`2446178a) Branchnt!ObRegisterCallbacks+0x97416:fffff800`24461736 498b4608 mov rax,qword ptr [r14+8]fffff800`2446173a 4c3930 cmp qword ptr [rax],r14fffff800`2446173d 754b jne nt!ObRegisterCallbacks+0x9746a (fffff800`2446178a) Branchnt!ObRegisterCallbacks+0x9741f:fffff800`2446173f 488908 mov qword ptr [rax],rcxfffff800`24461742 33d2 xor edx,edxfffff800`24461744 48894108 mov qword ptr [rcx+8],raxfffff800`24461748 498b4e20 mov rcx,qword ptr [r14+20h]fffff800`2446174c 4803cd add rcx,rbpfffff800`2446174f e81c419eff call nt!ExReleasePushLockEx (fffff800`23e45870)fffff800`24461754 65488b0c2588010000 mov rcx,qword ptr gs:[188h]fffff800`2446175d e80e409eff call nt!KiLeaveGuardedRegionUnsafe (fffff800`23e45770)fffff800`24461762 0fb74602 movzx eax,word ptr [rsi+2]fffff800`24461766 4103fd add edi,r13dfffff800`24461769 3bf8 cmp edi,eaxfffff800`2446176b 7295 jb nt!ObRegisterCallbacks+0x973e2 (fffff800`24461702) Branchnt!ObRegisterCallbacks+0x9744d:fffff800`2446176d ba4f62466c mov edx,6C46624Fhfffff800`24461772 488bce mov rcx,rsifffff800`24461775 e836591500 call nt!ExFreePool (fffff800`245b70b0)fffff800`2446177a 90 nopfffff800`2446177b e94b8df6ff jmp nt!ObRegisterCallbacks+0x1ab (fffff800`243ca4cb) Branchnt!ObRegisterCallbacks+0x97460:fffff800`24461780 bb0d0000c0 mov ebx,0C000000Dhfffff800`24461785 e9198df6ff jmp nt!ObRegisterCallbacks+0x183 (fffff800`243ca4a3) Branchnt!ObRegisterCallbacks+0x9746a:fffff800`2446178a b903000000 mov ecx,3fffff800`2446178f cd29 int 29hnt!ObRegisterCallbacks+0x97471:fffff800`24461791 b80d0000c0 mov eax,0C000000Dhfffff800`24461796 e9328df6ff jmp nt!ObRegisterCallbacks+0x1ad (fffff800`243ca4cd) Branchnt!ObRegisterCallbacks:fffff800`243ca320 48895c2408 mov qword ptr [rsp+8],rbxfffff800`243ca325 48896c2410 mov qword ptr [rsp+10h],rbpfffff800`243ca32a 4889742418 mov qword ptr [rsp+18h],rsifffff800`243ca32f 57 push rdifffff800`243ca330 4154 push r12fffff800`243ca332 4155 push r13fffff800`243ca334 4156 push r14fffff800`243ca336 4157 push r15fffff800`243ca338 4883ec20 sub rsp,20hfffff800`243ca33c 0fb701 movzx eax,word ptr [rcx]fffff800`243ca33f 4c8bf9 mov r15,rcxfffff800`243ca342 b900ff0000 mov ecx,0FF00hfffff800`243ca347 33ff xor edi,edifffff800`243ca349 6623c1 and ax,cxfffff800`243ca34c 4c8be2 mov r12,rdxfffff800`243ca34f b900010000 mov ecx,100hfffff800`243ca354 8bdf mov ebx,edifffff800`243ca356 663bc1 cmp ax,cxfffff800`243ca359 0f8532740900 jne nt!ObRegisterCallbacks+0x97471 (fffff800`24461791) Branchnt!ObRegisterCallbacks+0x3f:fffff800`243ca35f 410fb74702 movzx eax,word ptr [r15+2]fffff800`243ca364 6685c0 test ax,axfffff800`243ca367 0f8424740900 je nt!ObRegisterCallbacks+0x97471 (fffff800`24461791) Branchnt!ObRegisterCallbacks+0x4d:fffff800`243ca36d 410fb76f08 movzx ebp,word ptr [r15+8]fffff800`243ca372 448d6f01 lea r13d,[rdi+1]fffff800`243ca376 8bc8 mov ecx,eaxfffff800`243ca378 83c520 add ebp,20hfffff800`243ca37b c1e106 shl ecx,6fffff800`243ca37e 41b84f62466c mov r8d,6C46624Fhfffff800`243ca384 03e9 add ebp,ecxfffff800`243ca386 418bcd mov ecx,r13dfffff800`243ca389 8bd5 mov edx,ebpfffff800`243ca38b 448bf5 mov r14d,ebpfffff800`243ca38e e87dcc1e00 call nt!ExAllocatePoolWithTag (fffff800`245b7010)fffff800`243ca393 488bf0 mov rsi,raxfffff800`243ca396 4885c0 test rax,raxfffff800`243ca399 0f841f730900 je nt!ObRegisterCallbacks+0x9739e (fffff800`244616be) Branchnt!ObRegisterCallbacks+0x7f:fffff800`243ca39f 458bc6 mov r8d,r14dfffff800`243ca3a2 33d2 xor edx,edxfffff800`243ca3a4 488bc8 mov rcx,raxfffff800`243ca3a7 e8d48cc4ff call nt!memset (fffff800`24013080)fffff800`243ca3ac b800010000 mov eax,100hfffff800`243ca3b1 668906 mov word ptr [rsi],axfffff800`243ca3b4 498b4718 mov rax,qword ptr [r15+18h]fffff800`243ca3b8 48894608 mov qword ptr [rsi+8],raxfffff800`243ca3bc 450fb74708 movzx r8d,word ptr [r15+8]fffff800`243ca3c1 412be8 sub ebp,r8dfffff800`243ca3c4 6644894612 mov word ptr [rsi+12h],r8wfffff800`243ca3c9 6644894610 mov word ptr [rsi+10h],r8wfffff800`243ca3ce 8bcd mov ecx,ebpfffff800`243ca3d0 4803ce add rcx,rsifffff800`243ca3d3 48894e18 mov qword ptr [rsi+18h],rcxfffff800`243ca3d7 498b5710 mov rdx,qword ptr [r15+10h]fffff800`243ca3db e8e089c4ff call nt!memcpy (fffff800`24012dc0)fffff800`243ca3e0 8bef mov ebp,edifffff800`243ca3e2 66413b7f02 cmp di,word ptr [r15+2]fffff800`243ca3e7 0f83b6000000 jae nt!ObRegisterCallbacks+0x183 (fffff800`243ca4a3) Branchnt!ObRegisterCallbacks+0xcd:fffff800`243ca3ed 448bf5 mov r14d,ebpfffff800`243ca3f0 49c1e605 shl r14,5fffff800`243ca3f4 4d037720 add r14,qword ptr [r15+20h]fffff800`243ca3f8 8bdd mov ebx,ebpfffff800`243ca3fa 41397e08 cmp dword ptr [r14+8],edifffff800`243ca3fe 0f847c730900 je nt!ObRegisterCallbacks+0x97460 (fffff800`24461780) Branchnt!ObRegisterCallbacks+0xe4:fffff800`243ca404 498b06 mov rax,qword ptr [r14]fffff800`243ca407 488b08 mov rcx,qword ptr [rax]fffff800`243ca40a f6414240 test byte ptr [rcx+42h],40hfffff800`243ca40e 0f846c730900 je nt!ObRegisterCallbacks+0x97460 (fffff800`24461780) Branchnt!ObRegisterCallbacks+0xf4:fffff800`243ca414 498b4e10 mov rcx,qword ptr [r14+10h]fffff800`243ca418 4885c9 test rcx,rcxfffff800`243ca41b 0f84a7720900 je nt!ObRegisterCallbacks+0x973a8 (fffff800`244616c8) Branchnt!ObRegisterCallbacks+0x101:fffff800`243ca421 ba20000000 mov edx,20hfffff800`243ca426 e8a552beff call nt!MmVerifyCallbackFunctionCheckFlags (fffff800`23faf6d0)fffff800`243ca42b 85c0 test eax,eaxfffff800`243ca42d 0f84bf720900 je nt!ObRegisterCallbacks+0x973d2 (fffff800`244616f2) Branchnt!ObRegisterCallbacks+0x113:fffff800`243ca433 498b4e18 mov rcx,qword ptr [r14+18h]fffff800`243ca437 4885c9 test rcx,rcxfffff800`243ca43a 0f85a0720900 jne nt!ObRegisterCallbacks+0x973c0 (fffff800`244616e0) Branchnt!ObRegisterCallbacks+0x120:fffff800`243ca440 48c1e306 shl rbx,6fffff800`243ca444 4883c320 add rbx,20hfffff800`243ca448 4803de add rbx,rsifffff800`243ca44b 488d4b38 lea rcx,[rbx+38h]fffff800`243ca44f 48895b08 mov qword ptr [rbx+8],rbxfffff800`243ca453 48891b mov qword ptr [rbx],rbxfffff800`243ca456 e8f5d4aeff call nt!ExInitializePushLock (fffff800`23eb7950)fffff800`243ca45b 418b4608 mov eax,dword ptr [r14+8]fffff800`243ca45f 488bd3 mov rdx,rbxfffff800`243ca462 894310 mov dword ptr [rbx+10h],eaxfffff800`243ca465 48897318 mov qword ptr [rbx+18h],rsifffff800`243ca469 498b06 mov rax,qword ptr [r14]fffff800`243ca46c 488b08 mov rcx,qword ptr [rax]fffff800`243ca46f 48894b20 mov qword ptr [rbx+20h],rcxfffff800`243ca473 498b4610 mov rax,qword ptr [r14+10h]fffff800`243ca477 48894328 mov qword ptr [rbx+28h],raxfffff800`243ca47b 498b4618 mov rax,qword ptr [r14+18h]fffff800`243ca47f 48894330 mov qword ptr [rbx+30h],raxfffff800`243ca483 e86c000000 call nt!ObpInsertCallbackByAltitude (fffff800`243ca4f4)fffff800`243ca488 8bd8 mov ebx,eaxfffff800`243ca48a 85c0 test eax,eaxfffff800`243ca48c 7815 js nt!ObRegisterCallbacks+0x183 (fffff800`243ca4a3) Branchnt!ObRegisterCallbacks+0x16e:fffff800`243ca48e 6644016e02 add word ptr [rsi+2],r13wfffff800`243ca493 4103ed add ebp,r13dfffff800`243ca496 410fb74f02 movzx ecx,word ptr [r15+2]fffff800`243ca49b 3be9 cmp ebp,ecxfffff800`243ca49d 0f824affffff jb nt!ObRegisterCallbacks+0xcd (fffff800`243ca3ed) Branchnt!ObRegisterCallbacks+0x183:fffff800`243ca4a3 85db test ebx,ebxfffff800`243ca4a5 0f884c720900 js nt!ObRegisterCallbacks+0x973d7 (fffff800`244616f7) Branchnt!ObRegisterCallbacks+0x18b:fffff800`243ca4ab 663b7e02 cmp di,word ptr [rsi+2]fffff800`243ca4af 7316 jae nt!ObRegisterCallbacks+0x1a7 (fffff800`243ca4c7) Branchnt!ObRegisterCallbacks+0x191:fffff800`243ca4b1 8bc7 mov eax,edifffff800`243ca4b3 4103fd add edi,r13dfffff800`243ca4b6 48c1e006 shl rax,6fffff800`243ca4ba 44096c3034 or dword ptr [rax+rsi+34h],r13dfffff800`243ca4bf 0fb74602 movzx eax,word ptr [rsi+2]fffff800`243ca4c3 3bf8 cmp edi,eaxfffff800`243ca4c5 72ea jb nt!ObRegisterCallbacks+0x191 (fffff800`243ca4b1) Branchnt!ObRegisterCallbacks+0x1a7:fffff800`243ca4c7 49893424 mov qword ptr [r12],rsint!ObRegisterCallbacks+0x1ab:fffff800`243ca4cb 8bc3 mov eax,ebxnt!ObRegisterCallbacks+0x1ad:fffff800`243ca4cd 488b5c2450 mov rbx,qword ptr [rsp+50h]fffff800`243ca4d2 488b6c2458 mov rbp,qword ptr [rsp+58h]fffff800`243ca4d7 488b742460 mov rsi,qword ptr [rsp+60h]fffff800`243ca4dc 4883c420 add rsp,20hfffff800`243ca4e0 415f pop r15fffff800`243ca4e2 415e pop r14fffff800`243ca4e4 415d pop r13fffff800`243ca4e6 415c pop r12fffff800`243ca4e8 5f pop rdifffff800`243ca4e9 c3 retnt!ObRegisterCallbacks+0x9739e:fffff800`244616be b89a0000c0 mov eax,0C000009Ahfffff800`244616c3 e9058ef6ff jmp nt!ObRegisterCallbacks+0x1ad (fffff800`243ca4cd) Branchnt!ObRegisterCallbacks+0x973a8:fffff800`244616c8 49397e18 cmp qword ptr [r14+18h],rdifffff800`244616cc 0f84ae000000 je nt!ObRegisterCallbacks+0x97460 (fffff800`24461780) Branchnt!ObRegisterCallbacks+0x973b2:fffff800`244616d2 4885c9 test rcx,rcxfffff800`244616d5 0f84588df6ff je nt!ObRegisterCallbacks+0x113 (fffff800`243ca433) Branchnt!ObRegisterCallbacks+0x973bb:fffff800`244616db e9418df6ff jmp nt!ObRegisterCallbacks+0x101 (fffff800`243ca421) Branchnt!ObRegisterCallbacks+0x973c0:fffff800`244616e0 ba20000000 mov edx,20hfffff800`244616e5 e8e6dfb4ff call nt!MmVerifyCallbackFunctionCheckFlags (fffff800`23faf6d0)fffff800`244616ea 85c0 test eax,eaxfffff800`244616ec 0f854e8df6ff jne nt!ObRegisterCallbacks+0x120 (fffff800`243ca440) Branchnt!ObRegisterCallbacks+0x973d2:fffff800`244616f2 bb220000c0 mov ebx,0C0000022hnt!ObRegisterCallbacks+0x973d7:fffff800`244616f7 663b7e02 cmp di,word ptr [rsi+2]fffff800`244616fb 7370 jae nt!ObRegisterCallbacks+0x9744d (fffff800`2446176d) Branchnt!ObRegisterCallbacks+0x973dd:fffff800`244616fd bdb8000000 mov ebp,0B8hnt!ObRegisterCallbacks+0x973e2:fffff800`24461702 8bc7 mov eax,edifffff800`24461704 4c8d7620 lea r14,[rsi+20h]fffff800`24461708 48c1e006 shl rax,6fffff800`2446170c 4c03f0 add r14,raxfffff800`2446170f 65488b042588010000 mov rax,qword ptr gs:[188h]fffff800`24461718 66ff88e6010000 dec word ptr [rax+1E6h]fffff800`2446171f 498b4e20 mov rcx,qword ptr [r14+20h]fffff800`24461723 33d2 xor edx,edxfffff800`24461725 4803cd add rcx,rbpfffff800`24461728 e8433c9eff call nt!ExAcquirePushLockExclusiveEx (fffff800`23e45370)fffff800`2446172d 498b0e mov rcx,qword ptr [r14]fffff800`24461730 4c397108 cmp qword ptr [rcx+8],r14fffff800`24461734 7554 jne nt!ObRegisterCallbacks+0x9746a (fffff800`2446178a) Branchnt!ObRegisterCallbacks+0x97416:fffff800`24461736 498b4608 mov rax,qword ptr [r14+8]fffff800`2446173a 4c3930 cmp qword ptr [rax],r14fffff800`2446173d 754b jne nt!ObRegisterCallbacks+0x9746a (fffff800`2446178a) Branchnt!ObRegisterCallbacks+0x9741f:fffff800`2446173f 488908 mov qword ptr [rax],rcxfffff800`24461742 33d2 xor edx,edxfffff800`24461744 48894108 mov qword ptr [rcx+8],raxfffff800`24461748 498b4e20 mov rcx,qword ptr [r14+20h]fffff800`2446174c 4803cd add rcx,rbpfffff800`2446174f e81c419eff call nt!ExReleasePushLockEx (fffff800`23e45870)fffff800`24461754 65488b0c2588010000 mov rcx,qword ptr gs:[188h]fffff800`2446175d e80e409eff call nt!KiLeaveGuardedRegionUnsafe (fffff800`23e45770)fffff800`24461762 0fb74602 movzx eax,word ptr [rsi+2]fffff800`24461766 4103fd add edi,r13dfffff800`24461769 3bf8 cmp edi,eaxfffff800`2446176b 7295 jb nt!ObRegisterCallbacks+0x973e2 (fffff800`24461702) Branchnt!ObRegisterCallbacks+0x9744d:fffff800`2446176d ba4f62466c mov edx,6C46624Fhfffff800`24461772 488bce mov rcx,rsifffff800`24461775 e836591500 call nt!ExFreePool (fffff800`245b70b0)fffff800`2446177a 90 nopfffff800`2446177b e94b8df6ff jmp nt!ObRegisterCallbacks+0x1ab (fffff800`243ca4cb) Branchnt!ObRegisterCallbacks+0x97460:fffff800`24461780 bb0d0000c0 mov ebx,0C000000Dhfffff800`24461785 e9198df6ff jmp nt!ObRegisterCallbacks+0x183 (fffff800`243ca4a3) Branchnt!ObRegisterCallbacks+0x9746a:fffff800`2446178a b903000000 mov ecx,3fffff800`2446178f cd29 int 29hnt!ObRegisterCallbacks+0x97471:fffff800`24461791 b80d0000c0 mov eax,0C000000Dhfffff800`24461796 e9328df6ff jmp nt!ObRegisterCallbacks+0x1ad (fffff800`243ca4cd) BranchNTSTATUS ObUnRegisterCallbacks(PVOID RegistrationHandle) { POB_CALLBACK_HEADER Header = (POB_CALLBACK_HEADER)RegistrationHandle; USHORT i = 0; // 遍历所有回调项 while (i < Header->OperationCount) { POB_CALLBACK_ENTRY Entry = (POB_CALLBACK_ENTRY*)((PUCHAR)Header->Entries + i * 0x40); // 等待运行保护完成 ExWaitForRundownProtectionRelease(&Entry->RundownProtect); // 进入临界区并获取推锁 KeEnterCriticalRegion(); ExAcquirePushLockExclusiveEx(&Entry->Lock, 0); // 从全局链表安全移除 if (ValidateLinkedList(Entry)) { // 链表完整性校验 RemoveEntryList(&Entry->Link); InitializeListHead(&Entry->Link); // 防止野指针 } else { KeBugCheckEx(LIST_ENTRY_CORRUPT, 3, 0, 0, 0); } // 释放锁并离开临界区 ExReleasePushLockExclusiveEx(&Entry->Lock); KeLeaveCriticalRegion(); i++; } // 释放整个回调结构内存 ExFreePoolWithTag(Header, 'ObCf'); return STATUS_SUCCESS;}NTSTATUS ObUnRegisterCallbacks(PVOID RegistrationHandle) { POB_CALLBACK_HEADER Header = (POB_CALLBACK_HEADER)RegistrationHandle; USHORT i = 0; // 遍历所有回调项 while (i < Header->OperationCount) { POB_CALLBACK_ENTRY Entry = (POB_CALLBACK_ENTRY*)((PUCHAR)Header->Entries + i * 0x40); // 等待运行保护完成 ExWaitForRundownProtectionRelease(&Entry->RundownProtect); // 进入临界区并获取推锁 KeEnterCriticalRegion(); ExAcquirePushLockExclusiveEx(&Entry->Lock, 0); // 从全局链表安全移除 if (ValidateLinkedList(Entry)) { // 链表完整性校验 RemoveEntryList(&Entry->Link); InitializeListHead(&Entry->Link); // 防止野指针 } else { KeBugCheckEx(LIST_ENTRY_CORRUPT, 3, 0, 0, 0); } // 释放锁并离开临界区 ExReleasePushLockExclusiveEx(&Entry->Lock); KeLeaveCriticalRegion(); i++; } // 释放整个回调结构内存 ExFreePoolWithTag(Header, 'ObCf'); return STATUS_SUCCESS;}[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!
赞赏
- [原创]一个漏洞驱动利用以结束杀软进程 1879
- [原创]一个恶意驱动的逆向分析 12577
- [翻译]Beyond BIOS 第二章翻译 UEFI基础架构 949
- [原创]一个关于ntoskrnl内核内存泄漏问题复现与分析 1063
- [原创] 一种底层磁盘数据截获方法(附源码) 5137