首页
论坛
课程
招聘
[原创]通过对PsSetCreateThreadNotifyRoutine的逆向分析得出的结果来实现反线程监控
2021-10-22 20:27 14817

[原创]通过对PsSetCreateThreadNotifyRoutine的逆向分析得出的结果来实现反线程监控

2021-10-22 20:27
14817

一.前言

实验环境是WIN7 X86。之前写出一篇反进程监控的文章,通过对PsSetCreateProcessNotifyRoutineEx的逆向分析得出的结果来实现反进程监控

本文通过对PsSetCreateThreadNotifyRoutine的逆向来实现反线程监控

二.逆向分析PsSetCreateThreadNotifyRoutine

在IDA中查看PsSetCreateThreadNotifyRoutine的反汇编代码如下

PAGE:006DF4A7 ; NTSTATUS __stdcall PsSetCreateThreadNotifyRoutine(PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine)
PAGE:006DF4A7                 public PsSetCreateThreadNotifyRoutine
PAGE:006DF4A7 PsSetCreateThreadNotifyRoutine proc near
PAGE:006DF4A7
PAGE:006DF4A7 NotifyRoutine   = dword ptr  8
PAGE:006DF4A7
PAGE:006DF4A7                 mov     edi, edi
PAGE:006DF4A9                 push    ebp
PAGE:006DF4AA                 mov     ebp, esp
PAGE:006DF4AC                 push    ebx
PAGE:006DF4AD                 push    edi
PAGE:006DF4AE                 xor     edi, edi
PAGE:006DF4B0                 push    edi
PAGE:006DF4B1                 push    [ebp+NotifyRoutine]
PAGE:006DF4B4                 call    AllocateAssign
PAGE:006DF4B9                 mov     ebx, eax
PAGE:006DF4BB                 cmp     ebx, edi
PAGE:006DF4BD                 jnz     short loc_6DF4C6
PAGE:006DF4BF                 mov     eax, STATUS_INSUFFICIENT_RESOURCES
PAGE:006DF4C4                 jmp     short loc_6DF4F5
PAGE:006DF4C6 ; ---------------------------------------------------------------------------
PAGE:006DF4C6
PAGE:006DF4C6 loc_6DF4C6:                             ; CODE XREF: PsSetCreateThreadNotifyRoutine+16↑j
PAGE:006DF4C6                 push    esi
PAGE:006DF4C7                 mov     esi, offset ThreadArray
PAGE:006DF4CC
PAGE:006DF4CC loc_6DF4CC:                             ; CODE XREF: PsSetCreateThreadNotifyRoutine+40↓j
PAGE:006DF4CC                 push    0
PAGE:006DF4CE                 mov     ecx, ebx
PAGE:006DF4D0                 mov     eax, esi
PAGE:006DF4D2                 call    SetArray
PAGE:006DF4D7                 test    al, al
PAGE:006DF4D9                 jnz     short loc_6DF4FB
PAGE:006DF4DB                 add     edi, 4
PAGE:006DF4DE                 add     esi, 4
PAGE:006DF4E1                 cmp     edi, 100h
PAGE:006DF4E7                 jb      short loc_6DF4CC
PAGE:006DF4E9                 push    ebx             ; Buffer
PAGE:006DF4EA                 call    FreeAllocate
PAGE:006DF4EF                 mov     eax, STATUS_INSUFFICIENT_RESOURCES
PAGE:006DF4F4
PAGE:006DF4F4 loc_6DF4F4:                             ; CODE XREF: PsSetCreateThreadNotifyRoutine+75↓j
PAGE:006DF4F4                 pop     esi
PAGE:006DF4F5
PAGE:006DF4F5 loc_6DF4F5:                             ; CODE XREF: PsSetCreateThreadNotifyRoutine+1D↑j
PAGE:006DF4F5                 pop     edi
PAGE:006DF4F6                 pop     ebx
PAGE:006DF4F7                 pop     ebp
PAGE:006DF4F8                 retn    4
PAGE:006DF4FB ; ---------------------------------------------------------------------------
PAGE:006DF4FB
PAGE:006DF4FB loc_6DF4FB:                             ; CODE XREF: PsSetCreateThreadNotifyRoutine+32↑j
PAGE:006DF4FB                 xor     ecx, ecx
PAGE:006DF4FD                 mov     eax, offset unk_542CC0
PAGE:006DF502                 inc     ecx
PAGE:006DF503                 lock xadd [eax], ecx
PAGE:006DF507                 mov     eax, dword_542B78
PAGE:006DF50C                 test    al, 8
PAGE:006DF50E                 jnz     short loc_6DF51A
PAGE:006DF510                 mov     eax, offset dword_542B78
PAGE:006DF515                 lock bts dword ptr [eax], 3
PAGE:006DF51A
PAGE:006DF51A loc_6DF51A:                             ; CODE XREF: PsSetCreateThreadNotifyRoutine+67↑j
PAGE:006DF51A                 xor     eax, eax
PAGE:006DF51C                 jmp     short loc_6DF4F4
PAGE:006DF51C PsSetCreateThreadNotifyRoutine endp

