运行 使用 RtlCreateUserProcess 的程序只能偶尔工作
Running programs using RtlCreateUserProcess only works occasionally
免责声明:这个问题似乎被否决了,因为我应该使用普通的 Win32 API(CreateProcess、ShellExecute)。我知道这些 APIs 并且我知道 RtlCreateUserProcess
不应该被直接调用。但是,原生 API 是一个与安全性非常相关的主题,这就是我研究它的原因。
我正在尝试 运行 使用从 ntdll.dll 导出的函数 RtlCreateUserProcess
在 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;
}
不幸的是,没有太多关于使用此功能的信息,所以如果能回答如何正确使用此功能,我将不胜感激。
CreateProcess
在创建新进程后做更多的工作,特别是它根据 exe 清单(BasepConstructSxsCreateProcessMessage
+ CsrClientCallServer
)为新进程创建激活上下文,因为新进程有初始激活上下文,存储在 PEB
(SystemDefaultActivationContextData 和 ActivationContextData)中,但在通过纯调用 RtlCreateUserProcess
this 创建的过程中字段为空 (0)。结果,您的进程从 system32(版本 5.82)加载了 ComCtl32.dll 并激活了记事本上下文 - 6+ 版本。
The ordinal 345 could not be located in dynamic link library
确实在 ComCtl32.DLL pre 6 版本 (5.82) 中。 345
- 这是 TaskDialogIndirect
api 仅存在于 ComCtl32.DLL 版本 6+ .但是你的进程负载 5.82.. -
所以 CreateProcess
不是比 RtlCreateUserProcess
或 NtCreateUserProcess
薄 shell,而是大而复杂 api。如果可能的话,它很难发挥作用,直接实施
免责声明:这个问题似乎被否决了,因为我应该使用普通的 Win32 API(CreateProcess、ShellExecute)。我知道这些 APIs 并且我知道 RtlCreateUserProcess
不应该被直接调用。但是,原生 API 是一个与安全性非常相关的主题,这就是我研究它的原因。
我正在尝试 运行 使用从 ntdll.dll 导出的函数 RtlCreateUserProcess
在 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;
}
不幸的是,没有太多关于使用此功能的信息,所以如果能回答如何正确使用此功能,我将不胜感激。
CreateProcess
在创建新进程后做更多的工作,特别是它根据 exe 清单(BasepConstructSxsCreateProcessMessage
+ CsrClientCallServer
)为新进程创建激活上下文,因为新进程有初始激活上下文,存储在 PEB
(SystemDefaultActivationContextData 和 ActivationContextData)中,但在通过纯调用 RtlCreateUserProcess
this 创建的过程中字段为空 (0)。结果,您的进程从 system32(版本 5.82)加载了 ComCtl32.dll 并激活了记事本上下文 - 6+ 版本。
The ordinal 345 could not be located in dynamic link library
确实在 ComCtl32.DLL pre 6 版本 (5.82) 中。 345
- 这是 TaskDialogIndirect
api 仅存在于 ComCtl32.DLL 版本 6+ .但是你的进程负载 5.82.. -
所以 CreateProcess
不是比 RtlCreateUserProcess
或 NtCreateUserProcess
薄 shell,而是大而复杂 api。如果可能的话,它很难发挥作用,直接实施