├── README.md ├── hook.cpp ├── main.c ├── nttypes.h ├── syscalls-asm.h └── syscalls.h /README.md: -------------------------------------------------------------------------------- 1 | # NtCreateUserProcess 2 | 3 | Attempt to get NtCreateUserProcess working as direct syscall. Contains `main.c` which is a raw implementation of the API, and `hook.cpp` which attempts to hook the NTDLL call and call the original by passing the parameters received from `CreateProcessA()`. 4 | 5 | *Note: probably needs a trampoline to not mess with the register state* 6 | 7 | 8 | 9 | Sources: [https://github.com/Microwave89/createuserprocess/](https://github.com/Microwave89/createuserprocess/) 10 | 11 | > Using [SysWhispers](https://github.com/jthuraisamy/SysWhispers) and [InlineWhispers](https://github.com/outflanknl/InlineWhispers) to generate the direct syscalls 12 | -------------------------------------------------------------------------------- /hook.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | //#include "syscalls-asm.h" 4 | 5 | FARPROC NtCreateUserProcessAddr = NULL; 6 | SIZE_T bytesWritten = 0; 7 | char NtCreateUserProcessOriginalBytes[6] = {}; 8 | 9 | NTSTATUS __stdcall HookedNtCreateUserProcess(PHANDLE ProcessHandle, PHANDLE ThreadHandle, ACCESS_MASK ProcessDesiredAccess, ACCESS_MASK ThreadDesiredAccess, POBJECT_ATTRIBUTES ProcessObjectAttributes, POBJECT_ATTRIBUTES ThreadObjectAttributes, ULONG ProcessFlags, ULONG ThreadFlags, PRTL_USER_PROCESS_PARAMETERS ProcessParameters, PPS_CREATE_INFO CreateInfo, PPS_ATTRIBUTE_LIST AttributeList) 10 | { 11 | printf("Hello from hooked NtCreateUserProcess ;)\n"); 12 | 13 | // unpatch 14 | WriteProcessMemory(GetCurrentProcess(), (LPVOID)NtCreateUserProcessAddr, NtCreateUserProcessOriginalBytes, sizeof(NtCreateUserProcessOriginalBytes), &bytesWritten); 15 | 16 | // call the original 17 | printf("Calling original\n"); 18 | return &NtCreateUserProcessAddr(ProcessHandle, ThreadHandle, ProcessDesiredAccess, ThreadDesiredAccess, ProcessObjectAttributes, ThreadObjectAttributes, ProcessFlags, ThreadFlags, ProcessParameters, CreateInfo, AttributeList); 19 | } 20 | 21 | int main() 22 | { 23 | HINSTANCE library = LoadLibraryA("ntdll.dll"); 24 | SIZE_T bytesRead = 0; 25 | 26 | // get address of the NtCreateUserProcess function in memory 27 | NtCreateUserProcessAddr = GetProcAddress(library, "NtCreateUserProcess"); 28 | 29 | // save the first 6 bytes of the original NtCreateUserProcess function - will need for unhooking 30 | ReadProcessMemory(GetCurrentProcess(), (LPCVOID)NtCreateUserProcessAddr, NtCreateUserProcessOriginalBytes, 6, &bytesRead); 31 | 32 | // create a patch "push
(&HookedNtCreateUserProcess);//wonky cast to get around C++ ISO rules - https://stackoverflow.com/questions/45134220/how-to-convert-a-pointer-of-type-void-to-void 35 | char patch[6] = { 0 }; 36 | 37 | memcpy_s(patch, 1, "\x68", 1); 38 | memcpy_s(patch + 1, 4, &hookedNtCreateUserProcessAddr, 4); 39 | memcpy_s(patch + 5, 1, "\xC3", 1); 40 | 41 | // patch NtCreateUserProcess 42 | WriteProcessMemory(GetCurrentProcess(), (LPVOID)NtCreateUserProcessAddr, patch, sizeof(patch), &bytesWritten); 43 | 44 | // Execute code after hooking 45 | PROCESS_INFORMATION pi; 46 | STARTUPINFO si; 47 | memset(&si, 0, sizeof(si)); 48 | memset(&pi, 0, sizeof(pi)); 49 | 50 | CreateProcessA("C:\\Windows\\System32\\calc.exe", NULL, NULL, NULL, FALSE, /*CREATE_SUSPENDED*/NULL, NULL, NULL, &si, &pi); 51 | return 0; 52 | } -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "syscalls-asm.h" 4 | 5 | int main() 6 | { 7 | UNICODE_STRING uImageName; 8 | WCHAR imageName[] = { L"\\??\\C:\\Windows\\System32\\calc.exe" }; 9 | uImageName.Buffer = imageName; 10 | uImageName.Length = sizeof(imageName) - sizeof(UNICODE_NULL); 11 | uImageName.MaximumLength = sizeof(imageName); 12 | PUNICODE_STRING pProcessImageName = &uImageName; 13 | 14 | PS_CREATE_INFO procInfo; 15 | RTL_USER_PROCESS_PARAMETERS userParams; 16 | PS_ATTRIBUTE_LIST attrList; 17 | PS_PROTECTION protectionInfo; 18 | 19 | NTSTATUS status = STATUS_PENDING; 20 | HANDLE hProcess = NULL; 21 | HANDLE hThread = NULL; 22 | ///We should supply a minimal environment (environment variables). Following one is simple yet fits our needs. 23 | char data[2 * sizeof(ULONGLONG)] = { 'Y', 0x00, 0x3D, 0x00, 'Q', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 24 | 25 | if (pProcessImageName) { 26 | protectionInfo.Signer = (UCHAR)PsProtectedSignerNone; 27 | protectionInfo.Type = (UCHAR)PsProtectedTypeNone; 28 | protectionInfo.Audit = 0; 29 | 30 | RtlSecureZeroMemory(&userParams, sizeof(RTL_USER_PROCESS_PARAMETERS)); 31 | RtlSecureZeroMemory(&attrList, sizeof(PS_ATTRIBUTE_LIST) - sizeof(PS_ATTRIBUTE)); 32 | RtlSecureZeroMemory(&procInfo, sizeof(PS_CREATE_INFO)); 33 | 34 | userParams.Length = sizeof(RTL_USER_PROCESS_PARAMETERS); 35 | userParams.MaximumLength = sizeof(RTL_USER_PROCESS_PARAMETERS); 36 | attrList.TotalLength = sizeof(PS_ATTRIBUTE_LIST) - sizeof(PS_ATTRIBUTE); 37 | procInfo.Size = sizeof(PS_CREATE_INFO); 38 | 39 | userParams.Environment = (WCHAR*)data; 40 | userParams.EnvironmentSize = sizeof(data); 41 | userParams.Flags = RTL_USER_PROCESS_PARAMETERS_NORMALIZED; 42 | 43 | attrList.Attributes[0].Attribute = PsAttributeValue(PsAttributeImageName, FALSE, TRUE, FALSE); 44 | attrList.Attributes[0].Size = pProcessImageName->Length; 45 | attrList.Attributes[0].Value = (ULONG_PTR)pProcessImageName->Buffer; 46 | 47 | status = NtCreateUserProcess(&hProcess, &hThread, MAXIMUM_ALLOWED, MAXIMUM_ALLOWED, NULL, NULL, 0, /*THREAD_CREATE_FLAGS_CREATE_SUSPENDED*/0x1, &userParams, &procInfo, &attrList); 48 | } 49 | return 0; 50 | } -------------------------------------------------------------------------------- /nttypes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | ///Copied from Process Hacker 2.37 source (ntpsapi.h) 3 | 4 | #include 5 | 6 | #ifndef InitializeObjectAttributes 7 | #define InitializeObjectAttributes( p, n, a, r, s ) { \ 8 | (p)->Length = sizeof( OBJECT_ATTRIBUTES ); \ 9 | (p)->RootDirectory = r; \ 10 | (p)->Attributes = a; \ 11 | (p)->ObjectName = n; \ 12 | (p)->SecurityDescriptor = s; \ 13 | (p)->SecurityQualityOfService = NULL; \ 14 | } 15 | #endif 16 | 17 | typedef struct _UNICODE_STRING 18 | { 19 | USHORT Length; 20 | USHORT MaximumLength; 21 | PWSTR Buffer; 22 | } UNICODE_STRING, *PUNICODE_STRING; 23 | 24 | typedef struct _OBJECT_ATTRIBUTES 25 | { 26 | ULONG Length; 27 | HANDLE RootDirectory; 28 | PUNICODE_STRING ObjectName; 29 | ULONG Attributes; 30 | PVOID SecurityDescriptor; 31 | PVOID SecurityQualityOfService; 32 | } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; 33 | 34 | typedef enum _PS_PROTECTED_TYPE { 35 | PsProtectedTypeNone, 36 | PsProtectedTypeProtectedLight, 37 | PsProtectedTypeProtected, 38 | PsProtectedTypeMax 39 | } PS_PROTECTED_TYPE; 40 | 41 | typedef enum _PS_PROTECTED_SIGNER { 42 | PsProtectedSignerNone, 43 | PsProtectedSignerAuthenticode, 44 | PsProtectedSignerCodeGen, 45 | PsProtectedSignerAntimalware, 46 | PsProtectedSignerLsa, 47 | PsProtectedSignerWindows, 48 | PsProtectedSignerWinTcb, 49 | PsProtectedSignerMax 50 | } PS_PROTECTED_SIGNER; 51 | 52 | typedef struct _PS_PROTECTION { 53 | union { 54 | UCHAR Level; 55 | struct { 56 | UCHAR Type : 3; 57 | UCHAR Audit : 1; 58 | UCHAR Signer : 4; 59 | }; 60 | }; 61 | } PS_PROTECTION, *PPS_PROTECTION; 62 | 63 | // begin_rev 64 | #define PS_ATTRIBUTE_NUMBER_MASK 0x0000ffff 65 | #define PS_ATTRIBUTE_THREAD 0x00010000 // can be used with threads 66 | #define PS_ATTRIBUTE_INPUT 0x00020000 // input only 67 | #define PS_ATTRIBUTE_ADDITIVE 0x00040000 /// Is an additional option (see ProcThreadAttributeValue in WinBase.h) 68 | // end_rev 69 | 70 | typedef enum _PS_ATTRIBUTE_NUM { 71 | PsAttributeParentProcess, // in HANDLE 72 | PsAttributeDebugPort, // in HANDLE 73 | PsAttributeToken, // in HANDLE 74 | PsAttributeClientId, // out PCLIENT_ID 75 | PsAttributeTebAddress, // out PTEB 76 | PsAttributeImageName, // in PWSTR 77 | PsAttributeImageInfo, // out PSECTION_IMAGE_INFORMATION 78 | PsAttributeMemoryReserve, // in PPS_MEMORY_RESERVE 79 | PsAttributePriorityClass, // in UCHAR 80 | PsAttributeErrorMode, // in ULONG 81 | PsAttributeStdHandleInfo, // 10, in PPS_STD_HANDLE_INFO 82 | PsAttributeHandleList, // in PHANDLE 83 | PsAttributeGroupAffinity, // in PGROUP_AFFINITY 84 | PsAttributePreferredNode, // in PUSHORT 85 | PsAttributeIdealProcessor, // in PPROCESSOR_NUMBER 86 | PsAttributeUmsThread, // see UpdateProceThreadAttributeList in msdn (CreateProcessA/W...) in PUMS_CREATE_THREAD_ATTRIBUTES 87 | PsAttributeMitigationOptions, // in UCHAR 88 | PsAttributeProtectionLevel, 89 | PsAttributeSecureProcess, // since THRESHOLD (Virtual Secure Mode, Device Guard) 90 | PsAttributeJobList, 91 | PsAttributeMax 92 | } PS_ATTRIBUTE_NUM; 93 | 94 | #define PsAttributeValue(Number, Thread, Input, Additive) \ 95 | (((Number) & PS_ATTRIBUTE_NUMBER_MASK) | \ 96 | ((Thread) ? PS_ATTRIBUTE_THREAD : 0) | \ 97 | ((Input) ? PS_ATTRIBUTE_INPUT : 0) | \ 98 | ((Additive) ? PS_ATTRIBUTE_ADDITIVE : 0)) 99 | 100 | typedef struct _PS_ATTRIBUTE { 101 | ULONGLONG Attribute; /// PROC_THREAD_ATTRIBUTE_XXX | PROC_THREAD_ATTRIBUTE_XXX modifiers, see ProcThreadAttributeValue macro and Windows Internals 6 (372) 102 | SIZE_T Size; /// Size of Value or *ValuePtr 103 | union { 104 | ULONG_PTR Value; /// Reserve 8 bytes for data (such as a Handle or a data pointer) 105 | PVOID ValuePtr; /// data pointer 106 | }; 107 | PSIZE_T ReturnLength; /// Either 0 or specifies size of data returned to caller via "ValuePtr" 108 | } PS_ATTRIBUTE, *PPS_ATTRIBUTE; 109 | 110 | typedef struct _PS_ATTRIBUTE_LIST { 111 | SIZE_T TotalLength; /// sizeof(PS_ATTRIBUTE_LIST) 112 | PS_ATTRIBUTE Attributes[2]; /// Depends on how many attribute entries should be supplied to NtCreateUserProcess 113 | } PS_ATTRIBUTE_LIST, *PPS_ATTRIBUTE_LIST; 114 | 115 | typedef struct _PS_MEMORY_RESERVE { 116 | PVOID ReserveAddress; 117 | SIZE_T ReserveSize; 118 | } PS_MEMORY_RESERVE, *PPS_MEMORY_RESERVE; 119 | 120 | typedef enum _PS_STD_HANDLE_STATE { 121 | PsNeverDuplicate, 122 | PsRequestDuplicate, // duplicate standard handles specified by PseudoHandleMask, and only if StdHandleSubsystemType matches the image subsystem 123 | PsAlwaysDuplicate, // always duplicate standard handles 124 | PsMaxStdHandleStates 125 | } PS_STD_HANDLE_STATE; 126 | 127 | // begin_rev 128 | #define PS_STD_INPUT_HANDLE 0x1 129 | #define PS_STD_OUTPUT_HANDLE 0x2 130 | #define PS_STD_ERROR_HANDLE 0x4 131 | // end_rev 132 | 133 | typedef struct _PS_STD_HANDLE_INFO { 134 | union { 135 | ULONG Flags; 136 | struct { 137 | ULONG StdHandleState : 2; // PS_STD_HANDLE_STATE 138 | ULONG PseudoHandleMask : 3; // PS_STD_* 139 | }; 140 | }; 141 | ULONG StdHandleSubsystemType; 142 | } PS_STD_HANDLE_INFO, *PPS_STD_HANDLE_INFO; 143 | 144 | // windows-internals-book:"Chapter 5" 145 | typedef enum _PS_CREATE_STATE { 146 | PsCreateInitialState, 147 | PsCreateFailOnFileOpen, 148 | PsCreateFailOnSectionCreate, 149 | PsCreateFailExeFormat, 150 | PsCreateFailMachineMismatch, 151 | PsCreateFailExeName, // Debugger specified 152 | PsCreateSuccess, 153 | PsCreateMaximumStates 154 | } PS_CREATE_STATE; 155 | 156 | typedef struct _PS_CREATE_INFO { 157 | SIZE_T Size; 158 | PS_CREATE_STATE State; 159 | union { 160 | // PsCreateInitialState 161 | struct { 162 | union { 163 | ULONG InitFlags; 164 | struct { 165 | UCHAR WriteOutputOnExit : 1; 166 | UCHAR DetectManifest : 1; 167 | UCHAR IFEOSkipDebugger : 1; 168 | UCHAR IFEODoNotPropagateKeyState : 1; 169 | UCHAR SpareBits1 : 4; 170 | UCHAR SpareBits2 : 8; 171 | USHORT ProhibitedImageCharacteristics : 16; 172 | }; 173 | }; 174 | ACCESS_MASK AdditionalFileAccess; 175 | } InitState; 176 | 177 | // PsCreateFailOnSectionCreate 178 | struct { 179 | HANDLE FileHandle; 180 | } FailSection; 181 | 182 | // PsCreateFailExeFormat 183 | struct { 184 | USHORT DllCharacteristics; 185 | } ExeFormat; 186 | 187 | // PsCreateFailExeName 188 | struct { 189 | HANDLE IFEOKey; 190 | } ExeName; 191 | 192 | // PsCreateSuccess 193 | struct { 194 | union { 195 | ULONG OutputFlags; 196 | struct { 197 | UCHAR ProtectedProcess : 1; 198 | UCHAR AddressSpaceOverride : 1; 199 | UCHAR DevOverrideEnabled : 1; // from Image File Execution Options 200 | UCHAR ManifestDetected : 1; 201 | UCHAR ProtectedProcessLight : 1; 202 | UCHAR SpareBits1 : 3; 203 | UCHAR SpareBits2 : 8; 204 | USHORT SpareBits3 : 16; 205 | }; 206 | }; 207 | HANDLE FileHandle; 208 | HANDLE SectionHandle; 209 | ULONGLONG UserProcessParametersNative; 210 | ULONG UserProcessParametersWow64; 211 | ULONG CurrentParameterFlags; 212 | ULONGLONG PebAddressNative; 213 | ULONG PebAddressWow64; 214 | ULONGLONG ManifestAddress; 215 | ULONG ManifestSize; 216 | } SuccessState; 217 | }; 218 | } PS_CREATE_INFO, *PPS_CREATE_INFO; 219 | 220 | typedef struct _RTL_DRIVE_LETTER_CURDIR 221 | { 222 | USHORT Flags; 223 | USHORT Length; 224 | ULONG TimeStamp; 225 | UNICODE_STRING DosPath; 226 | } RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR; 227 | 228 | typedef struct _RTL_USER_PROCESS_PARAMETERS { 229 | ULONG MaximumLength; 230 | ULONG Length; 231 | ULONG Flags; 232 | ULONG DebugFlags; 233 | PVOID ConsoleHandle; 234 | ULONG ConsoleFlags; 235 | HANDLE StdInputHandle; 236 | HANDLE StdOutputHandle; 237 | HANDLE StdErrorHandle; 238 | UNICODE_STRING CurrentDirectoryPath; 239 | HANDLE CurrentDirectoryHandle; 240 | UNICODE_STRING DllPath; 241 | UNICODE_STRING ImagePathName; 242 | UNICODE_STRING CommandLine; 243 | PVOID Environment; 244 | ULONG EnvironmentSize; 245 | ULONG StartingPositionLeft; 246 | ULONG StartingPositionTop; 247 | ULONG Width; 248 | ULONG Height; 249 | ULONG CharWidth; 250 | ULONG CharHeight; 251 | ULONG ConsoleTextAttributes; 252 | ULONG WindowFlags; 253 | ULONG ShowWindowFlags; 254 | UNICODE_STRING WindowTitle; 255 | UNICODE_STRING DesktopName; 256 | UNICODE_STRING ShellInfo; 257 | UNICODE_STRING RuntimeData; 258 | RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20]; 259 | } RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS; 260 | 261 | 262 | EXTERN_C NTSTATUS NtCreateUserProcess( 263 | OUT PHANDLE ProcessHandle, 264 | OUT PHANDLE ThreadHandle, 265 | IN ACCESS_MASK ProcessDesiredAccess, 266 | IN ACCESS_MASK ThreadDesiredAccess, 267 | IN POBJECT_ATTRIBUTES ProcessObjectAttributes OPTIONAL, 268 | IN POBJECT_ATTRIBUTES ThreadObjectAttributes OPTIONAL, 269 | IN ULONG ProcessFlags, 270 | IN ULONG ThreadFlags, 271 | IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters OPTIONAL, 272 | IN OUT PPS_CREATE_INFO CreateInfo, 273 | IN PPS_ATTRIBUTE_LIST AttributeList OPTIONAL); 274 | 275 | // end_private 276 | 277 | // Extended PROCESS_CREATE_FLAGS_* 278 | // begin_rev 279 | #define PROCESS_CREATE_FLAGS_LARGE_PAGE_SYSTEM_DLL 0x00000020 280 | #define PROCESS_CREATE_FLAGS_PROTECTED_PROCESS 0x00000040 281 | #define PROCESS_CREATE_FLAGS_CREATE_SESSION 0x00000080 // ? 282 | #define PROCESS_CREATE_FLAGS_INHERIT_FROM_PARENT 0x00000100 283 | // end_rev 284 | 285 | // begin_rev 286 | #define THREAD_CREATE_FLAGS_CREATE_SUSPENDED 0x00000001 287 | #define THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH 0x00000002 // ? 288 | #define THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER 0x00000004 289 | #define THREAD_CREATE_FLAGS_HAS_SECURITY_DESCRIPTOR 0x00000010 // ? 290 | #define THREAD_CREATE_FLAGS_ACCESS_CHECK_IN_TARGET 0x00000020 // ? 291 | #define THREAD_CREATE_FLAGS_INITIAL_THREAD 0x00000080 292 | // end_rev 293 | 294 | #define RTL_USER_PROCESS_PARAMETERS_NORMALIZED 0x01 -------------------------------------------------------------------------------- /syscalls-asm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | //#include "syscalls.h" 3 | #include "nttypes.h" 4 | //crash line 55 5 | //cmp word ptr [rax+0x120], 18362 6 | 7 | /* 8 | #define ZwCreateUserProcess NtCreateUserProcess 9 | __asm__("NtCreateUserProcess: \n\ 10 | mov rax, gs:[0x60] \n\ 11 | NtCreateUserProcess_Check_X_X_XXXX: \n\ 12 | cmp dword ptr [rax+0x118], 6 \n\ 13 | je NtCreateUserProcess_Check_6_X_XXXX \n\ 14 | cmp dword ptr [rax+0x118], 10 \n\ 15 | je NtCreateUserProcess_Check_10_0_XXXX \n\ 16 | jmp NtCreateUserProcess_SystemCall_Unknown \n\ 17 | NtCreateUserProcess_Check_6_X_XXXX: \n\ 18 | cmp dword ptr [rax+0x11c], 0 \n\ 19 | je NtCreateUserProcess_Check_6_0_XXXX \n\ 20 | cmp dword ptr [rax+0x11c], 1 \n\ 21 | je NtCreateUserProcess_Check_6_1_XXXX \n\ 22 | cmp dword ptr [rax+0x11c], 2 \n\ 23 | je NtCreateUserProcess_SystemCall_6_2_XXXX \n\ 24 | cmp dword ptr [rax+0x11c], 3 \n\ 25 | je NtCreateUserProcess_SystemCall_6_3_XXXX \n\ 26 | jmp NtCreateUserProcess_SystemCall_Unknown \n\ 27 | NtCreateUserProcess_Check_6_0_XXXX: \n\ 28 | cmp word ptr [rax+0x120], 6000 \n\ 29 | je NtCreateUserProcess_SystemCall_6_0_6000 \n\ 30 | cmp word ptr [rax+0x120], 6001 \n\ 31 | je NtCreateUserProcess_SystemCall_6_0_6001 \n\ 32 | cmp word ptr [rax+0x120], 6002 \n\ 33 | je NtCreateUserProcess_SystemCall_6_0_6002 \n\ 34 | jmp NtCreateUserProcess_SystemCall_Unknown \n\ 35 | NtCreateUserProcess_Check_6_1_XXXX: \n\ 36 | cmp word ptr [rax+0x120], 7600 \n\ 37 | je NtCreateUserProcess_SystemCall_6_1_7600 \n\ 38 | cmp word ptr [rax+0x120], 7601 \n\ 39 | je NtCreateUserProcess_SystemCall_6_1_7601 \n\ 40 | jmp NtCreateUserProcess_SystemCall_Unknown \n\ 41 | NtCreateUserProcess_Check_10_0_XXXX: \n\ 42 | cmp word ptr [rax+0x120], 10240 \n\ 43 | je NtCreateUserProcess_SystemCall_10_0_10240 \n\ 44 | cmp word ptr [rax+0x120], 10586 \n\ 45 | je NtCreateUserProcess_SystemCall_10_0_10586 \n\ 46 | cmp word ptr [rax+0x120], 14393 \n\ 47 | je NtCreateUserProcess_SystemCall_10_0_14393 \n\ 48 | cmp word ptr [rax+0x120], 15063 \n\ 49 | je NtCreateUserProcess_SystemCall_10_0_15063 \n\ 50 | cmp word ptr [rax+0x120], 16299 \n\ 51 | je NtCreateUserProcess_SystemCall_10_0_16299 \n\ 52 | cmp word ptr [rax+0x120], 17134 \n\ 53 | je NtCreateUserProcess_SystemCall_10_0_17134 \n\ 54 | cmp word ptr [rax+0x120], 17763 \n\ 55 | je NtCreateUserProcess_SystemCall_10_0_17763 \n\ 56 | cmp word ptr [rax+0x120], 18362 \n\ 57 | je NtCreateUserProcess_SystemCall_10_0_18362 \n\ 58 | cmp word ptr [rax+0x120], 18363 \n\ 59 | je NtCreateUserProcess_SystemCall_10_0_18363 \n\ 60 | cmp word ptr [rax+0x120], 19041 \n\ 61 | je NtCreateUserProcess_SystemCall_10_0_19041 \n\ 62 | cmp word ptr [rax+0x120], 19042 \n\ 63 | je NtCreateUserProcess_SystemCall_10_0_19042 \n\ 64 | jmp NtCreateUserProcess_SystemCall_Unknown \n\ 65 | NtCreateUserProcess_SystemCall_6_0_6000: \n\ 66 | mov eax, 0x00ac \n\ 67 | jmp NtCreateUserProcess_Epilogue \n\ 68 | NtCreateUserProcess_SystemCall_6_0_6001: \n\ 69 | mov eax, 0x00aa \n\ 70 | jmp NtCreateUserProcess_Epilogue \n\ 71 | NtCreateUserProcess_SystemCall_6_0_6002: \n\ 72 | mov eax, 0x00aa \n\ 73 | jmp NtCreateUserProcess_Epilogue \n\ 74 | NtCreateUserProcess_SystemCall_6_1_7600: \n\ 75 | mov eax, 0x00aa \n\ 76 | jmp NtCreateUserProcess_Epilogue \n\ 77 | NtCreateUserProcess_SystemCall_6_1_7601: \n\ 78 | mov eax, 0x00aa \n\ 79 | jmp NtCreateUserProcess_Epilogue \n\ 80 | NtCreateUserProcess_SystemCall_6_2_XXXX: \n\ 81 | mov eax, 0x00b5 \n\ 82 | jmp NtCreateUserProcess_Epilogue \n\ 83 | NtCreateUserProcess_SystemCall_6_3_XXXX: \n\ 84 | mov eax, 0x00b7 \n\ 85 | jmp NtCreateUserProcess_Epilogue \n\ 86 | NtCreateUserProcess_SystemCall_10_0_10240: \n\ 87 | mov eax, 0x00ba \n\ 88 | jmp NtCreateUserProcess_Epilogue \n\ 89 | NtCreateUserProcess_SystemCall_10_0_10586: \n\ 90 | mov eax, 0x00bb \n\ 91 | jmp NtCreateUserProcess_Epilogue \n\ 92 | NtCreateUserProcess_SystemCall_10_0_14393: \n\ 93 | mov eax, 0x00bd \n\ 94 | jmp NtCreateUserProcess_Epilogue \n\ 95 | NtCreateUserProcess_SystemCall_10_0_15063: \n\ 96 | mov eax, 0x00c0 \n\ 97 | jmp NtCreateUserProcess_Epilogue \n\ 98 | NtCreateUserProcess_SystemCall_10_0_16299: \n\ 99 | mov eax, 0x00c1 \n\ 100 | jmp NtCreateUserProcess_Epilogue \n\ 101 | NtCreateUserProcess_SystemCall_10_0_17134: \n\ 102 | mov eax, 0x00c2 \n\ 103 | jmp NtCreateUserProcess_Epilogue \n\ 104 | NtCreateUserProcess_SystemCall_10_0_17763: \n\ 105 | mov eax, 0x00c3 \n\ 106 | jmp NtCreateUserProcess_Epilogue \n\ 107 | NtCreateUserProcess_SystemCall_10_0_18362: \n\ 108 | mov eax, 0x00c4 \n\ 109 | jmp NtCreateUserProcess_Epilogue \n\ 110 | NtCreateUserProcess_SystemCall_10_0_18363: \n\ 111 | mov eax, 0x00c4 \n\ 112 | jmp NtCreateUserProcess_Epilogue \n\ 113 | NtCreateUserProcess_SystemCall_10_0_19041: \n\ 114 | mov eax, 0x00c8 \n\ 115 | jmp NtCreateUserProcess_Epilogue \n\ 116 | NtCreateUserProcess_SystemCall_10_0_19042: \n\ 117 | mov eax, 0x00c8 \n\ 118 | jmp NtCreateUserProcess_Epilogue \n\ 119 | NtCreateUserProcess_SystemCall_Unknown: \n\ 120 | ret \n\ 121 | NtCreateUserProcess_Epilogue: \n\ 122 | mov r10, rcx \n\ 123 | syscall \n\ 124 | ret \n\ 125 | "); 126 | */ 127 | 128 | #define ZwCreateUserProcess NtCreateUserProcess 129 | __asm__("NtCreateUserProcess: \n\ 130 | mov rax, gs:[0x60] \n\ 131 | mov eax, 0x00c8 \n\ 132 | mov r10, rcx \n\ 133 | syscall \n\ 134 | ret \n\ 135 | "); 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /syscalls.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | typedef struct _PS_ATTRIBUTE 6 | { 7 | ULONG Attribute; 8 | SIZE_T Size; 9 | union 10 | { 11 | ULONG Value; 12 | PVOID ValuePtr; 13 | } u1; 14 | PSIZE_T ReturnLength; 15 | } PS_ATTRIBUTE, *PPS_ATTRIBUTE; 16 | 17 | #ifndef InitializeObjectAttributes 18 | #define InitializeObjectAttributes( p, n, a, r, s ) { \ 19 | (p)->Length = sizeof( OBJECT_ATTRIBUTES ); \ 20 | (p)->RootDirectory = r; \ 21 | (p)->Attributes = a; \ 22 | (p)->ObjectName = n; \ 23 | (p)->SecurityDescriptor = s; \ 24 | (p)->SecurityQualityOfService = NULL; \ 25 | } 26 | #endif 27 | 28 | typedef struct _UNICODE_STRING 29 | { 30 | USHORT Length; 31 | USHORT MaximumLength; 32 | PWSTR Buffer; 33 | } UNICODE_STRING, *PUNICODE_STRING; 34 | 35 | typedef enum _PS_CREATE_STATE 36 | { 37 | PsCreateInitialState, 38 | PsCreateFailOnFileOpen, 39 | PsCreateFailOnSectionCreate, 40 | PsCreateFailExeFormat, 41 | PsCreateFailMachineMismatch, 42 | PsCreateFailExeName, 43 | PsCreateSuccess, 44 | PsCreateMaximumStates 45 | } PS_CREATE_STATE, *PPS_CREATE_STATE; 46 | 47 | typedef struct _OBJECT_ATTRIBUTES 48 | { 49 | ULONG Length; 50 | HANDLE RootDirectory; 51 | PUNICODE_STRING ObjectName; 52 | ULONG Attributes; 53 | PVOID SecurityDescriptor; 54 | PVOID SecurityQualityOfService; 55 | } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; 56 | 57 | typedef struct _PS_CREATE_INFO 58 | { 59 | SIZE_T Size; 60 | PS_CREATE_STATE State; 61 | union 62 | { 63 | // PsCreateInitialState 64 | struct { 65 | union { 66 | ULONG InitFlags; 67 | struct { 68 | UCHAR WriteOutputOnExit : 1; 69 | UCHAR DetectManifest : 1; 70 | UCHAR IFEOSkipDebugger : 1; 71 | UCHAR IFEODoNotPropagateKeyState : 1; 72 | UCHAR SpareBits1 : 4; 73 | UCHAR SpareBits2 : 8; 74 | USHORT ProhibitedImageCharacteristics : 16; 75 | }; 76 | }; 77 | ACCESS_MASK AdditionalFileAccess; 78 | } InitState; 79 | // PsCreateFailOnSectionCreate 80 | struct { 81 | HANDLE FileHandle; 82 | } FailSection; 83 | // PsCreateFailExeFormat 84 | struct { 85 | USHORT DllCharacteristics; 86 | } ExeFormat; 87 | // PsCreateFailExeName 88 | struct { 89 | HANDLE IFEOKey; 90 | } ExeName; 91 | // PsCreateSuccess 92 | struct { 93 | union { 94 | ULONG OutputFlags; 95 | struct { 96 | UCHAR ProtectedProcess : 1; 97 | UCHAR AddressSpaceOverride : 1; 98 | UCHAR DevOverrideEnabled : 1; // from Image File Execution Options 99 | UCHAR ManifestDetected : 1; 100 | UCHAR ProtectedProcessLight : 1; 101 | UCHAR SpareBits1 : 3; 102 | UCHAR SpareBits2 : 8; 103 | USHORT SpareBits3 : 16; 104 | }; 105 | }; 106 | HANDLE FileHandle; 107 | HANDLE SectionHandle; 108 | ULONGLONG UserProcessParametersNative; 109 | ULONG UserProcessParametersWow64; 110 | ULONG CurrentParameterFlags; 111 | ULONGLONG PebAddressNative; 112 | ULONG PebAddressWow64; 113 | ULONGLONG ManifestAddress; 114 | ULONG ManifestSize; 115 | } SuccessState; 116 | }; 117 | } PS_CREATE_INFO, *PPS_CREATE_INFO; 118 | 119 | typedef struct _PS_ATTRIBUTE_LIST 120 | { 121 | SIZE_T TotalLength; 122 | PS_ATTRIBUTE Attributes[1]; 123 | } PS_ATTRIBUTE_LIST, *PPS_ATTRIBUTE_LIST; 124 | 125 | EXTERN_C NTSTATUS NtCreateUserProcess( 126 | OUT PHANDLE ProcessHandle, 127 | OUT PHANDLE ThreadHandle, 128 | IN ACCESS_MASK ProcessDesiredAccess, 129 | IN ACCESS_MASK ThreadDesiredAccess, 130 | IN POBJECT_ATTRIBUTES ProcessObjectAttributes OPTIONAL, 131 | IN POBJECT_ATTRIBUTES ThreadObjectAttributes OPTIONAL, 132 | IN ULONG ProcessFlags, 133 | IN ULONG ThreadFlags, 134 | IN PVOID ProcessParameters OPTIONAL, 135 | IN OUT PPS_CREATE_INFO CreateInfo, 136 | IN PPS_ATTRIBUTE_LIST AttributeList OPTIONAL); 137 | --------------------------------------------------------------------------------