C++ 调用NtCreateProcessEx失败,无异常

C++ 调用NtCreateProcessEx失败,无异常,c++,winapi,system-calls,ntdll,C++,Winapi,System Calls,Ntdll,我想调用NtCreateProcessEx,但我没有收到异常和错误,也没有发生任何事情。另外,我不想使用CreateProcess。我的意图是使用此特定函数从文件创建并运行一个进程 这就是我迄今为止所尝试的: #include <Windows.h> #include <bcrypt.h> #include "winternl.h" #pragma comment(lib, "ntdll") NTSTATUS NTAPI NtCreateProcessEx( O

我想调用
NtCreateProcessEx
,但我没有收到异常和错误,也没有发生任何事情。另外,我不想使用
CreateProcess
。我的意图是使用此特定函数从文件创建并运行一个进程

这就是我迄今为止所尝试的:

#include <Windows.h>
#include <bcrypt.h>
#include "winternl.h"
#pragma comment(lib, "ntdll")

NTSTATUS NTAPI NtCreateProcessEx(
    OUT HANDLE ProcessHandle,
    IN ACCESS_MASK DesiredAccess,
    IN OBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
    IN HANDLE ParentProcess,
    IN BOOLEAN InheritObjectTable,
    IN HANDLE SectionHandle OPTIONAL,
    IN HANDLE DebugPort OPTIONAL,
    IN HANDLE ExceptionPort OPTIONAL,
    IN BOOLEAN InJob);

