-
-
[原创]逆了下PsSetCreateProcessNotifyRoutine
-
发表于: 2013-4-17 13:28 4977
-
虽然看雪上已经有类似的帖子,但这确实是自己去做的,发出来分享下。
kd> u PsSetCreateProcessNotifyRoutine l50 nt!PsSetCreateProcessNotifyRoutine: 805d0c60 8bff mov edi,edi 805d0c62 55 push ebp 805d0c63 8bec mov ebp,esp 805d0c65 53 push ebx 805d0c66 33db xor ebx,ebx 805d0c68 385d0c cmp byte ptr [ebp+0Ch],bl //通过传入的第二个参数判断是添加回调还是移除回调 805d0c6b 56 push esi 805d0c6c 57 push edi 805d0c6d 7464 je nt!PsSetCreateProcessNotifyRoutine+0x73 (805d0cd3) //如果是添加回调函数,跳到(805d0cd3) 805d0c6f bf404a5680 mov edi,offset nt!PspCreateProcessNotifyRoutine (80564a40) 805d0c74 57 push edi //如果是移除回调函数 edi = PspCreateProcessNotifyRoutine 805d0c75 e86ad80300 call nt!ExReferenceCallBackBlock (8060e4e4) //释放回调块 805d0c7a 8bf0 mov esi,eax 805d0c7c 85f6 test esi,esi 805d0c7e 741f je nt!PsSetCreateProcessNotifyRoutine+0x3f (805d0c9f) //如果释放失败 跳(805d0c9f) 805d0c80 56 push esi 805d0c81 e8a201fdff call nt!ExGetCallBackBlockRoutine (805a0e28) //ExGetCallBackBlockRoutine 805d0c86 3b4508 cmp eax,dword ptr [ebp+8] //返回值与传入的 回调函数地址 做比较 805d0c89 750d jne nt!PsSetCreateProcessNotifyRoutine+0x38 (805d0c98) //如果不等跳(805d0c98) 805d0c8b 56 push esi 805d0c8c 6a00 push 0 805d0c8e 57 push edi 805d0c8f e884d70300 call nt!ExCompareExchangeCallBack (8060e418) //ExCompareExchangeCallBack 805d0c94 84c0 test al,al 805d0c96 7517 jne nt!PsSetCreateProcessNotifyRoutine+0x4f (805d0caf) //移除成功 805d0c98 56 push esi 805d0c99 57 push edi 805d0c9a e847d90300 call nt!ExDereferenceCallBackBlock (8060e5e6) //ExDereferenceCallBackBlock 805d0c9f 43 inc ebx 805d0ca0 83c704 add edi,4 805d0ca3 83fb08 cmp ebx,8 805d0ca6 72cc jb nt!PsSetCreateProcessNotifyRoutine+0x14 (805d0c74) 805d0ca8 b87a0000c0 mov eax,0C000007Ah 805d0cad eb64 jmp nt!PsSetCreateProcessNotifyRoutine+0xb3 (805d0d13) //函数结束 805d0caf b8604a5680 mov eax,offset nt!PspCreateProcessNotifyRoutineCount (80564a60) //全局变量PspCreateProcessNotifyRoutineCount 805d0cb4 83c9ff or ecx,0FFFFFFFFh 805d0cb7 f00fc108 lock xadd dword ptr [eax],ecx 805d0cbb 56 push esi 805d0cbc 8d049d404a5680 lea eax,nt!PspCreateProcessNotifyRoutine (80564a40)[ebx*4] 805d0cc3 50 push eax 805d0cc4 e81dd90300 call nt!ExDereferenceCallBackBlock (8060e5e6) 805d0cc9 56 push esi 805d0cca e813d60300 call nt!ExWaitForCallBacks (8060e2e2) 805d0ccf 33ff xor edi,edi 805d0cd1 eb38 jmp nt!PsSetCreateProcessNotifyRoutine+0xab (805d0d0b) //上面很明显有一个for循环 if(卸载回调函数) { ULONG edi = (ULONG)PspCreateProcessNotifyRoutine; for(int ebx=0;ebx<8;a+=4,ebx++,edi+=4) { int esi = ExReferenceCallBackBlock(edi); if(esi != 0) { int callback = ExGetCallBackBlockRoutine(esi); if(callback == 参数1) { if(ExCompareExchangeCallBack(edi,0,esi)) break; } ExDereferenceCallBackBlock(edi,esi); } } ULONG eax = (ULONG)PspCreateProcessNotifyRoutineCount; *(dword*)eax -= 1; } else(设置回调函数) { .... } 综合可见:PspCreateProcessNotifyRoutine是一个 8个长度的4字节数组 即:PspCreateProcessNotifyRoutine[8] 805d0cd3 53 push ebx //805d0c6d 跳到这里 开始添加系统回调 push 0 805d0cd4 ff7508 push dword ptr [ebp+8] //压入回调函数的地址 805d0cd7 e80cd70300 call nt!ExAllocateCallBack (8060e3e8) 805d0cdc 8bf0 mov esi,eax 805d0cde 3bf3 cmp esi,ebx //返回值与0比较 805d0ce0 7507 jne nt!PsSetCreateProcessNotifyRoutine+0x89 (805d0ce9) //不等于0 跳(805d0ce9) 805d0ce2 b89a0000c0 mov eax,0C000009Ah 805d0ce7 eb2a jmp nt!PsSetCreateProcessNotifyRoutine+0xb3 (805d0d13) //返回值等于0 函数结束 805d0ce9 bf404a5680 mov edi,offset nt!PspCreateProcessNotifyRoutine (80564a40) //805d0cde跳这里 edi=全局变量PspCreateProcessNotifyRoutine 805d0cee 6a00 push 0 805d0cf0 56 push esi 805d0cf1 57 push edi 805d0cf2 e821d70300 call nt!ExCompareExchangeCallBack (8060e418) //交换回调函数 805d0cf7 84c0 test al,al 805d0cf9 751f jne nt!PsSetCreateProcessNotifyRoutine+0xba (805d0d1a) //如果返回值不等于0 跳(805d0d1a),说明交换成功 805d0cfb 83c304 add ebx,4 805d0cfe 83c704 add edi,4 //ebx+=4 edi+=4 805d0d01 83fb20 cmp ebx,20h //如果ebx < 0x20 跳(805d0cee), 805d0d04 72e8 jb nt!PsSetCreateProcessNotifyRoutine+0x8e (805d0cee) //这里也是一个for循环 int routine = PspCreateProcessNotifyRoutine; for(int i=0;i<0x20;i+=4,routine+=4) { int result = ExCompareExchangeCallBack(routine,ExAllocateCallBack的返回值,0); if(result != 0) goto success; } 805d0d06 bf0d0000c0 mov edi,0C000000Dh 805d0d0b 56 push esi 805d0d0c e84d8c0100 call nt!ExFreeCallBack (805e995e) //for循环完毕 仍然没有交换成功,释放申请的CallBack 805d0d11 8bc7 mov eax,edi 805d0d13 5f pop edi 805d0d14 5e pop esi 805d0d15 5b pop ebx 805d0d16 5d pop ebp 805d0d17 c20800 ret 8 805d0d1a 33c9 xor ecx,ecx //交换回调函数成功跳这里 805d0d1c b8604a5680 mov eax,offset nt!PspCreateProcessNotifyRoutineCount (80564a60) //全局变量 PspCreateProcessNotifyRoutineCount 805d0d21 41 inc ecx 805d0d22 f00fc108 lock xadd dword ptr [eax],ecx //PspCreateProcessNotifyRoutineCount ++ 805d0d26 33c0 xor eax,eax 805d0d28 ebe9 jmp nt!PsSetCreateProcessNotifyRoutine+0xb3 (805d0d13) //跳回,然后函数完成返回 805d0d2a cc int 3
ULONG GetPspCreateProcessNotifyRoutineAddr() { ULONG pAddr = (ULONG)PsSetCreateProcessNotifyRoutine; BOOL bFind = FALSE; ULONG uRoutine = 0; PUCHAR pSet = (PUCHAR)pAddr; _asm { int 3 } for (int i=0;i<50;i++,pSet++) { if (*pSet == 0xbf && *(pSet+ 5) == 0x57 && *(pSet-2) == 0x74) { bFind = TRUE; break; } } if (bFind) { uRoutine = *((PULONG)(pSet+1)); KdPrint(("没有找到PspCreateThreadNotifyRoutine的地址\n")); }else{ KdPrint(("找到了PspCreateThreadNotifyRoutine的地址\n")); } return uRoutine; }
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏记录
参与人
雪币
留言
时间
伟叔叔
为你点赞~
2024-5-31 07:41
心游尘世外
为你点赞~
2024-5-31 04:37
QinBeast
为你点赞~
2024-5-31 04:30
飘零丶
为你点赞~
2024-4-3 00:16
shinratensei
为你点赞~
2024-2-5 05:46
一笑人间万事
为你点赞~
2023-3-7 00:34
赞赏
他的文章
- [求助]请问一下PE数字签名里面的PKCS#签名块解析方法 3058
- [讨论]自定义OBJECT_TYPE有什么用途 4297
- [求助]TCP包中的时间戳怎么添加 3698
- [求助]隐藏磁盘分区的方法有哪些? 3157
- [求助]硬盘使用次数,加电时间这些信息存在哪里 5331
看原图
赞赏
雪币:
留言: