当前位置: 首页 > news >正文

wordpress建站 评测广告接单有什么平台

wordpress建站 评测,广告接单有什么平台,抚顺网站seo,免费注册公众号在操作系统内核中#xff0c;DPC#xff08;Deferred Procedure Call#xff09;是一种延迟执行的过程调用机制#xff0c;用于在中断服务例程#xff08;ISR#xff09;的上下文之外执行一些工作。DPC定时器是基于DPC机制的一种定时执行任务的方式。 DPC定时器的主要特…在操作系统内核中DPCDeferred Procedure Call是一种延迟执行的过程调用机制用于在中断服务例程ISR的上下文之外执行一些工作。DPC定时器是基于DPC机制的一种定时执行任务的方式。 DPC定时器的主要特点 延迟执行 DPC定时器允许系统在未来的某个时间点执行一些操作而不是立即执行。这对于一些需要在中断处理例程之外执行的任务很有用以避免中断处理例程的执行时间过长。定时器机制 DPC定时器是基于时间的机制允许开发人员指定一个将来的时间点当系统时间达到该时间点时相关的DPC将被调度执行。这有助于实现定时任务例如定期执行某个函数或操作。中断上下文之外执行 DPC定时器通常在中断服务例程ISR之外执行以避免在ISR中执行过长时间的任务从而提高系统的响应性和稳定性。任务调度 DPC定时器允许内核将需要延迟执行的任务排队并在指定的时间点执行这些任务。这种任务调度机制有助于更有效地管理系统资源。 在笔者上一篇文章《内核枚举IoTimer定时器》中我们通过IoInitializeTimer这个API函数为跳板向下扫描特征码获取到了IopTimerQueueHead也就是IO定时器的队列头本章学习的枚举DPC定时器依然使用特征码扫描唯一不同的是在新版系统中DPC是被异或加密的想要找到正确的地址只是需要在找到DPC表头时进行解密操作即可。 DPC定时器的作用是什么 DPCDeferred Procedure Call是一种异步执行的机制。它允许内核代码在不中断当前进程的情况下延迟执行一些工作。DPC的执行是由内核定时器触发的。内核定时器是一种特殊的内核对象用于定时执行某个特定的操作。在DPC的上下文中内核可以安全地访问任何内核数据结构而不会引起死锁或其他问题。 在内核中可以使用DPC定时器设置任意定时任务当到达某个节点时自动触发定时回调定时器的内部使用KTIMER对象当设置任务时会自动插入到DPC队列由操作系统循环读取DPC队列并执行任务枚举DPC定时器可得知系统中存在的DPC任务。 要想在新版系统中得到DPC定时器则需要执行的步骤有哪些 1.找到KiProcessorBlock地址并解析成_KPRCB结构2.在_KPRCB结构中得到_KTIMER_TABLE偏移3.解析_KTIMER_TABLE_ENTRY得到加密后的双向链表 首先_KPRCB这个结构体与CPU内核对应获取方式可通过一个未导出的变量nt!KiProcessorBlock来得到如下双核电脑结构体存在两个与之对应的结构地址。 kd dq nt!KiProcessorBlock fffff80770a32cc0 fffff8076f77c180 ffffbe813cee0180 fffff80770a32cd0 0000000000000000 0000000000000000 fffff80770a32ce0 0000000000000000 0000000000000000此KiProcessorBlock是一个数组其第一个结构体TimerTable则是结构体的偏移。 kd dt _KPRCB fffff8076f77c180 ntdll!_KPRCB0x000 MxCsr : 0x1f800x3680 TimerTable : _KTIMER_TABLE (此处)0x5880 DpcGate : _KGATE接下来是把所有的KTIMER都枚举出来KTIMER在TimerTable中的存储方式是数组双向链表。 kd dt _KTIMER_TABLE ntdll!_KTIMER_TABLE0x000 TimerExpiry : [64] Ptr64 _KTIMER0x200 TimerEntries : [256] _KTIMER_TABLE_ENTRY (此处)到了_KTIMER_TABLE_ENTRY这里Entry开始的双向链表每一个元素都对应一个Timer也就是说我们已经可以遍历所有未解密的Time变量了。 kd dt _KTIMER_TABLE_ENTRY 0xfffff8076f77c180 0x3680 ntdll!_KTIMER_TABLE_ENTRY0x000 Lock : 00x008 Entry : _LIST_ENTRY [ 0x0000000000000000 - 0x0000000000000000 ]0x018 Time : _ULARGE_INTEGER 0x0kd dt _KTIMER_TABLE_ENTRY 0xfffff8076f77c180 0x3680 0x200 ntdll!_KTIMER_TABLE_ENTRY0x000 Lock : 00x008 Entry : _LIST_ENTRY [ 0xffffa707a0d3e1a0 - 0xffffa707a0d3e1a0 ]0x018 Time : _ULARGE_INTEGER 0x00000001a8030353至于如何解密我们需要得到加密位置如下通过KeSetTimer找到KeSetTimerEx从中得到DCP加密流程。 kd u nt!KeSetTimer nt!KeSetTimer: fffff8030fc63a40 4883ec38 sub rsp,38h fffff8030fc63a44 4c89442420 mov qword ptr [rsp20h],r8 fffff8030fc63a49 4533c9 xor r9d,r9d fffff8030fc63a4c 4533c0 xor r8d,r8d fffff8030fc63a4f e80c000000 call nt!KiSetTimerEx (fffff8030fc63a60) fffff8030fc63a54 4883c438 add rsp,38h fffff8030fc63a58 c3 ret fffff8030fc63a59 cc int 3kd u nt!KiSetTimerEx l50 nt!KiSetTimerEx: fffff8030fc63a60 48895c2408 mov qword ptr [rsp8],rbx fffff8030fc63a65 48896c2410 mov qword ptr [rsp10h],rbp fffff8030fc63a6a 4889742418 mov qword ptr [rsp18h],rsi fffff8030fc63a6f 57 push rdi fffff8030fc63a70 4154 push r12 fffff8030fc63a72 4155 push r13 fffff8030fc63a74 4156 push r14 fffff8030fc63a76 4157 push r15 fffff8030fc63a78 4883ec50 sub rsp,50h fffff8030fc63a7c 488b057d0c5100 mov rax,qword ptr [nt!KiWaitNever (fffff80310174700)] fffff8030fc63a83 488bf9 mov rdi,rcx fffff8030fc63a86 488b35630e5100 mov rsi,qword ptr [nt!KiWaitAlways (fffff803101748f0)] fffff8030fc63a8d 410fb6e9 movzx ebp,r9b fffff8030fc63a91 4c8bac24a0000000 mov r13,qword ptr [rsp0A0h] fffff8030fc63a99 458bf8 mov r15d,r8d fffff8030fc63a9c 4933f5 xor rsi,r13 fffff8030fc63a9f 488bda mov rbx,rdx fffff8030fc63aa2 480fce bswap rsi fffff8030fc63aa5 4833f1 xor rsi,rcx fffff8030fc63aa8 8bc8 mov ecx,eax fffff8030fc63aaa 48d3ce ror rsi,cl fffff8030fc63aad 4833f0 xor rsi,rax fffff8030fc63ab0 440f20c1 mov rcx,cr8 fffff8030fc63ab4 48898c24a0000000 mov qword ptr [rsp0A0h],rcx fffff8030fc63abc b802000000 mov eax,2 fffff8030fc63ac1 440f22c0 mov cr8,rax fffff8030fc63ac5 8b05dd0a5100 mov eax,dword ptr [nt!KiIrqlFlags (fffff803101745a8)] fffff8030fc63acb 85c0 test eax,eax fffff8030fc63acd 0f85b72d1a00 jne nt!KiSetTimerEx0x1a2e2a (fffff8030fe0688a) fffff8030fc63ad3 654c8b342520000000 mov r14,qword ptr gs:[20h] fffff8030fc63adc 33d2 xor edx,edx fffff8030fc63ade 488bcf mov rcx,rdi fffff8030fc63ae1 e86aa2fdff call nt!KiCancelTimer (fffff8030fc3dd50) fffff8030fc63ae6 440fb6e0 movzx r12d,al fffff8030fc63aea 48897730 mov qword ptr [rdi30h],rsi fffff8030fc63aee 33c0 xor eax,eax fffff8030fc63af0 44897f3c mov dword ptr [rdi3Ch],r15d fffff8030fc63af4 8b0f mov ecx,dword ptr [rdi] fffff8030fc63af6 4889442430 mov qword ptr [rsp30h],rax fffff8030fc63afb 894c2430 mov dword ptr [rsp30h],ecx fffff8030fc63aff 488bcb mov rcx,rbx fffff8030fc63b02 48c1e920 shr rcx,20h fffff8030fc63b06 4889442438 mov qword ptr [rsp38h],rax fffff8030fc63b0b 4889442440 mov qword ptr [rsp40h],rax fffff8030fc63b10 40886c2431 mov byte ptr [rsp31h],bpl fffff8030fc63b15 85c9 test ecx,ecx fffff8030fc63b17 0f89c0000000 jns nt!KiSetTimerEx0x17d (fffff8030fc63bdd) fffff8030fc63b1d 33c9 xor ecx,ecx fffff8030fc63b1f 8bd1 mov edx,ecx fffff8030fc63b21 40f6c5fc test bpl,0FCh fffff8030fc63b25 0f85a3000000 jne nt!KiSetTimerEx0x16e (fffff8030fc63bce) fffff8030fc63b2b 48894c2420 mov qword ptr [rsp20h],rcx fffff8030fc63b30 48b80800000080f7ffff mov rax,0FFFFF78000000008h fffff8030fc63b3a 4d8bc5 mov r8,r13 fffff8030fc63b3d 488b00 mov rax,qword ptr [rax] fffff8030fc63b40 804c243340 or byte ptr [rsp33h],40h fffff8030fc63b45 482bc3 sub rax,rbx fffff8030fc63b48 48894718 mov qword ptr [rdi18h],rax fffff8030fc63b4c 4803c2 add rax,rdx fffff8030fc63b4f 48c1e812 shr rax,12h fffff8030fc63b53 488bd7 mov rdx,rdi fffff8030fc63b56 440fb6c8 movzx r9d,al fffff8030fc63b5a 44884c2432 mov byte ptr [rsp32h],r9b fffff8030fc63b5f 8b442430 mov eax,dword ptr [rsp30h] fffff8030fc63b63 8907 mov dword ptr [rdi],eax fffff8030fc63b65 894f04 mov dword ptr [rdi4],ecx fffff8030fc63b68 498bce mov rcx,r14 fffff8030fc63b6b e8209ffdff call nt!KiInsertTimerTable (fffff8030fc3da90) fffff8030fc63b70 84c0 test al,al fffff8030fc63b72 0f8495000000 je nt!KiSetTimerEx0x1ad (fffff8030fc63c0d) fffff8030fc63b78 f7058608510000000200 test dword ptr [nt!PerfGlobalGroupMask0x8 (fffff80310174408)],20000h fffff8030fc63b82 0f852f2d1a00 jne nt!KiSetTimerEx0x1a2e57 (fffff8030fe068b7) fffff8030fc63b88 f081277fffffff lock and dword ptr [rdi],0FFFFFF7Fh fffff8030fc63b8f 488b8424a0000000 mov rax,qword ptr [rsp0A0h] fffff8030fc63b97 4533c9 xor r9d,r9d fffff8030fc63b9a 33d2 xor edx,edx fffff8030fc63b9c 88442420 mov byte ptr [rsp20h],al fffff8030fc63ba0 498bce mov rcx,r14 fffff8030fc63ba3 458d4101 lea r8d,[r91] fffff8030fc63ba7 e8044efeff call nt!KiExitDispatcher (fffff8030fc489b0)如上汇编代码KiSetTimerEx中就是DPC加密细节如果需要解密只需要逆操作即可此处我就具体分析下加密细节分析这个东西我建议你使用记事本带着色的。 分析思路是这样的首先这里要传入待加密的DPC数据然后经过KiWaitNever和KiWaitAlways对数据进行xor,ror,bswap等操作。 将如上所示的汇编解密流程通过C语言的方式实现解密函数DPC_Print过程可以被总结为如下几个流程 首先获取定时器结构体中Dpc成员的地址将其转换为ULONG_PTR类型的指针ptrDpc。 然后将ptrDpc异或上一个常量p2dq(ptrKiWaitNever)这个常量是KiWaitNever的指针地址强制转换为ULONG_PTR类型后的结果相当于异或上一个随机值来进行简单的加密。 然后将ptrDpc循环左移nShift位其中nShift的值为KiWaitNever指针值的低8位即取最后一个字节。 接着将ptrDpc异或上定时器结构体的地址相当于对加密结果进行一个简单的混淆。然后对ptrDpc进行字节交换相当于将ptrDpc的字节序进行翻转以便在后面的代码中能够正确地解密DPC结构体。最后将ptrDpc异或上一个常量p2dq(ptrKiWaitAlways)这个常量是KiWaitAlways的指针地址强制转换为ULONG_PTR类型后的结果相当于再进行一次简单的加密。 最后如果解密得到的DPC结构体指针DecDpc是一个有效的内核地址就输出该DPC的地址和它的延迟函数地址。其中DeferredRoutine是KDPC结构体的一个成员用于保存DPC的回调函数地址将上述流程通过代码方式实现则如下所示 #include ntddk.h #include ntstrsafe.h// 解密DPC void DPC_Print(PKTIMER ptrTimer) {ULONG_PTR ptrDpc (ULONG_PTR)ptrTimer-Dpc;KDPC* DecDpc NULL;DWORD nShift (p2dq(ptrKiWaitNever) 0xFF);// _RSI-Dpc (_KDPC *)v19;// _RSI Timer;ptrDpc ^ p2dq(ptrKiWaitNever); // v19 KiWaitNever ^ v18;ptrDpc _rotl64(ptrDpc, nShift); // v18 __ROR8__((unsigned __int64)Timer ^ _RBX, KiWaitNever);ptrDpc ^ (ULONG_PTR)ptrTimer;ptrDpc _byteswap_uint64(ptrDpc); // __asm { bswap rbx }ptrDpc ^ p2dq(ptrKiWaitAlways); // _RBX (unsigned __int64)DPC ^ KiWaitAlways;// real DPCif (MmIsAddressValid((PVOID)ptrDpc)){DecDpc (KDPC*)ptrDpc;DbgPrint(DPC %p | routine %p \n, DecDpc, DecDpc-DeferredRoutine);} }VOID UnDriver(PDRIVER_OBJECT driver) {DbgPrint(卸载完成... \n); }NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath) {DbgPrint(hello lyshark);PKTIMER ptrTimer NULL;DPC_Print(ptrTimer);Driver-DriverUnload UnDriver;return STATUS_SUCCESS; }接着将这些功能通过代码实现首先得到我们需要的函数地址这些地址包括。 ULONG_PTR ptrKiProcessorBlock 0xfffff80770a32cc0; ULONG_PTR ptrOffsetKTimerTable 0x3680; ULONG_PTR ptrKiWaitNever 0xfffff80770a316f8; ULONG_PTR ptrKiWaitAlways 0xfffff80770a318e8;此处我把它分为三步走第一步找到KiProcessorBlock函数地址第二步找到KeSetTimer并从里面寻找KeSetTimerEx第三步根据KiSetTimerEx地址搜索到KiWaitNever(),KiWaitAlways()这两个函数内存地址最终循环链表并解密DPC队列。 寻找KiProcessorBlock地址 找到KiProcessorBlock函数地址该地址可通过__readmsr()寄存器相加偏移得到。 在WinDBG中可以输入rdmsr c0000082得到MSR地址。 MSR寄存器使用代码获取也是很容易只要找到MSR地址在加上0x20即可得到KiProcessorBlock的地址了。 /*lyshark 0: kd dp !KiProcessorBlockfffff80770a32cc0 fffff8076f77c180 ffffbe813cee0180fffff80770a32cd0 0000000000000000 0000000000000000fffff80770a32ce0 0000000000000000 0000000000000000fffff80770a32cf0 0000000000000000 0000000000000000fffff80770a32d00 0000000000000000 0000000000000000fffff80770a32d10 0000000000000000 0000000000000000fffff80770a32d20 0000000000000000 0000000000000000fffff80770a32d30 0000000000000000 0000000000000000 */#include ntddk.h #include ntstrsafe.h// 得到KiProcessorBlock地址 ULONG64 GetKiProcessorBlock() {ULONG64 PrcbAddress 0;PrcbAddress (ULONG64)__readmsr(0xC0000101) 0x20;if (PrcbAddress ! 0){// PrcbAddress 是一个地址 这个地址存放了某个 CPU 的 _KPRCB 的地址return *(ULONG_PTR*)PrcbAddress;}return 0; }VOID UnDriver(PDRIVER_OBJECT driver) {DbgPrint(卸载完成... \n); }NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath) {DbgPrint(hello lyshark \n);ULONG64 address GetKiProcessorBlock();if (address ! 0){DbgPrint(KiProcessorBlock %p \n, address);}Driver-DriverUnload UnDriver;return STATUS_SUCCESS; }运行后即可得到输出效果如下 寻找KeSetTimer地址 找到KeSetTimer从里面搜索特征得到call KeSetTimerEx函数地址还记得《内核枚举IoTimer定时器》中我们采用的特征码定位方式吗没错本次还要使用这个方法我们此处需要搜索到e80c000000这段特征。 /*lyshark 0: kd uf KeSetTimernt!KeSetTimer:fffff80770520a30 4883ec38 sub rsp,38hfffff80770520a34 4c89442420 mov qword ptr [rsp20h],r8fffff80770520a39 4533c9 xor r9d,r9dfffff80770520a3c 4533c0 xor r8d,r8dfffff80770520a3f e80c000000 call nt!KiSetTimerEx (fffff80770520a50)fffff80770520a44 4883c438 add rsp,38hfffff80770520a48 c3 ret */#include ntddk.h #include ntstrsafe.h// 得到KiProcessorBlock地址 ULONG64 GetKeSetTimerEx() {// 获取 KeSetTimer 地址ULONG64 ul_KeSetTimer 0;UNICODE_STRING uc_KeSetTimer { 0 };RtlInitUnicodeString(uc_KeSetTimer, LKeSetTimer);ul_KeSetTimer (ULONG64)MmGetSystemRoutineAddress(uc_KeSetTimer);if (ul_KeSetTimer 0){return 0;}// 前 30 字节找 call 指令BOOLEAN b_e8 FALSE;ULONG64 ul_e8Addr 0;for (INT i 0; i 30; i){// 验证地址是否可读写if (!MmIsAddressValid((PVOID64)ul_KeSetTimer)){ continue;}// e8 0c 00 00 00 call nt!KiSetTimerEx (fffff80770520a50)if (*(PUCHAR)(ul_KeSetTimer i) 0xe8){b_e8 TRUE;ul_e8Addr ul_KeSetTimer i;break;}}// 找到 call 则解析目的地址if (b_e8 TRUE){if (!MmIsAddressValid((PVOID64)ul_e8Addr)){return 0;}INT ul_callCode *(INT*)(ul_e8Addr 1);ULONG64 ul_KiSetTimerEx ul_e8Addr ul_callCode 5;return ul_KiSetTimerEx;}return 0; }VOID UnDriver(PDRIVER_OBJECT driver) {DbgPrint(卸载完成... \n); }NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath) {DbgPrint(hello lyshark \n);ULONG64 address GetKeSetTimerEx();if (address ! 0){DbgPrint(KeSetTimerEx %p \n, address);}Driver-DriverUnload UnDriver;return STATUS_SUCCESS; }输出寻找CALL地址效果图如下 寻找KiWaitNever和KiWaitAlways地址 也是最重要的一步在KiSetTimerEx里面搜索特征拿到里面的KiWaitNever(),KiWaitAlways()这两个函数地址。 488b05850c5100 KiWaitNever488b356b0e5100 KiWaitAlways 这个过程需要重复搜索所以要把第一步和第二部过程归纳起来具体代码如下所示。 /*0: kd uf KiSetTimerExnt!KiSetTimerEx:fffff80770520a50 48895c2408 mov qword ptr [rsp8],rbxfffff80770520a55 48896c2410 mov qword ptr [rsp10h],rbpfffff80770520a5a 4889742418 mov qword ptr [rsp18h],rsifffff80770520a5f 57 push rdifffff80770520a60 4154 push r12fffff80770520a62 4155 push r13fffff80770520a64 4156 push r14fffff80770520a66 4157 push r15fffff80770520a68 4883ec50 sub rsp,50hfffff80770520a6c 488b05850c5100 mov rax,qword ptr [nt!KiWaitNever (fffff80770a316f8)]fffff80770520a73 488bf9 mov rdi,rcxfffff80770520a76 488b356b0e5100 mov rsi,qword ptr [nt!KiWaitAlways (fffff80770a318e8)]fffff80770520a7d 410fb6e9 movzx ebp,r9b */#include ntddk.h #include ntstrsafe.h// 得到KiProcessorBlock地址 ULONG64 GetKeSetTimerEx() {// 获取 KeSetTimer 地址ULONG64 ul_KeSetTimer 0;UNICODE_STRING uc_KeSetTimer { 0 };RtlInitUnicodeString(uc_KeSetTimer, LKeSetTimer);ul_KeSetTimer (ULONG64)MmGetSystemRoutineAddress(uc_KeSetTimer);if (ul_KeSetTimer 0){return 0;}// 前 30 字节找 call 指令BOOLEAN b_e8 FALSE;ULONG64 ul_e8Addr 0;for (INT i 0; i 30; i){// 验证地址是否可读写if (!MmIsAddressValid((PVOID64)ul_KeSetTimer)){ continue;}// e8 0c 00 00 00 call nt!KiSetTimerEx (fffff80770520a50)if (*(PUCHAR)(ul_KeSetTimer i) 0xe8){b_e8 TRUE;ul_e8Addr ul_KeSetTimer i;break;}}// 找到 call 则解析目的地址if (b_e8 TRUE){if (!MmIsAddressValid((PVOID64)ul_e8Addr)){return 0;}INT ul_callCode *(INT*)(ul_e8Addr 1);ULONG64 ul_KiSetTimerEx ul_e8Addr ul_callCode 5;return ul_KiSetTimerEx;}return 0; }// 得到KiWaitNever地址 ULONG64 GetKiWaitNever(ULONG64 address) {// 验证地址是否可读写if (!MmIsAddressValid((PVOID64)address)){return 0;}// 前 100 字节找 找 KiWaitNeverfor (INT i 0; i 100; i){// 48 8b 05 85 0c 51 00 | mov rax, qword ptr[nt!KiWaitNever(fffff80770a316f8)]if (*(PUCHAR)(address i) 0x48 *(PUCHAR)(address i 1) 0x8b *(PUCHAR)(address i 2) 0x05){ULONG64 ul_movCode *(UINT32*)(address i 3);ULONG64 ul_movAddr address i ul_movCode 7;// DbgPrint(找到KiWaitNever地址: %p \n, ul_movAddr);return ul_movAddr;}}return 0; }// 得到KiWaitAlways地址 ULONG64 GetKiWaitAlways(ULONG64 address) {// 验证地址是否可读写if (!MmIsAddressValid((PVOID64)address)){return 0;}// 前 100 字节找 找 KiWaitNeverfor (INT i 0; i 100; i){// 48 8b 35 6b 0e 51 00 | mov rsi,qword ptr [nt!KiWaitAlways (fffff80770a318e8)]if (*(PUCHAR)(address i) 0x48 *(PUCHAR)(address i 1) 0x8b *(PUCHAR)(address i 2) 0x35){ULONG64 ul_movCode *(UINT32*)(address i 3);ULONG64 ul_movAddr address i ul_movCode 7;return ul_movAddr;}}return 0; }VOID UnDriver(PDRIVER_OBJECT driver) {DbgPrint(卸载完成... \n); }NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath) {DbgPrint(hello lyshark \n);ULONG64 address GetKeSetTimerEx();if (address ! 0){ULONG64 KiWaitNeverAddress GetKiWaitNever(address);DbgPrint(KiWaitNeverAddress %p \n, KiWaitNeverAddress);ULONG64 KiWaitAlwaysAddress GetKiWaitAlways(address);DbgPrint(KiWaitAlwaysAddress %p \n, KiWaitAlwaysAddress);}Driver-DriverUnload UnDriver;return STATUS_SUCCESS; }运行这个程序我们看下寻找到的地址是否与WinDBG中找到的地址一致。 实现枚举DPCTimer 最后将这些功能整合在一起循环输出链表元素并解密元素即可实现枚举当前系统DPC定时器。 代码核心API分析 KeNumberProcessors 得到CPU数量(内核常量)KeSetSystemAffinityThread 线程绑定到特定CPU上GetKiProcessorBlock 获得KPRCB的地址KeRevertToUserAffinityThread 取消绑定CPU 解密部分提取出KiWaitNever和KiWaitAlways用于解密计算转换PKDPC对象结构并输出即可。 #include Fltkernel.h #include ntddk.h #include intrin.h#define IRP_TEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)UNICODE_STRING name_device; // 设备名 UNICODE_STRING name_symbol; // 符号链接 PDEVICE_OBJECT deviceObj; // 设备对象typedef struct _KTIMER_TABLE_ENTRY {ULONG_PTR Lock;LIST_ENTRY Entry;ULONG_PTR Time; }KTIMER_TABLE_ENTRY, *PKTIMER_TABLE_ENTRY;typedef struct _KTIMER_TABLE {ULONG_PTR TimerExpiry[64];KTIMER_TABLE_ENTRY TimerEntries[256]; }KTIMER_TABLE, *PKTIMER_TABLE;BOOLEAN get_KiWait(PULONG64 never, PULONG64 always) {// 获取 KeSetTimer 地址ULONG64 ul_KeSetTimer 0;UNICODE_STRING uc_KeSetTimer { 0 };RtlInitUnicodeString(uc_KeSetTimer, LKeSetTimer);ul_KeSetTimer (ULONG64)MmGetSystemRoutineAddress(uc_KeSetTimer);if (ul_KeSetTimer NULL){return FALSE;}// 前 30 字节找 call 指令BOOLEAN b_e8 FALSE;ULONG64 ul_e8Addr 0;for (INT i 0; i 30; i){if (!MmIsAddressValid((PVOID64)ul_KeSetTimer)){continue;}/*0: kd u nt!KeSetTimernt!KeSetTimer:fffff8030fc63a40 4883ec38 sub rsp,38hfffff8030fc63a44 4c89442420 mov qword ptr [rsp20h],r8fffff8030fc63a49 4533c9 xor r9d,r9dfffff8030fc63a4c 4533c0 xor r8d,r8dfffff8030fc63a4f e80c000000 call nt!KiSetTimerEx (fffff8030fc63a60)fffff8030fc63a54 4883c438 add rsp,38hfffff8030fc63a58 c3 retfffff8030fc63a59 cc int 3*/// fffff8030fc63a4f e8 0c 00 00 00 call nt!KiSetTimerEx (fffff8030fc63a60)if (*(PUCHAR)(ul_KeSetTimer i) 0xe8){b_e8 TRUE;ul_e8Addr ul_KeSetTimer i;break;}}// 找到 call 则解析目的地址/*0: kd u nt!KiSetTimerEx l20nt!KiSetTimerEx:fffff8030fc63a60 48895c2408 mov qword ptr [rsp8],rbxfffff8030fc63a65 48896c2410 mov qword ptr [rsp10h],rbpfffff8030fc63a6a 4889742418 mov qword ptr [rsp18h],rsifffff8030fc63a6f 57 push rdifffff8030fc63a70 4154 push r12fffff8030fc63a72 4155 push r13fffff8030fc63a74 4156 push r14fffff8030fc63a76 4157 push r15fffff8030fc63a78 4883ec50 sub rsp,50hfffff8030fc63a7c 488b057d0c5100 mov rax,qword ptr [nt!KiWaitNever (fffff80310174700)]fffff8030fc63a83 488bf9 mov rdi,rcx*/ULONG64 ul_KiSetTimerEx 0;if (b_e8 TRUE){if (!MmIsAddressValid((PVOID64)ul_e8Addr)){return FALSE;}INT ul_callCode *(INT*)(ul_e8Addr 1);ULONG64 ul_callAddr ul_e8Addr ul_callCode 5;ul_KiSetTimerEx ul_callAddr;}// 没有 call 则直接在当前函数找 else{ul_KiSetTimerEx ul_KeSetTimer;}// 前 50 字节找 找 KiWaitNever 和 KiWaitAlways/*0: kd u nt!KiSetTimerEx l20nt!KiSetTimerEx:fffff8030fc63a60 48895c2408 mov qword ptr [rsp8],rbxfffff8030fc63a65 48896c2410 mov qword ptr [rsp10h],rbpfffff8030fc63a6a 4889742418 mov qword ptr [rsp18h],rsifffff8030fc63a6f 57 push rdifffff8030fc63a70 4154 push r12fffff8030fc63a72 4155 push r13fffff8030fc63a74 4156 push r14fffff8030fc63a76 4157 push r15fffff8030fc63a78 4883ec50 sub rsp,50hfffff8030fc63a7c 488b057d0c5100 mov rax,qword ptr [nt!KiWaitNever (fffff80310174700)]fffff8030fc63a83 488bf9 mov rdi,rcxfffff8030fc63a86 488b35630e5100 mov rsi,qword ptr [nt!KiWaitAlways (fffff803101748f0)]*/if (!MmIsAddressValid((PVOID64)ul_KiSetTimerEx)){return FALSE;}ULONG64 ul_arr_ret[2]; // 存放 KiWaitNever 和 KiWaitAlways 的地址INT i_sub 0; // 对应 ul_arr_ret 的下标for (INT i 0; i 50; i){// // fffff8030fc63a7c 488b057d0c5100 mov rax,qword ptr [nt!KiWaitNever (fffff80310174700)]if (*(PUCHAR)(ul_KiSetTimerEx i) 0x48 *(PUCHAR)(ul_KiSetTimerEx i 1) 0x8b *(PUCHAR)(ul_KiSetTimerEx i 6) 0x00){ULONG64 ul_movCode *(UINT32*)(ul_KiSetTimerEx i 3);ULONG64 ul_movAddr ul_KiSetTimerEx i ul_movCode 7;// 只拿符合条件的前两个值if (i_sub 2){ul_arr_ret[i_sub] ul_movAddr;}}}*never ul_arr_ret[0];*always ul_arr_ret[1];return TRUE; }BOOLEAN EnumDpc() {DbgPrint(hello lyshark \n);// 获取 CPU 核心数INT i_cpuNum KeNumberProcessors;DbgPrint(CPU核心数: %d \n, i_cpuNum);for (KAFFINITY i 0; i i_cpuNum; i){// 线程绑定特定 CPUKeSetSystemAffinityThread(i 1);// 获得 KPRCB 的地址ULONG64 p_PRCB (ULONG64)__readmsr(0xC0000101) 0x20;if (!MmIsAddressValid((PVOID64)p_PRCB)){return FALSE;}// 取消绑定 CPUKeRevertToUserAffinityThread();// 计算 TimerTable 在 _KPRCB 结构中的偏移PKTIMER_TABLE p_TimeTable NULL;// Windows 10 得到_KPRCB 0x3680p_TimeTable (PKTIMER_TABLE)(*(PULONG64)p_PRCB 0x3680);// 遍历 TimerEntries[] 数组大小 256for (INT j 0; j 256; j){// 获取 Entry 双向链表地址if (!MmIsAddressValid((PVOID64)p_TimeTable)){continue;}PLIST_ENTRY p_ListEntryHead (p_TimeTable-TimerEntries[j].Entry);// 遍历 Entry 双向链表for (PLIST_ENTRY p_ListEntry p_ListEntryHead-Flink; p_ListEntry ! p_ListEntryHead; p_ListEntry p_ListEntry-Flink){// 根据 Entry 取 _KTIMER 对象地址if (!MmIsAddressValid((PVOID64)p_ListEntry)){continue;}PKTIMER p_Timer CONTAINING_RECORD(p_ListEntry, KTIMER, TimerListEntry);// 硬编码取 KiWaitNever 和 KiWaitAlways ULONG64 never 0, always 0;if (get_KiWait(never, always) FALSE){return FALSE;}// 获取解密前的 Dpc 对象if (!MmIsAddressValid((PVOID64)p_Timer)){continue;}ULONG64 ul_Dpc (ULONG64)p_Timer-Dpc;INT i_Shift (*((PULONG64)never) 0xFF);// 解密 Dpc 对象ul_Dpc ^ *((ULONG_PTR*)never); // 异或ul_Dpc _rotl64(ul_Dpc, i_Shift); // 循环左移ul_Dpc ^ (ULONG_PTR)p_Timer; // 异或ul_Dpc _byteswap_uint64(ul_Dpc); // 颠倒顺序ul_Dpc ^ *((ULONG_PTR*)always); // 异或// 对象类型转换PKDPC p_Dpc (PKDPC)ul_Dpc;// 打印验证if (!MmIsAddressValid((PVOID64)p_Dpc)){continue;}DbgPrint(定时器对象0x%p | 函数入口0x%p | 触发周期: %d \n , p_Timer, p_Dpc-DeferredRoutine, p_Timer-Period);}}}return TRUE; }// 对应 IRP_MJ_DEVICE_CONTROL NTSTATUS myIrpControl(IN PDEVICE_OBJECT pDevObj, IN PIRP pIRP) {// 获取 IRP 对应的 I/O 堆栈指针PIO_STACK_LOCATION stack IoGetCurrentIrpStackLocation(pIRP);// 得到输入缓冲区大小ULONG cbin stack-Parameters.DeviceIoControl.InputBufferLength;// 得到输出缓冲区大小ULONG cbout stack-Parameters.DeviceIoControl.OutputBufferLength;// 得到 IOCTL 码ULONG code stack-Parameters.DeviceIoControl.IoControlCode;// 捕获 I/O 操作类型MajorFunctionswitch (code){case IRP_TEST:{break;}default:break;}// 完成 IO 请求IoCompleteRequest(pIRP, IO_NO_INCREMENT);return STATUS_SUCCESS; }// 对应 IRP_MJ_CREATE 、 IRP_MJ_CLOSE NTSTATUS dpc_CAC(IN PDEVICE_OBJECT pDevObj, IN PIRP pIRP) {// 将 IRP 返回给 I/O 管理器IoCompleteRequest(pIRP, // IRP 指针IO_NO_INCREMENT // 线程优先级IO_NO_INCREMENT 不增加优先级);// 设置 I/O 请求状态pIRP-IoStatus.Status STATUS_SUCCESS;// 设置 I/O 请求传输的字节数pIRP-IoStatus.Information 0;return STATUS_SUCCESS; }NTSTATUS CreateDevice(IN PDRIVER_OBJECT DriverObject) {// 定义返回值NTSTATUS status;// 初始化设备名RtlInitUnicodeString(name_device, L\\Device\\LySharkDriver);// 创建设备status IoCreateDevice(DriverObject, // 指向驱动对象的指针0, // 设备扩展分配的字节数name_device, // 设备名FILE_DEVICE_UNKNOWN, // 设备类型0, // 驱动设备附加信息TRUE, // 设备对象是否独占设备deviceObj // 设备对象指针 );if (!NT_SUCCESS(status)){return status;}// 初始化符号链接名RtlInitUnicodeString(name_symbol, L\\??\\LySharkDriver);// 创建符号链接status IoCreateSymbolicLink(name_symbol, name_device);if (!NT_SUCCESS(status)){return status;}return STATUS_SUCCESS; }NTSTATUS DriverUnload(IN PDRIVER_OBJECT DriverObject) {// 定义返回值NTSTATUS status;// 删除符号链接status IoDeleteSymbolicLink(name_symbol);if (!NT_SUCCESS(status)){return status;}// 删除设备IoDeleteDevice(deviceObj);return STATUS_SUCCESS; }NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) {// 定义返回值NTSTATUS status;// 指定驱动卸载函数DriverObject-DriverUnload (PDRIVER_UNLOAD)DriverUnload;// 指定派遣函数DriverObject-MajorFunction[IRP_MJ_CREATE] dpc_CAC;DriverObject-MajorFunction[IRP_MJ_CLOSE] dpc_CAC;DriverObject-MajorFunction[IRP_MJ_DEVICE_CONTROL] myIrpControl;// 创建设备status CreateDevice(DriverObject);if (!NT_SUCCESS(status)){return status;}// 执行枚举EnumDpc();return STATUS_SUCCESS; }最终运行枚举程序你将会看到系统中所有的定时器与ARK工具对比是一致的。
http://www.pierceye.com/news/337351/

