CreateProcess
时,它将调用(显然是ZwCreateProcessEx
然后),将ZwCreateThread
设置为CreateSuspended
,然后调用True
,然后我假设最终初始化正在进行。之后它会调用ZwResumeThread
,然后一切都会正常进行。我的问题集中在
ZwCreateThread
函数上:http://undocumented.ntinternals.net/index.html?page = UserMode%2FUn documented%20Functions%2FNT%20Objects%2FThread%2FNtCreateThread.html ,是参数
CreateProcess
,我已经看到了几个NtAllocateVirtualMemory,其ThreadStartRoutine
的值为ThreadContext->EAX
,但是它们都没有为Protect
分配内存。因此,到底将线程入口点分配在哪里?#1 楼
免责声明:这些API的实现可能会在Windows版本之间发生变化。我将在回答中引用32位Windows XP SP3。您的结果可能会有所不同。线程创建的工作原理
在调用
NtCreateThread
之前必须初始化三个结构:INITIAL_TEB
:包含指向堆栈区域的指针CONTEXT
:包含寄存器状态OBJECT_ATTRIBUTES
:包含线程的安全属性在我的实现中,有专门的函数来处理以下每个任务:
BaseCreateStack
,BaseInitializeContext
和BaseFormatObjectAttributes
。有趣的是,BaseInitializeContext
相反将线程的起始地址(即新进程的入口)放在CONTEXT.Eip
中。并且BaseInitializeContext
设置为CONTEXT.Eax
的地址。 (由于CONTEXT.Eip
在每个进程中都映射到相同的地址,因此我们知道这也是另一个进程中的BaseProcessStartThunk
的地址。)在kernel32
处执行BaseProcessStartThunk
等于入口点的处理。NtCreateThread
保存寄存器BaseProcessStartThunk
的起始地址。它通过使用eax
的BaseProcessStartThunk
调用eax
在内部设置起始地址(请参阅NtSetInformationThread
)。然后,它将调用起始地址。最后,当线程返回时,它将调用ThreadInformationClass
。如何将可执行映像映射到新进程中? ,我们必须返回几步。
首先,通过
ThreadQuerySetWin32StartAddress
打开新流程可执行文件的句柄。文件句柄用于创建节对象通过
ntddk.h
。调用
ExitThread
并将NtOpenFile
设置为NtCreateSection
。这将解析section对象并填写一个NtQuerySection
结构,其中最值得注意的是包括InformationClass
字段。这就是确定新进程的入口点的方式。最终,将
SectionImageInformation
的节句柄作为参数,调用SECTION_IMAGE_INFORMATION
。这实际上是创建新进程并将可执行映像映射到新进程的地址空间的原因。 EntryPoint
还提供了传递给NtCreateProcessEx
的进程句柄,以创建新线程。#2 楼
好的,因此ZwCreateThread在上下文结构中具有它(PCONTEXT + 0xB0)用来接收地址的api调用如下: br />
CreateSection(..SectionInformation..)
此SectionInformation包含远程进程的EntryPoint的地址,稍后使用函数
NtQuerySection(Handle, x, SectionInformation, x, x)
初始化ThreadContext
,然后使用_BaseInitializeContext@20
...已全部在Windows XP下检查过,希望对某人有用
评论
这很有趣,微软是第一个实施注入方法的;)
– 0xAK
16年6月18日在12:14