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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值