windows线程创建流程
Posted zhuhuibeishadiao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了windows线程创建流程相关的知识,希望对你有一定的参考价值。
如果查看堆栈(正常的堆栈回溯)
所有线程的入口都是RtlUserThreadStart,
真正的流程如下.
包括远程线程 这里着重说明应用层,内核层不做具体描述.
CreateThread->ntdll!NtCreateThread(Ex)->内核设置上下文->回到被创建线程对应进程上下文ntdll!LdrInitializeThunk->ntdll!LdrpInitialize->ntdll!_LdrpInitialize->ntdll!LdrpInitializeThread->如果exe有Tls call LdrpCallTlsInitializers(2, LdrpImageEntry)没有忽略->ntdll!LdrpCallInitRoutine通知其它dll线程创建->ZwContrine->内核恢复上下文重设新线程入口点为ntdll!RtlUserThreadStart
然后线程就跑起来了
ntdll!RtlUserThreadStart->kernel32!BaseThreadInitThunk->call UserThreadEntry->ntdll!RtlExitUserThread->ntdll!ZwTerminateThread
监控应用层线程创建(无hook)
以下的接管代码中进程上下文都是要创建的线程上下文 直接获取当前线程就是要创建的线程,只是还没call到真正的入口函数
接着获取线程真正入口函数调用NtQueryInformationThread ->ThreadQuerySetWin32StartAddress功能获取入口地址进行过滤
1.利用dll通知 (写一个dll 专门用于监控线程创建 不调用DisableThreadLibraryCalls())
2.在主模块中 添加tls回调 或者手动插入LDR
快速得到LdrpImageEntry 这是一个LDR_DATA_TABLE_ENTRY结构
HMODULE hNtdll = GetModuleHandle(L"ntdll.dll");
pfnLdrFindEntryForAddress LdrFindEntryForAddress = (pfnLdrFindEntryForAddress)GetProcAddress(hNtdll, "LdrFindEntryForAddress");
LDR_DATA_TABLE_ENTRY* pEntry = NULL;
if (NT_SUCCESS(LdrFindEntryForAddress(GetModuleHandle(NULL), &pEntry)))
效果:这里我添加了VEH 从一个xxx里面抄的
00000001 0.00000000 //
00000002 0.00000270 Stack Number : 14 tid:2908
00000002 0.00000950 ntdll.dll:0x00007FF9C57E0000
00000003 0.00000100 call NtQueryInfortionThread
00000003 0.00000400 Stack[i]:0x00007FF63F02BB0F return to exe
00000004 0.00000500 Stack[i]:0x00007FF63F02AA2D return to exe
00000005 0.00000600 Stack[i]:0x00007FF6409C7272 return to exe
00000006 0.00000700 Stack[i]:0x00007FF640619548 return to exe
00000007 0.00000800 Stack[i]:0x00007FF9C587EDCD return to RtlpExecuteHandlerForException
00000008 0.00000910 Stack[i]:0x00007FF9C57E6C86 return to RtlDispatchException
00000009 0.00001010 Stack[i]:0x00007FF9C587DCFE return to KiUserExceptionDispatcher
00000010 0.00001110 Stack[i]:0x00007FF63F02A9EC return to exe
00000011 0.00001200 Stack[i]:0x00007FF9C5814143 return to LdrpCallInitRoutine
00000012 0.00001300 Stack[i]:0x00007FF9C581423F return to LdrpCallTlsInitializers(2, LdrpImageEntry)
00000013 0.00001420 Stack[i]:0x00007FF9C5811C78 return to LdrpInitializeThread
00000014 0.00001520 Stack[i]:0x00007FF9C58531E1 return to _LdrpInitialize
00000015 0.00001620 Stack[i]:0x00007FF9C585313B return to LdrpInitialize
00000016 0.00001750 Stack[i]:0x00007FF9C58530EE return to LdrInitializeThunk
00000017 0.00001850 //
3.替换Kernel32ThreadInitThunkFunctio指针
4.修改PEB里面的链表信息
4.1 模拟一个LDR_DATA_TABLE_ENTRY 插入PEB中
4.2 修改peb中一些系统的dll 入口点 比如kernel32 entrypoint
以上是关于windows线程创建流程的主要内容,如果未能解决你的问题,请参考以下文章