相关文章:

  • 做化工的在哪个网站做平台好长期做网站应该购买稳定的空间
  • 网站建设 推广找山东博达制作网页难吗
  • 临安网站设计海口h5建站模板
  • 网站建设济南云畅网络技术有限公司厦门最新通告
  • ozon电商平台seo关键词搜索和优化
  • 网站收录查询情况科技网站导航
  • 如何做有后台的网站模板网站和定制网站的优劣势对比
  • 在360网站做公告怎么弄南平建设企业网站
  • 网站建设电影动漫制作专业什么电脑最适合
  • 企业做网站公司有哪些wordpress登陆不了一直返回首页
  • 汽车网站建设公司哪家好长春做网站多少钱
  • 雄安移动网站建设php网站用什么软件
  • 网站开发税收分类山东平台网站建设制作
  • 企业自助建站网手机怎么制作钓鱼网站
  • 家乡ppt模板免费下载网站x wordpress 视差 主题
  • 淄博张店外贸建站公司手机微信网页版
  • 网站建设全域云网站建设流程详解
  • 梅州市五华县建设银行网站写作网站招聘
  • 博物馆网站建设情况工业互联网龙头公司排名
  • 做网站用什么系统做网站开发电脑配置
  • 企业网站推广的主要方法上海中汇建设发展有限公司网站
  • 郑州做网站公司电话网站是否有管理员权限
  • 开发建设信息的网站广东省建设厅的注册中心网站首页
  • 用cms做的网站 的步骤有域名如何做网站
  • h5个人网站源码江苏启安建设集团有限公司网站
  • 网站开发net教程网站后台登陆路径
  • 织梦网站模板安装教程国外设计有名网站
  • 最专业企业营销型网站建设南充 网站开发
  • 国外有哪些网站做推广的比较好北京展览馆网站建设
  • 国外英语写作网站网站后台 刷新