7#define PS_ATTRIBUTE_IMAGE_NAME 0x00020005
8#define PS_ATTRIBUTE_CLIENT_ID 0x00010003
9#define RTL_USER_PROC_PARAMS_NORMALIZED 0x01
10#define THREAD_CREATE_FLAGS_CREATE_SUSPENDED 0x00000001
11#define PEB_SHIM_DATA_OFFSET 0x1E8
16#define NT_SUCCESS(s) ((NTSTATUS)(s) >= 0)
97#define RESOLVE(module, type, name) \
98 ((type)DTTR_UNWRAP_WINAPI_EXISTS(GetProcAddress(module, name)))
105 const WCHAR *image_name
107 WCHAR full_path[MAX_PATH];
108 const DWORD resolved_len = GetFullPathNameW(image_name, MAX_PATH, full_path,
NULL);
109 if (resolved_len == 0 || resolved_len >= MAX_PATH) {
113 const size_t full_path_len = wcslen(full_path);
114 if (full_path_len + 5 > nt_path_size || full_path_len + 1 > cwd_size) {
119 memcpy(nt_path + 4, full_path, (full_path_len + 1) *
sizeof(WCHAR));
121 memcpy(cwd, full_path, (full_path_len + 1) *
sizeof(WCHAR));
122 WCHAR *
const last_sep = wcsrchr(cwd, L
'\\');
124 DTTR_FATAL(
"Game path is missing a parent directory");
133 const char *shim_data,
140 MEM_COMMIT | MEM_RESERVE,
145 WriteProcessMemory(process, remote_shim, shim_data, shim_data_len,
NULL)
157 "Shim data (%u bytes) written to PEB->pShimData at 0x%08X",
158 (
unsigned)shim_data_len,
159 (
unsigned)(uintptr_t)remote_shim
164 const WCHAR *image_name,
165 const char *shim_data,
166 size_t shim_data_len,
167 PROCESS_INFORMATION *child_info
170 "Spawning game process: NtCreateUserProcess (%u bytes shim data)",
171 (
unsigned)shim_data_len
179 "NtCreateUserProcess"
185 "RtlCreateProcessParametersEx"
191 "RtlDestroyProcessParameters"
197 "RtlInitUnicodeString"
200 WCHAR nt_path[MAX_PATH + 8];
204 sizeof(nt_path) /
sizeof(nt_path[0]),
206 sizeof(cwd) /
sizeof(cwd[0]),
211 rtl_init_unicode_string(&us_image, nt_path);
212 rtl_init_unicode_string(&us_cmd, image_name);
213 rtl_init_unicode_string(&us_cwd, cwd);
219 NTSTATUS status = rtl_create_process_parameters_ex(
233 DTTR_FATAL(
"RtlCreateProcessParametersEx failed: 0x%08lX", (
unsigned long)status);
243 {.value_ptr = us_image.
buffer},
256 HANDLE process =
NULL, thread =
NULL;
257 status = nt_create_user_process(
270 rtl_destroy_process_parameters(params);
272 DTTR_FATAL(
"NtCreateUserProcess failed: 0x%08lX", (
unsigned long)status);
275 child_info->hProcess = process;
276 child_info->hThread = thread;
280 "Process created: PID=%lu, TID=%lu",
281 child_info->dwProcessId,
282 child_info->dwThreadId
285 CONTEXT thread_context = {.ContextFlags = CONTEXT_INTEGER};
288 const uintptr_t peb_addr = (uintptr_t)thread_context.Ebx;
DTTR_Graphics_COM_DirectDrawSurface7 DWORD flags void NULL
#define DTTR_UNWRAP_WINAPI_NONZERO(result)
#define DTTR_UNWRAP_WINAPI_EXISTS(result)
#define DTTR_FATAL(error_message,...)
#define DTTR_LOG_DEBUG(...)
#define PS_ATTRIBUTE_IMAGE_NAME
static void write_remote_shim_data(HANDLE process, uintptr_t peb_addr, const char *shim_data, size_t shim_data_len)
#define PS_ATTRIBUTE_CLIENT_ID
#define RESOLVE(module, type, name)
NTSTATUS(NTAPI * rtl_destroy_process_parameters_fn)(PVOID)
#define RTL_USER_PROC_PARAMS_NORMALIZED
NTSTATUS(NTAPI * nt_create_user_process_fn)(PHANDLE, PHANDLE, ACCESS_MASK, ACCESS_MASK, object_attributes *, object_attributes *, ULONG, ULONG, PVOID, create_info *, attribute_list *)
VOID(NTAPI * rtl_init_unicode_string_fn)(unicode_string *, PCWSTR)
static const WCHAR NT_PATH_PREFIX[]
#define THREAD_CREATE_FLAGS_CREATE_SUSPENDED
#define PEB_SHIM_DATA_OFFSET
void DTTR_Compat_CreateProcess(const WCHAR *image_name, const char *shim_data, size_t shim_data_len, PROCESS_INFORMATION *child_info)
static void resolve_nt_path_and_cwd(WCHAR *nt_path, size_t nt_path_size, WCHAR *cwd, size_t cwd_size, const WCHAR *image_name)
NTSTATUS(NTAPI * rtl_create_process_parameters_ex_fn)(PVOID *, unicode_string *, unicode_string *, unicode_string *, unicode_string *, PVOID, unicode_string *, unicode_string *, unicode_string *, unicode_string *, ULONG)
ULONG additional_file_access
unicode_string * object_name
PVOID security_descriptor