调用 NtCreateProcessEx 无一例外地失败
Calling NtCreateProcessEx fails without exception
我想调用 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;
}
整个互联网上都没有关于此特定功能的文档和示例。我可以为 NtCreateFile
做一些与此类似的事情,但这是我对 NtCreateProcessEx
最接近的尝试,但没有运气。
我使用 Visual Studio 2019 和 windows 10 1909。
这些是我尝试过的一些资源:
- NtCreateProcess(Ex) - Can I have a child process inherit the parents address space while running under a different process name?
- http://www.rohitab.com/discuss/topic/40191-ntcreateuserprocess/
- https://github.com/Microwave89/createuserprocess/blob/master/createuserprocess/main.c
- http://www.rohitab.com/discuss/topic/42229-start-a-process-using-ntcreateprocessex-usermode/
- https://hshrzd.wordpress.com/2017/12/18/process-doppelganging-a-new-way-to-impersonate-a-process/
首先,第三个参数是指向OBJECT_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
);
要使用的示例(删除错误检查):
#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;
}
我想调用 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;
}
整个互联网上都没有关于此特定功能的文档和示例。我可以为 NtCreateFile
做一些与此类似的事情,但这是我对 NtCreateProcessEx
最接近的尝试,但没有运气。
我使用 Visual Studio 2019 和 windows 10 1909。
这些是我尝试过的一些资源:
- NtCreateProcess(Ex) - Can I have a child process inherit the parents address space while running under a different process name?
- http://www.rohitab.com/discuss/topic/40191-ntcreateuserprocess/
- https://github.com/Microwave89/createuserprocess/blob/master/createuserprocess/main.c
- http://www.rohitab.com/discuss/topic/42229-start-a-process-using-ntcreateprocessex-usermode/
- https://hshrzd.wordpress.com/2017/12/18/process-doppelganging-a-new-way-to-impersonate-a-process/
首先,第三个参数是指向OBJECT_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
);
要使用的示例(删除错误检查):
#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;
}