一.前言
实验环境是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;
}
四.运行结果
可以看到开起线程监控以后,所有线程的创建与销毁都被监控到了。而通过代码删除以后,则回调函数被删除,线程监控失效
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界
最后于 2021-10-22 20:28
被1900编辑
,原因: