mirror of
https://github.com/vxunderground/VX-API
synced 2026-06-06 16:54:55 +00:00
315 lines
9.5 KiB
C++
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;
|
|
}
|