0

免责声明:这个问题似乎被否决了,因为我应该使用普通的 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;
}

不幸的是,没有太多关于使用这个功能的信息,所以我很感激任何关于如何正确使用这个功能的答案。

4

1 回答 1

3

CreateProcess在创建新进程后做更多的工作,特别是它基于 exe 清单(BasepConstructSxsCreateProcessMessage+ CsrClientCallServer)为新进程创建激活上下文,因为新进程具有初始激活上下文,存储在PEBSystemDefaultActivationContextDataActivationContextData)但在通过纯调用创建的进程RtlCreateUserProcess中字段为空 (0)。结果,您的进程从system32(版本5.82)和带有激活上下文的记事本加载ComCtl32.dll - 6+版本。

序号 345 无法位于动态链接库中

真的在ComCtl32.DLL pre 6版本(5.82)中。345- 这是TaskDialogIndirect仅存在于ComCtl32.DLL版本6+中的 api 。但是您的进程加载5.82 .. -调用 TaskDialogIndirect 加载程序说未找到序数 345

所以不是or上CreateProcess的薄壳,而是大而复杂的 api。如果可能的话,它的功能非常困难,直接实施RtlCreateUserProcessNtCreateUserProcess

于 2021-10-17T15:17:41.410 回答