当在内部调用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:包含线程的安全属性

在我的实现中,有专门的函数来处理以下每个任务:BaseCreateStackBaseInitializeContextBaseFormatObjectAttributes。有趣的是,BaseInitializeContext相反将线程的起始地址(即新进程的入口)放在CONTEXT.Eip中。并且BaseInitializeContext设置为CONTEXT.Eax的地址。 (由于CONTEXT.Eip在每个进程中都映射到相同的地址,因此我们知道这也是另一个进程中的BaseProcessStartThunk的地址。)在kernel32处执行BaseProcessStartThunk等于入口点的处理。

NtCreateThread保存寄存器BaseProcessStartThunk的起始地址。它通过使用eaxBaseProcessStartThunk调用eax在内部设置起始地址(请参阅NtSetInformationThread)。然后,它将调用起始地址。最后,当线程返回时,它将调用ThreadInformationClass

如何将可执行映像映射到新进程中? ,我们必须返回几步。

首先,通过ThreadQuerySetWin32StartAddress打开新流程可执行文件的句柄。

文件句柄用于创建节对象通过ntddk.h

调用ExitThread并将NtOpenFile设置为NtCreateSection。这将解析section对象并填写一个NtQuerySection结构,其中最值得注意的是包括InformationClass字段。这就是确定新进程的入口点的方式。

最终,将SectionImageInformation的节句柄作为参数,调用SECTION_IMAGE_INFORMATION。这实际上是创建新进程并将可执行映像映射到新进程的地址空间的原因。 EntryPoint还提供了传递给NtCreateProcessEx的进程句柄,以创建新线程。

评论


这很有趣,微软是第一个实施注入方法的;)

– 0xAK
16年6月18日在12:14

#2 楼

好的,因此ZwCreateThread在上下文结构中具有它(PCONTEXT + 0xB0)

用来接收地址的api调用如下: br /> CreateSection(..SectionInformation..)

此SectionInformation包含远程进程的EntryPoint的地址,稍后使用函数NtQuerySection(Handle, x, SectionInformation, x, x)初始化ThreadContext,然后使用_BaseInitializeContext@20 ...已全部在Windows XP下检查过,希望对某人有用