Files
vxunderground-VX-API/VX-API/CreateProcessViaNtCreateUserProcess.cpp
T
2022-09-11 22:59:40 -05:00

315 lines
9.5 KiB
C++

#include "Win32Helper.h"
#define PS_ATTRIBUTE_NUMBER_MASK 0x0000ffff
#define PS_ATTRIBUTE_THREAD 0x00010000
#define PS_ATTRIBUTE_INPUT 0x00020000
#define PS_ATTRIBUTE_ADDITIVE 0x00040000
typedef enum _PS_ATTRIBUTE_NUM
{
PsAttributeParentProcess,
PsAttributeDebugPort,
PsAttributeToken,
PsAttributeClientId,
PsAttributeTebAddress,
PsAttributeImageName,
PsAttributeImageInfo,
PsAttributeMemoryReserve,
PsAttributePriorityClass,
PsAttributeErrorMode,
PsAttributeStdHandleInfo,
PsAttributeHandleList,
PsAttributeGroupAffinity,
PsAttributePreferredNode,
PsAttributeIdealProcessor,
PsAttributeUmsThread,
PsAttributeMitigationOptions,
PsAttributeProtectionLevel,
PsAttributeSecureProcess,
PsAttributeJobList,
PsAttributeChildProcessPolicy,
PsAttributeAllApplicationPackagesPolicy,
PsAttributeWin32kFilter,
PsAttributeSafeOpenPromptOriginClaim,
PsAttributeBnoIsolation,
PsAttributeDesktopAppPolicy,
PsAttributeMax
} PS_ATTRIBUTE_NUM;
#define PsAttributeValue(Number, Thread, Input, Additive) \
(((Number) & PS_ATTRIBUTE_NUMBER_MASK) | \
((Thread) ? PS_ATTRIBUTE_THREAD : 0) | \
((Input) ? PS_ATTRIBUTE_INPUT : 0) | \
((Additive) ? PS_ATTRIBUTE_ADDITIVE : 0))
#define RTL_USER_PROCESS_PARAMETERS_NORMALIZED 0x01
#define PS_ATTRIBUTE_IMAGE_NAME \
PsAttributeValue(PsAttributeImageName, FALSE, TRUE, FALSE)
typedef struct _PS_ATTRIBUTE
{
ULONG_PTR Attribute;
SIZE_T Size;
union
{
ULONG_PTR Value;
PVOID ValuePtr;
};
PSIZE_T ReturnLength;
} PS_ATTRIBUTE, * PPS_ATTRIBUTE;
typedef struct _PS_ATTRIBUTE_LIST
{
SIZE_T TotalLength;
PS_ATTRIBUTE Attributes[2];
} PS_ATTRIBUTE_LIST, * PPS_ATTRIBUTE_LIST;
typedef enum _PS_CREATE_STATE
{
PsCreateInitialState,
PsCreateFailOnFileOpen,
PsCreateFailOnSectionCreate,
PsCreateFailExeFormat,
PsCreateFailMachineMismatch,
PsCreateFailExeName,
PsCreateSuccess,
PsCreateMaximumStates
} PS_CREATE_STATE;
typedef struct _PS_CREATE_INFO {
SIZE_T Size;
PS_CREATE_STATE State;
union {
struct {
union {
ULONG InitFlags;
struct {
UCHAR WriteOutputOnExit : 1;
UCHAR DetectManifest : 1;
UCHAR IFEOSkipDebugger : 1;
UCHAR IFEODoNotPropagateKeyState : 1;
UCHAR SpareBits1 : 4;
UCHAR SpareBits2 : 8;
USHORT ProhibitedImageCharacteristics : 16;
} s1;
} u1;
ACCESS_MASK AdditionalFileAccess;
} InitState;
struct { HANDLE FileHandle; } FailSection;
struct { USHORT DllCharacteristics; } ExeFormat;
struct { HANDLE IFEOKey; } ExeName;
struct {
union {
ULONG OutputFlags;
struct {
UCHAR ProtectedProcess : 1;
UCHAR AddressSpaceOverride : 1;
UCHAR DevOverrideEnabled : 1;
UCHAR ManifestDetected : 1;
UCHAR ProtectedProcessLight : 1;
UCHAR SpareBits1 : 3;
UCHAR SpareBits2 : 8;
USHORT SpareBits3 : 16;
} s2;
} u2;
HANDLE FileHandle;
HANDLE SectionHandle;
ULONGLONG UserProcessParametersNative;
ULONG UserProcessParametersWow64;
ULONG CurrentParameterFlags;
ULONGLONG PebAddressNative;
ULONG PebAddressWow64;
ULONGLONG ManifestAddress;
ULONG ManifestSize;
} SuccessState;
};
} PS_CREATE_INFO, * PPS_CREATE_INFO;
DWORD CreateProcessViaNtCreateUserProcessA(PCHAR BinaryPath)
{
typedef NTSTATUS(NTAPI* NTCREATEUSERPROCESS)(
PHANDLE,
PHANDLE,
ACCESS_MASK,
ACCESS_MASK,
POBJECT_ATTRIBUTES,
POBJECT_ATTRIBUTES,
ULONG,
ULONG,
PRTL_USER_PROCESS_PARAMETERS,
PPS_CREATE_INFO,
PPS_ATTRIBUTE_LIST
);
typedef NTSTATUS(NTAPI* RTLCREATEPROCESSPARAMETERSEX)(
PRTL_USER_PROCESS_PARAMETERS*,
PUNICODE_STRING,
PUNICODE_STRING,
PUNICODE_STRING,
PUNICODE_STRING,
PVOID,
PUNICODE_STRING,
PUNICODE_STRING,
PUNICODE_STRING,
PUNICODE_STRING,
ULONG
);
typedef NTSTATUS(NTAPI* RTLDESTROYPROCESSPARAMETERS)(PRTL_USER_PROCESS_PARAMETERS);
NTCREATEUSERPROCESS NtCreateUserProcess;
RTLCREATEPROCESSPARAMETERSEX RtlCreateProcessParametersEx;
RTLDESTROYPROCESSPARAMETERS RtlDestroyProcessParameters;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL;
UNICODE_STRING NtImagePath;
WCHAR MsDosFullPath[MAX_PATH * sizeof(WCHAR)] = { 0 };
PS_CREATE_INFO CreateInfo = { 0 };
HMODULE hModule;
PPS_ATTRIBUTE_LIST AttributeList = NULL;
HANDLE hHandle = NULL, hThread = NULL;
DWORD dwError = ERROR_SUCCESS;
WCHAR wBinaryPath[MAX_PATH * sizeof(WCHAR)] = { 0 };
CreateInfo.Size = sizeof(CreateInfo);
CreateInfo.State = PsCreateInitialState;
hModule = GetModuleHandleEx2W(L"ntdll.dll");
if (hModule == NULL)
return GetLastErrorEx();
NtCreateUserProcess = (NTCREATEUSERPROCESS)GetProcAddressA((DWORD64)hModule, "NtCreateUserProcess");
if (NtCreateUserProcess == NULL)
return GetLastErrorEx();
RtlCreateProcessParametersEx = (RTLCREATEPROCESSPARAMETERSEX)GetProcAddressA((DWORD64)hModule, "RtlCreateProcessParametersEx");
if (RtlCreateProcessParametersEx == NULL)
return GetLastErrorEx();
RtlDestroyProcessParameters = (RTLDESTROYPROCESSPARAMETERS)GetProcAddressA((DWORD64)hModule, "RtlDestroyProcessParameters");
if (RtlDestroyProcessParameters == NULL)
return GetLastErrorEx();
CharStringToWCharString(wBinaryPath, BinaryPath, StringLengthA(BinaryPath));
StringCopyW(MsDosFullPath, (PWCHAR)L"\\??\\");
StringConcatW(MsDosFullPath, wBinaryPath);
RtlInitUnicodeString(&NtImagePath, MsDosFullPath);
if (RtlCreateProcessParametersEx(&ProcessParameters, &NtImagePath, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, RTL_USER_PROCESS_PARAMETERS_NORMALIZED) != ERROR_SUCCESS)
return GetLastErrorEx();
AttributeList = (PPS_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeapEx(), HEAP_ZERO_MEMORY, sizeof(PS_ATTRIBUTE));
if (AttributeList)
{
AttributeList->TotalLength = sizeof(PS_ATTRIBUTE_LIST) - sizeof(PS_ATTRIBUTE);
AttributeList->Attributes[0].Attribute = PS_ATTRIBUTE_IMAGE_NAME;
AttributeList->Attributes[0].Size = NtImagePath.Length;
AttributeList->Attributes[0].Value = (ULONG_PTR)NtImagePath.Buffer;
if (NtCreateUserProcess(&hHandle, &hThread, PROCESS_ALL_ACCESS, THREAD_ALL_ACCESS, NULL, NULL, NULL, NULL, ProcessParameters, &CreateInfo, AttributeList) != ERROR_SUCCESS)
dwError = GetLastErrorEx(); //?
}
if (AttributeList)
HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, AttributeList);
if (ProcessParameters)
RtlDestroyProcessParameters(ProcessParameters);
return dwError;
}
DWORD CreateProcessViaNtCreateUserProcessW(PWCHAR BinaryPath)
{
typedef NTSTATUS(NTAPI* NTCREATEUSERPROCESS)(
PHANDLE,
PHANDLE,
ACCESS_MASK,
ACCESS_MASK,
POBJECT_ATTRIBUTES,
POBJECT_ATTRIBUTES,
ULONG,
ULONG,
PRTL_USER_PROCESS_PARAMETERS,
PPS_CREATE_INFO,
PPS_ATTRIBUTE_LIST
);
typedef NTSTATUS(NTAPI* RTLCREATEPROCESSPARAMETERSEX)(
PRTL_USER_PROCESS_PARAMETERS*,
PUNICODE_STRING,
PUNICODE_STRING,
PUNICODE_STRING,
PUNICODE_STRING,
PVOID,
PUNICODE_STRING,
PUNICODE_STRING,
PUNICODE_STRING,
PUNICODE_STRING,
ULONG
);
typedef NTSTATUS(NTAPI* RTLDESTROYPROCESSPARAMETERS)(PRTL_USER_PROCESS_PARAMETERS);
NTCREATEUSERPROCESS NtCreateUserProcess;
RTLCREATEPROCESSPARAMETERSEX RtlCreateProcessParametersEx;
RTLDESTROYPROCESSPARAMETERS RtlDestroyProcessParameters;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL;
UNICODE_STRING NtImagePath;
WCHAR MsDosFullPath[MAX_PATH * sizeof(WCHAR)] = { 0 };
PS_CREATE_INFO CreateInfo = { 0 };
HMODULE hModule;
PPS_ATTRIBUTE_LIST AttributeList = NULL;
HANDLE hHandle = NULL, hThread = NULL;
DWORD dwError = ERROR_SUCCESS;
CreateInfo.Size = sizeof(CreateInfo);
CreateInfo.State = PsCreateInitialState;
hModule = GetModuleHandleEx2W(L"ntdll.dll");
if (hModule == NULL)
return GetLastErrorEx();
NtCreateUserProcess = (NTCREATEUSERPROCESS)GetProcAddressA((DWORD64)hModule, "NtCreateUserProcess");
if (NtCreateUserProcess == NULL)
return GetLastErrorEx();
RtlCreateProcessParametersEx = (RTLCREATEPROCESSPARAMETERSEX)GetProcAddressA((DWORD64)hModule, "RtlCreateProcessParametersEx");
if (RtlCreateProcessParametersEx == NULL)
return GetLastErrorEx();
RtlDestroyProcessParameters = (RTLDESTROYPROCESSPARAMETERS)GetProcAddressA((DWORD64)hModule, "RtlDestroyProcessParameters");
if (RtlDestroyProcessParameters == NULL)
return GetLastErrorEx();
StringCopyW(MsDosFullPath, (PWCHAR)L"\\??\\");
StringConcatW(MsDosFullPath, BinaryPath);
RtlInitUnicodeString(&NtImagePath, MsDosFullPath);
if (RtlCreateProcessParametersEx(&ProcessParameters, &NtImagePath, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, RTL_USER_PROCESS_PARAMETERS_NORMALIZED) != ERROR_SUCCESS)
return GetLastErrorEx();
AttributeList = (PPS_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeapEx(), HEAP_ZERO_MEMORY, sizeof(PS_ATTRIBUTE));
if (AttributeList)
{
AttributeList->TotalLength = sizeof(PS_ATTRIBUTE_LIST) - sizeof(PS_ATTRIBUTE);
AttributeList->Attributes[0].Attribute = PS_ATTRIBUTE_IMAGE_NAME;
AttributeList->Attributes[0].Size = NtImagePath.Length;
AttributeList->Attributes[0].Value = (ULONG_PTR)NtImagePath.Buffer;
if (NtCreateUserProcess(&hHandle, &hThread, PROCESS_ALL_ACCESS, THREAD_ALL_ACCESS, NULL, NULL, NULL, NULL, ProcessParameters, &CreateInfo, AttributeList) != ERROR_SUCCESS)
dwError = GetLastErrorEx(); //?
}
if (AttributeList)
HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, AttributeList);
if (ProcessParameters)
RtlDestroyProcessParameters(ProcessParameters);
return dwError;
}