int main()
{
    const HANDLE ph = nullptr;
    OBJECT_ATTRIBUTES oa;
    UNICODE_STRING fileName;
    RtlInitUnicodeString(&fileName, PCWSTR(L"\\??\\C:\\Windows\\System32\\calc.exe"));
    (&oa)->Length = sizeof(OBJECT_ATTRIBUTES);
    (&oa)->RootDirectory = nullptr;
    (&oa)->Attributes = 0x00000040L;
    (&oa)->ObjectName = &fileName;
    (&oa)->SecurityDescriptor = nullptr;
    (&oa)->SecurityQualityOfService = nullptr;;
    NtCreateProcessEx(ph, PROCESS_ALL_ACCESS, oa, nullptr, FALSE, nullptr, nullptr, nullptr, FALSE);

    return 0;
}
#包括
#包括
#包括“winternl.h”
#pragma注释(lib,“ntdll”)
NTSTATUS NTAPI NtCreateProcessEx(
外把手,
在ACCESS_MASK DesiredAccess中,
在对象属性ObjectAttributes OPTIONAL中,
在这个过程中,,
在布尔继承对象表中,
在HANDLE部分HANDLE OPTIONAL中,
在HANDLE DebugPort(可选)中,
在句柄例外端口可选中,
以布尔形式表示(InJob);
int main()
{
常量句柄ph=空PTR;
对象属性;
UNICODE_字符串文件名;
RtlInitUnicodeString(&fileName,PCWSTR(L“\\??\\C:\\Windows\\System32\\calc.exe”);
(&oa)->Length=sizeof(对象属性);
(&oa)->RootDirectory=nullptr;
(&oa)->属性=0x00000040L;
(&oa)->ObjectName=&fileName;
(&oa)->SecurityDescriptor=nullptr;
(&oa)->SecurityQualityOfService=nullptr;;
NtCreateProcessEx(ph、进程访问、oa、nullptr、FALSE、nullptr、nullptr、nullptr、FALSE);
返回0;
}
整个互联网上没有关于这个特定功能的文档和示例。我可以为
NtCreateFile
做一些类似的事情,但这是我对
NtCreateProcessEx
最接近的尝试,没有运气

我使用Visual Studio 2019和windows 10 1909

以下是我尝试过的一些资源:


  • 首先,第三个参数是指向
    对象属性的指针:

    typedef NTSTATUS(NTAPI* fpNtCreateProcessEx)
    (
        PHANDLE     ProcessHandle,
        ACCESS_MASK  DesiredAccess,
        POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
        HANDLE   ParentProcess,
        ULONG    Flags,
        HANDLE SectionHandle     OPTIONAL,
        HANDLE DebugPort     OPTIONAL,
        HANDLE ExceptionPort     OPTIONAL,
        BOOLEAN  InJob
        );
    
    要使用的示例(删除错误检查):

    #包括
    #包括
    使用名称空间std;
    #定义NtCurrentProcess()((句柄)(LONG_PTR)-1)
    typedef结构\u LSA\u UNICODE\u字符串{
    USHORT长度;
    USHORT最大长度;
    PWSTR缓冲区;
    }LSA_UNICODE_字符串、*PLSA_UNICODE_字符串、UNICODE_字符串、*PUNICODE_字符串;
    类型定义结构_对象_属性{
    乌龙长度;
    处理根目录;
    PUNICODE_字符串ObjectName;
    乌龙属性;
    PVOID安全描述符;
    PVOID安全性服务质量;
    }对象属性,*对象属性;
    typedef NTSTATUS(NTAPI*fpNtCreateProcessEx)
    (
    幻影处理柄,
    需要访问的访问屏蔽,
    POBJECT_属性ObjectAttributes可选,
    处理父进程,
    乌龙旗,
    句柄部分句柄可选,
    句柄调试端口可选,
    句柄例外端口可选,
    布尔InJob
    );
    typedef NTSTATUS(NTAPI*FPNTCreateTransation)
    (
    幻影交易手柄,
    需要访问的访问屏蔽,
    POBJECT_属性ObjectAttributes,
    LPUOW,
    把手,把手,
    ULONG CreateOptions,
    ULONG隔离层,
    ULONG IsolationFlags,
    PLARGE_整数超时,
    PUNICODE_字符串描述
    );
    typedef NTSTATUS(NTAPI*fpNtCreateSection)
    (
    幻影部分手柄,
    需要访问的访问屏蔽,
    POBJECT_属性ObjectAttributes,
    PLARGE_整数最大大小,
    乌龙保护区,
    ULONG分配属性,
    句柄文件句柄
    );
    类型定义NTSTATUS(NTAPI*fpNtClose)
    (
    把手
    );
    #定义PS_继承_句柄4
    int main()
    {
    处理hProcess;
    对象属性objattr;
    UNICODE_字符串对象名;
    非关税国家地位;
    WCHAR wstrObjName[最大路径];
    lstrcpyW(wstrObjName,L“C:\\test.exe”);
    HINSTANCE hinst=LoadLibrary(L“ntdll.dll”);
    fpNtCreateProcessEx _NtCreateProcessEx=(fpNtCreateProcessEx)GetProcAddress(hinst,“NtCreateProcessEx”);
    fpNtCreateTransaction _NtCreateTransaction=(fpNtCreateTransaction)GetProcAddress(hinst,“NtCreateTransaction”);
    fpNtCreateSection _NtCreateSection=(fpNtCreateSection)GetProcAddress(hinst,“NtCreateSection”);
    fpNtClose _NtClose=(fpNtClose)GetProcAddress(hinst,“NtClose”);
    //初始化ObjectName UNICODE\u字符串
    Buffer=wstrObjName;
    objname.Length=wcslen(wstrObjName)*sizeof(WCHAR);//字符串的字节长度,不带空终止符
    objname.MaximumLength=MAX_PATH*sizeof(WCHAR);
    //初始化对象属性
    objattr.Length=sizeof(对象属性);
    objattr.Attributes=0x00000040L;//不区分大小写
    objattr.ObjectName=NULL;
    objattr.RootDirectory=NULL;
    objattr.SecurityDescriptor=NULL;
    objattr.SecurityQualityOfService=NULL;
    HANDLE hTransaction=NULL;
    状态=\n创建事务(&H事务),
    事务\u所有\u访问,
    &objattr,
    无效的
    无效的
    0,
    0,
    0,
    无效的
    无效);
    HANDLE hTransactedFile=CreateFileTransactived(wstrObjName,
    一般写,一般读,
    0,
    无效的
    开放式,
    文件\u属性\u正常,
    无效的
    hTransaction,
    无效的
    无效);
    HANDLE hSection=NULL;
    状态=\n创建节(&H节),
    第(1)节所有(2)通道,,
    无效的
    0,
    第页(只读),
    SEC_图像,
    hTransactedFile);
    状态=\u NtCreateProcessEx(&hProcess,PROCESS\u ALL\u ACCESS,NULL,NtCurrentProcess(),PS\u INHERIT\u HANDLES,hSection,NULL,NULL,false);
    DWORD pid=GetProcessId(hProcess);
    printf(“Pid=%d\n”,Pid);
    CloseHandle(htTransactedFile);
    _NtClose(HTTransaction);
    _NtClose(hSection);
    _NtClose(hProcess);
    返回0;
    }
    
    您错误地使用了
    NtCreateProcessEx
    <代码>对象属性
    不得指向任何文件。并且必须是0。相反,您需要从可执行文件创建节,并将其传递到位
    SectionHandle
    。还需要做更多的工作——创造更多的就业机会
    #include <windows.h>
    #include <iostream>
    using namespace std;
    #define NtCurrentProcess() ( (HANDLE)(LONG_PTR) -1 )
    typedef struct _LSA_UNICODE_STRING {
        USHORT Length;
        USHORT MaximumLength;
        PWSTR  Buffer;
    } LSA_UNICODE_STRING, * PLSA_UNICODE_STRING, UNICODE_STRING, * PUNICODE_STRING;
    
    
    typedef struct _OBJECT_ATTRIBUTES {
        ULONG           Length;
        HANDLE          RootDirectory;
        PUNICODE_STRING ObjectName;
        ULONG           Attributes;
        PVOID           SecurityDescriptor;
        PVOID           SecurityQualityOfService;
    }  OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES;
    
    
    typedef NTSTATUS(NTAPI* fpNtCreateProcessEx)
    (
        PHANDLE     ProcessHandle,
        ACCESS_MASK  DesiredAccess,
        POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
        HANDLE   ParentProcess,
        ULONG    Flags,
        HANDLE SectionHandle     OPTIONAL,
        HANDLE DebugPort     OPTIONAL,
        HANDLE ExceptionPort     OPTIONAL,
        BOOLEAN  InJob
    );
    
    typedef NTSTATUS(NTAPI* fpNtCreateTransaction)
    (
        PHANDLE            TransactionHandle,
        ACCESS_MASK        DesiredAccess,
        POBJECT_ATTRIBUTES ObjectAttributes,
        LPGUID             Uow,
        HANDLE             TmHandle,
        ULONG              CreateOptions,
        ULONG              IsolationLevel,
        ULONG              IsolationFlags,
        PLARGE_INTEGER     Timeout,
        PUNICODE_STRING    Description
    );
    
    typedef NTSTATUS (NTAPI *fpNtCreateSection)
    (
        PHANDLE SectionHandle,
        ACCESS_MASK DesiredAccess,
        POBJECT_ATTRIBUTES ObjectAttributes,
        PLARGE_INTEGER MaximumSize,
        ULONG SectionPageProtection,
        ULONG AllocationAttributes,
        HANDLE FileHandle
    );
    typedef NTSTATUS (NTAPI *fpNtClose)
    (
        HANDLE Handle
    );
    #define PS_INHERIT_HANDLES                      4
    
    int main()
    {
        HANDLE hProcess;
        OBJECT_ATTRIBUTES objattr;
        UNICODE_STRING objname;
        NTSTATUS status;
        WCHAR wstrObjName[MAX_PATH];
        lstrcpyW(wstrObjName, L"C:\\test.exe");
    
        HINSTANCE hinst = LoadLibrary(L"ntdll.dll");
        fpNtCreateProcessEx _NtCreateProcessEx = (fpNtCreateProcessEx)GetProcAddress(hinst, "NtCreateProcessEx");
        fpNtCreateTransaction _NtCreateTransaction = (fpNtCreateTransaction)GetProcAddress(hinst, "NtCreateTransaction");
        fpNtCreateSection _NtCreateSection = (fpNtCreateSection)GetProcAddress(hinst, "NtCreateSection");
        fpNtClose _NtClose = (fpNtClose)GetProcAddress(hinst, "NtClose");
    
        // Initialize ObjectName UNICODE_STRING
        objname.Buffer = wstrObjName;
        objname.Length = wcslen(wstrObjName) * sizeof(WCHAR); // Length in bytes of string, without null terminator
        objname.MaximumLength = MAX_PATH * sizeof(WCHAR);
    
    
        // Initialize OBJECT_ATTRIBUTES
        objattr.Length = sizeof(OBJECT_ATTRIBUTES);
        objattr.Attributes = 0x00000040L; //OBJ_CASE_INSENSITIVE 
        objattr.ObjectName = NULL;
        objattr.RootDirectory = NULL;
        objattr.SecurityDescriptor = NULL;
        objattr.SecurityQualityOfService = NULL;
    
    
        HANDLE hTransaction = NULL;
        status = _NtCreateTransaction(&hTransaction,
            TRANSACTION_ALL_ACCESS,
            &objattr,
            NULL,
            NULL,
            0,
            0,
            0,
            NULL,
            NULL);
    
        HANDLE hTransactedFile = CreateFileTransacted(wstrObjName,
            GENERIC_WRITE | GENERIC_READ,
            0,
            NULL,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            NULL,
            hTransaction,
            NULL,
            NULL);
        HANDLE hSection = NULL;
        status = _NtCreateSection(&hSection,
            SECTION_ALL_ACCESS,
            NULL,
            0,
            PAGE_READONLY,
            SEC_IMAGE,
            hTransactedFile);
    
        status = _NtCreateProcessEx(&hProcess, PROCESS_ALL_ACCESS, NULL, NtCurrentProcess(), PS_INHERIT_HANDLES, hSection, NULL, NULL, false);
        DWORD pid = GetProcessId(hProcess);
        printf("Pid = %d\n", pid);
    
        CloseHandle(hTransactedFile);
        _NtClose(hTransaction);
        _NtClose(hSection);
        _NtClose(hProcess);
        return 0;
    }