首页
社区
课程
招聘
[原创]逆了下PsSetCreateProcessNotifyRoutine
发表于: 2013-4-17 13:28 4977

[原创]逆了下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;
}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 6
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//