发现和PsSetCreateProcessNotifyRoutineEx的实现不能说很像只能说一摸一样。那就不再叙述了,看上面那篇就好

三.反线程监控代码实现

下图中可以得知,从PsSetCreateThreadNotifyRoutine中将0x56BE作为特征码即可找到线程数组

接下来就是具体实现代码

NTSTATUS DriverEntry(IN PDRIVER_OBJECT driverObject, IN PUNICODE_STRING registryPath)
{
	NTSTATUS status = STATUS_SUCCESS;
	PULONG pThreadArray = NULL;
	PULONG pFuncAddr = NULL;
	ULONG i = 0;

	pThreadArray = GetThreadArray();
	if (pThreadArray)
	{
		for (i = 0; i < 0x40; i++)
		{
			if (pThreadArray[i] & ~0x7)
			{
				pFuncAddr = (PULONG)((pThreadArray[i] & ~0x7) + 4);
				status = PsRemoveCreateThreadNotifyRoutine((PCREATE_THREAD_NOTIFY_ROUTINE)*pFuncAddr);
				if (NT_SUCCESS(status))
				{
					DbgPrint("线程回调函数删除成功,地址是0x%X\r\n", *pFuncAddr);
				}
			}
		}
	}
exit:
	driverObject->DriverUnload = DriverUnload;
	return STATUS_SUCCESS;
}

PULONG GetThreadArray()
{
	PULONG pThreadArray = NULL;
	//要获取的函数地址的函数名
	UNICODE_STRING uStrFuncName = RTL_CONSTANT_STRING(L"PsSetCreateThreadNotifyRoutine");
	PUCHAR pPsSetCreateThreadNotifyRoutine = NULL;

	//获取函数地址
	pPsSetCreateThreadNotifyRoutine = (PUCHAR)MmGetSystemRoutineAddress(&uStrFuncName);
	while (*pPsSetCreateThreadNotifyRoutine != 0xC2)
	{
		if (*pPsSetCreateThreadNotifyRoutine == 0x56 && *(pPsSetCreateThreadNotifyRoutine + 1) == 0xBE)
		{
			pThreadArray = (PULONG)*(PULONG)(pPsSetCreateThreadNotifyRoutine + 2);
			break;
		}
		pPsSetCreateThreadNotifyRoutine++;
	}

	return pThreadArray;
}

四.运行结果

可以看到开起线程监控以后,所有线程的创建与销毁都被监控到了。而通过代码删除以后,则回调函数被删除,线程监控失效


[公告] 欢迎大家踊跃尝试高研班11月试题,挑战自己的极限!

最后于 2021-10-22 20:28 被1900编辑 ,原因:
收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回