免责声明:这个问题似乎被否决了,因为我应该使用普通的 Win32 API(CreateProcess、ShellExecute)。我知道这些 API,并且我知道RtlCreateUserProcess
不应该直接调用它们。然而,原生 API 是一个与安全性非常相关的话题,这就是我研究它的原因。
我正在尝试使用RtlCreateUserProcess
从 ntdll.dll 导出的函数在 Windows 上运行程序。我的代码可以运行 calc.exe,但是,在尝试运行 notepad.exe 后,我收到一条错误消息,内容为The ordinal 345 could not be located in dynamic link library "C:\Windows\SysWOW64\notepad.exe"
. 当试图运行其他程序时,它会显示各种类似的消息,总是与缺少一些序数或 DLL 有关。
我的示例代码如下所示:
#include <windows.h>
#include <iostream>
#include <winternl.h>
typedef struct _SECTION_IMAGE_INFORMATION {
PVOID EntryPoint;
ULONG StackZeroBits;
ULONG StackReserved;
ULONG StackCommit;
ULONG ImageSubsystem;
WORD SubSystemVersionLow;
WORD SubSystemVersionHigh;
ULONG Unknown1;
ULONG ImageCharacteristics;
ULONG ImageMachineType;
ULONG Unknown2[3];
} SECTION_IMAGE_INFORMATION, * PSECTION_IMAGE_INFORMATION;
typedef struct _RTL_USER_PROCESS_INFORMATION {
ULONG Size;
HANDLE ProcessHandle;
HANDLE ThreadHandle;
CLIENT_ID ClientId;
SECTION_IMAGE_INFORMATION ImageInformation;
} RTL_USER_PROCESS_INFORMATION, * PRTL_USER_PROCESS_INFORMATION;
typedef VOID(NTAPI* Func1)(PUNICODE_STRING DestinationString, __drv_aliasesMem PCWSTR SourceString);
typedef NTSTATUS(NTAPI* Func2)(OUT PRTL_USER_PROCESS_PARAMETERS* pProcessParameters, IN PUNICODE_STRING ImagePathName, IN PUNICODE_STRING DllPath OPTIONAL, IN PUNICODE_STRING CurrentDirectory OPTIONAL, IN PUNICODE_STRING CommandLine OPTIONAL, IN PVOID Environment OPTIONAL, IN PUNICODE_STRING WindowTitle OPTIONAL, IN PUNICODE_STRING DesktopInfo OPTIONAL, IN PUNICODE_STRING ShellInfo OPTIONAL, IN PUNICODE_STRING RuntimeData OPTIONAL);
typedef NTSTATUS(NTAPI* Func3)(PUNICODE_STRING NtImagePathName, ULONG Attributes, PRTL_USER_PROCESS_PARAMETERS ProcessParameters, PSECURITY_DESCRIPTOR ProcessSecurityDescriptor, PSECURITY_DESCRIPTOR ThreadSecurityDescriptor, HANDLE ParentProcess, BOOLEAN InheritHandles, HANDLE DebugPort, HANDLE ExceptionPort, PRTL_USER_PROCESS_INFORMATION ProcessInformation);
int main()
{
UNICODE_STRING str;
PRTL_USER_PROCESS_PARAMETERS processparameters;
RTL_USER_PROCESS_INFORMATION processinformation = { 0 };
Func1 RtlInitUnicodeString = (Func1)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlInitUnicodeString");
Func2 RtlCreateProcessParameters = (Func2)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlCreateProcessParameters");
Func3 RtlCreateUserProcess = (Func3)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlCreateUserProcess");
RtlInitUnicodeString(&str, L"\\??\\C:\\Windows\\SysWOW64\\notepad.exe"); //Starting calc.exe works, notepad.exe does not.
RtlCreateProcessParameters(&processparameters, &str, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
NTSTATUS works = RtlCreateUserProcess(&str, OBJ_CASE_INSENSITIVE, processparameters, NULL, NULL, NULL, FALSE, NULL, NULL, &processinformation);
if (NT_SUCCESS(works)) {
ResumeThread(processinformation.ThreadHandle);
//Started application crashes at this point + the error message gets shown
}
else {
std::cout << "Failed" << std::endl;
}
return 0;
}
不幸的是,没有太多关于使用这个功能的信息,所以我很感激任何关于如何正确使用这个功能的答案。