NtCreateProcess(Ex) - 我可以让子进程在不同的进程名称下运行时继承父地址空间吗? [英] NtCreateProcess(Ex) - Can I have a child process inherit the parents address space while running under a different process name?

查看:61
本文介绍了NtCreateProcess(Ex) - 我可以让子进程在不同的进程名称下运行时继承父地址空间吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在调用 NtCreateProcessEx 并将节句柄参数设置为 NULL,以便创建一个用户模式进程,该进程使用父地址空间的副本进行初始化.

I am calling NtCreateProcessEx with the section handle argument set to NULL in order to create a user mode process that is initialized with a copy of the parents address space.

我希望子进程以不同于父进程的映像名称运行.

I want the child process to run under a different image name other than the one of the parent process.

这甚至可能吗?

这是我对 NtCreateProcessEx 的调用:

Here's my call to NtCreateProcessEx:

HANDLE fileHandle;
OBJECT_ATTRIBUTES ObjectAttributes = { 0 };

UNICODE_STRING InputString;

RtlInitUnicodeString( &InputString, L"C:\\Users\\user\\Documents\\codeblocks_projects\\test\\bin\\Release\\test.exe" );

ObjectAttributes.Length = sizeof( OBJECT_ATTRIBUTES );
ObjectAttributes.ObjectName = &InputString;

NTSTATUS status = NtCreateProcessEx( &fileHandle, PROCESS_QUERY_INFORMATION, &ObjectAttributes, GetCurrentProcess(), PS_INHERIT_HANDLES, NULL, NULL, NULL, FALSE );

printf_s( "%x\n", status );

状态是 0xC0000033 - STATUS_OBJECT_NAME_INVALID,如果我不传递任何对象属性,调用工作正常.

Status is 0xC0000033 - STATUS_OBJECT_NAME_INVALID, if I don't pass any object attributes, the call works fine.

我在这里遗漏了什么?

推荐答案

我的猜测是,这不仅记录不佳;这也是不可能的.至少,现在看来实际上是不可能的,也许是出于安全考虑.

My guess is that this not only poorly documented; it is also impossible. At least, it seems effectively impossible nowadays, perhaps due to security concerns.

NtOpenProcess 的文档表明,自 Vista 以来,即使识别一个进程也不可能:

The documentation for NtOpenProcess indicates that even identifying a process by name hasn't been possible since Vista:

https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-ntopenprocess

我刚刚尝试使用 NtSetInformationProcess 的替代方法:

I just tried an alternative approach using NtSetInformationProcess:

#define PHNT_NO_INLINE_INIT_STRING
#include <phnt_windows.h>
#include <phnt.h>

#include <stdio.h>

int main() {
    NTSTATUS status;
    HANDLE handle;

    status
        = NtCreateProcess(&handle,
                          PROCESS_ALL_ACCESS,
                          NULL,
                          NtCurrentProcess(),
                          /*InheritObjectTable=*/TRUE,
                          NULL,
                          NULL,
                          NULL
            );

    UNICODE_STRING newName;
    RtlInitUnicodeString(&newName, L"dummy.exe");

    status
        = NtSetInformationProcess(
            handle,
            ProcessImageFileName,
            &newName,
            sizeof newName
            );
    // fails with 0xC0000003, STATUS_INVALID_INFO_CLASS
    printf("status: %x\n", status);

    // pause to observe the new "zombie child" in Process Explorer
    printf("sleeping...\n");
    Sleep(5000);
    
    return 0;
}

如代码中所述,NtSetInformationProcess 失败并显示 STATUS_INVALID_INFO_CLASS,即使相应的 NtQueryInformationProcess 允许这样做:

As noted in the code, NtSetInformationProcess fails with STATUS_INVALID_INFO_CLASS, even though this is allowed by the corresponding NtQueryInformationProcess:

https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntqueryinformationprocess

查看 ReactOS 源码,这似乎是故意的遗漏.我也发现了这个:

Looking at the ReactOS source, this seems to be a deliberate omission. I also found this:

https://reactos.org/pipermail/ros-diffs/2004-11 月/002066.html

在撰写本文时,上述内容为不再允许 NtSetInformationProcess() 的 ProcessImageFileName 信息类".

As of this writing, the above reads "don't allow the ProcessImageFileName information class for NtSetInformationProcess() anymore".

所有这些都表明它可能在过去是可能的.毕竟,旧 POSIX 子系统中的 exec() 是如何实现的?在 fork() 在新进程中创建一个初始线程并将线程的上下文设置为父进程的副本后,子进程可能会调用 exec(),因此 POSIX 实现可能会销毁并从内部重新创建子进程.在某些时候,子系统必须设置 ProcessImageFileName 以某种方式.

All this suggests it may have been possible in the past. After all, how was exec() in the old POSIX subsystem implemented? After fork() created an initial thread in the new process and set the thread's context to be a copy of the parent's, the child might then call exec(), whereupon the POSIX implementation probably destroyed and re-created the child process from within. At some point, the subsystem would have to set the ProcessImageFileName somehow.

这篇关于NtCreateProcess(Ex) - 我可以让子进程在不同的进程名称下运行时继承父地址空间吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