|
|
dd89bb |
/********************************************************/
|
|
|
dd89bb |
/* ntapi: Native API core library */
|
|
|
64e606 |
/* Copyright (C) 2013--2021 SysDeer Technologies, LLC */
|
|
|
dd89bb |
/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
|
|
|
dd89bb |
/********************************************************/
|
|
|
dd89bb |
|
|
|
dd89bb |
#include <psxtypes/psxtypes.h>
|
|
|
dd89bb |
#include <pemagine/pemagine.h>
|
|
|
dd89bb |
#include <ntapi/nt_status.h>
|
|
|
dd89bb |
#include <ntapi/nt_object.h>
|
|
|
dd89bb |
#include <ntapi/nt_thread.h>
|
|
|
dd89bb |
#include <ntapi/nt_process.h>
|
|
|
dd89bb |
#include <ntapi/nt_string.h>
|
|
|
dd89bb |
#include <ntapi/ntapi.h>
|
|
|
dd89bb |
#include "ntapi_impl.h"
|
|
|
dd89bb |
|
|
|
9f5e67 |
struct __ext_params {
|
|
|
9f5e67 |
size_t size_in_bytes;
|
|
|
9f5e67 |
nt_create_process_ext_param file_info;
|
|
|
9f5e67 |
};
|
|
|
9f5e67 |
|
|
|
9f5e67 |
struct __integral_cmdline {
|
|
|
9f5e67 |
struct pe_guid_str_utf16 guid;
|
|
|
9f5e67 |
wchar16_t space1;
|
|
|
9f5e67 |
wchar16_t rarg[2];
|
|
|
9f5e67 |
wchar16_t space2;
|
|
|
9f5e67 |
wchar16_t addr[2*__SIZEOF_POINTER__];
|
|
|
9f5e67 |
wchar16_t null;
|
|
|
9f5e67 |
};
|
|
|
9f5e67 |
|
|
|
dd89bb |
static int32_t __tt_create_process_cancel(nt_create_process_params * params, int32_t status)
|
|
|
dd89bb |
{
|
|
|
dd89bb |
if (params->hprocess) {
|
|
|
dd89bb |
__ntapi->zw_terminate_process(params->hprocess,NT_STATUS_INTERNAL_ERROR);
|
|
|
dd89bb |
__ntapi->zw_close(params->hprocess);
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
if (params->hthread)
|
|
|
dd89bb |
__ntapi->zw_close(params->hthread);
|
|
|
dd89bb |
|
|
|
dd89bb |
return status;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
|
|
|
dd89bb |
int32_t __stdcall __ntapi_tt_create_native_process_v2(
|
|
|
dd89bb |
__in_out nt_create_process_params * params)
|
|
|
dd89bb |
{
|
|
|
9f5e67 |
int32_t status;
|
|
|
dd89bb |
|
|
|
9f5e67 |
nt_object_attributes oa_process;
|
|
|
9f5e67 |
nt_object_attributes oa_thread;
|
|
|
dd89bb |
|
|
|
9f5e67 |
nt_unicode_string nt_image;
|
|
|
9f5e67 |
nt_unicode_string nt_cmd_line;
|
|
|
dd89bb |
|
|
|
9f5e67 |
nt_create_process_info nt_process_info;
|
|
|
9f5e67 |
int fresume_thread;
|
|
|
dd89bb |
|
|
|
9f5e67 |
struct __ext_params ext_params;
|
|
|
9f5e67 |
struct __integral_cmdline fcmdline = {
|
|
|
9f5e67 |
{
|
|
|
9f5e67 |
'{',{'3','e','4','3','e','c','8','4'},
|
|
|
9f5e67 |
'-',{'1','a','f','1'},
|
|
|
9f5e67 |
'-',{'4','e','d','e'},
|
|
|
9f5e67 |
'-',{'a','c','d','8'},
|
|
|
9f5e67 |
'-',{'c','3','d','9','2','0','a','f','c','8','6','8'},
|
|
|
9f5e67 |
'}'
|
|
|
9f5e67 |
},
|
|
|
dd89bb |
|
|
|
7f8d50 |
#if (__SIZEOF_POINTER__ == 4)
|
|
|
9f5e67 |
' ',{'-','r'},' ',
|
|
|
9f5e67 |
{'i','n','t','e','g','r','a','l'},0};
|
|
|
7f8d50 |
#elif (__SIZEOF_POINTER__ == 8)
|
|
|
9f5e67 |
' ',{'-','r'},' ',
|
|
|
9f5e67 |
{'i','n','t','e','g','r','a','l',
|
|
|
9f5e67 |
'-','r','u','n','t','i','m','e'},0};
|
|
|
dd89bb |
#endif
|
|
|
dd89bb |
|
|
|
dd89bb |
/* validation */
|
|
|
dd89bb |
if (params->cmd_line && params->process_params)
|
|
|
dd89bb |
return NT_STATUS_INVALID_PARAMETER_MIX;
|
|
|
dd89bb |
else if (params->cmd_line && params->rtblock)
|
|
|
dd89bb |
return NT_STATUS_INVALID_PARAMETER_MIX;
|
|
|
dd89bb |
else if (params->environment && params->process_params)
|
|
|
dd89bb |
return NT_STATUS_INVALID_PARAMETER_MIX;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* image_name */
|
|
|
dd89bb |
__ntapi->rtl_init_unicode_string(
|
|
|
dd89bb |
&nt_image,
|
|
|
dd89bb |
params->image_name);
|
|
|
dd89bb |
|
|
|
dd89bb |
/* oa_process */
|
|
|
dd89bb |
if (!params->obj_attr_process) {
|
|
|
dd89bb |
__ntapi->tt_aligned_block_memset(
|
|
|
dd89bb |
&oa_process,0,sizeof(oa_process));
|
|
|
dd89bb |
|
|
|
dd89bb |
oa_process.len = sizeof(oa_process);
|
|
|
dd89bb |
params->obj_attr_process = &oa_process;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
/* oa_thread */
|
|
|
dd89bb |
if (!params->obj_attr_thread) {
|
|
|
dd89bb |
__ntapi->tt_aligned_block_memset(
|
|
|
dd89bb |
&oa_thread,0,sizeof(oa_thread));
|
|
|
dd89bb |
|
|
|
dd89bb |
oa_thread.len = sizeof(oa_thread);
|
|
|
dd89bb |
params->obj_attr_thread = &oa_thread;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
/* process_params */
|
|
|
dd89bb |
if (!params->process_params) {
|
|
|
dd89bb |
/* environment */
|
|
|
dd89bb |
if (!params->environment)
|
|
|
dd89bb |
params->environment = __ntapi->tt_get_peb_env_block_utf16();
|
|
|
dd89bb |
|
|
|
9f5e67 |
/* cmd_line */
|
|
|
9f5e67 |
if (params->rtblock) {
|
|
|
9f5e67 |
nt_cmd_line.strlen = sizeof(fcmdline) - sizeof(fcmdline.null);
|
|
|
9f5e67 |
nt_cmd_line.maxlen = sizeof(fcmdline);
|
|
|
9f5e67 |
nt_cmd_line.buffer = &fcmdline.guid.lbrace;
|
|
|
9f5e67 |
params->cmd_line = &fcmdline.guid.lbrace;
|
|
|
9f5e67 |
} else {
|
|
|
9f5e67 |
if (!params->cmd_line)
|
|
|
9f5e67 |
params->cmd_line = params->image_name;
|
|
|
9f5e67 |
|
|
|
9f5e67 |
__ntapi->rtl_init_unicode_string(
|
|
|
9f5e67 |
&nt_cmd_line,
|
|
|
9f5e67 |
params->cmd_line);
|
|
|
9f5e67 |
}
|
|
|
9f5e67 |
|
|
|
dd89bb |
if ((status = __ntapi->rtl_create_process_parameters(
|
|
|
dd89bb |
¶ms->process_params,
|
|
|
dd89bb |
&nt_image,
|
|
|
dd89bb |
(nt_unicode_string *)0,
|
|
|
dd89bb |
(nt_unicode_string *)0,
|
|
|
dd89bb |
&nt_cmd_line,
|
|
|
dd89bb |
params->environment,
|
|
|
dd89bb |
(nt_unicode_string *)0,
|
|
|
dd89bb |
(nt_unicode_string *)0,
|
|
|
dd89bb |
(nt_unicode_string *)0,
|
|
|
dd89bb |
(nt_unicode_string *)0)))
|
|
|
dd89bb |
return status;
|
|
|
dd89bb |
|
|
|
dd89bb |
__ntapi->rtl_normalize_process_params(params->process_params);
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
/* create_process_info */
|
|
|
dd89bb |
if (!params->create_process_info) {
|
|
|
dd89bb |
__ntapi->tt_aligned_block_memset(
|
|
|
dd89bb |
&nt_process_info,0,sizeof(nt_process_info));
|
|
|
dd89bb |
|
|
|
dd89bb |
nt_process_info.size = sizeof(nt_create_process_info);
|
|
|
dd89bb |
nt_process_info.state = NT_PROCESS_CREATE_INITIAL_STATE;
|
|
|
dd89bb |
nt_process_info.init_state.init_flags = NT_PROCESS_CREATE_INFO_OBTAIN_OUTPUT;
|
|
|
dd89bb |
nt_process_info.init_state.file_access_ext = NT_FILE_READ_ATTRIBUTES|NT_FILE_READ_ACCESS;
|
|
|
dd89bb |
|
|
|
dd89bb |
params->create_process_info = &nt_process_info;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
/* create_process_ext_params */
|
|
|
dd89bb |
if (!params->create_process_ext_params) {
|
|
|
dd89bb |
__ntapi->tt_aligned_block_memset(
|
|
|
dd89bb |
&ext_params,0,sizeof(ext_params));
|
|
|
dd89bb |
|
|
|
dd89bb |
ext_params.size_in_bytes = sizeof(ext_params);
|
|
|
dd89bb |
|
|
|
dd89bb |
/* file_info */
|
|
|
dd89bb |
ext_params.file_info.ext_param_type = NT_CREATE_PROCESS_EXT_PARAM_SET_FILE_NAME;
|
|
|
dd89bb |
ext_params.file_info.ext_param_size = nt_image.strlen;
|
|
|
dd89bb |
ext_params.file_info.ext_param_addr = nt_image.buffer;
|
|
|
dd89bb |
|
|
|
dd89bb |
params->create_process_ext_params = (nt_create_process_ext_params *)&ext_params;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
params->hprocess = 0;
|
|
|
dd89bb |
params->hthread = 0;
|
|
|
dd89bb |
fresume_thread = 0;
|
|
|
dd89bb |
|
|
|
dd89bb |
if (params->rtblock) {
|
|
|
dd89bb |
fresume_thread = (params->creation_flags_thread ^ 0x01) & 0x01;
|
|
|
dd89bb |
params->creation_flags_thread |= 0x01;
|
|
|
dd89bb |
}
|
|
|
dd89bb |
|
|
|
dd89bb |
if (!params->desired_access_process)
|
|
|
dd89bb |
params->desired_access_process = NT_PROCESS_ALL_ACCESS;
|
|
|
dd89bb |
|
|
|
dd89bb |
if (!params->desired_access_thread)
|
|
|
dd89bb |
params->desired_access_thread = NT_THREAD_ALL_ACCESS;
|
|
|
dd89bb |
|
|
|
dd89bb |
if ((status = __ntapi->zw_create_user_process(
|
|
|
dd89bb |
¶ms->hprocess,
|
|
|
dd89bb |
¶ms->hthread,
|
|
|
dd89bb |
params->desired_access_process,
|
|
|
dd89bb |
params->desired_access_thread,
|
|
|
dd89bb |
params->obj_attr_process,
|
|
|
dd89bb |
params->obj_attr_thread,
|
|
|
dd89bb |
params->creation_flags_process,
|
|
|
dd89bb |
params->creation_flags_thread,
|
|
|
dd89bb |
params->process_params,
|
|
|
dd89bb |
params->create_process_info,
|
|
|
dd89bb |
params->create_process_ext_params)))
|
|
|
dd89bb |
return status;
|
|
|
dd89bb |
|
|
|
f154f6 |
/* session registration */
|
|
|
f154f6 |
if (params->hsession && (params->hsession != NT_INVALID_HANDLE_VALUE))
|
|
|
f154f6 |
if ((status = __ntapi->tty_client_process_register(
|
|
|
f154f6 |
params->hsession,
|
|
|
f154f6 |
params->pbi.unique_process_id,
|
|
|
f154f6 |
0,0,0)))
|
|
|
f154f6 |
return __tt_create_process_cancel(params,status);
|
|
|
f154f6 |
|
|
|
ec380f |
/* tidy up */
|
|
|
ec380f |
__ntapi->zw_close(params->create_process_info->success_state.hfile);
|
|
|
ec380f |
__ntapi->zw_close(params->create_process_info->success_state.hsection);
|
|
|
ec380f |
|
|
|
dd89bb |
if ((status = __ntapi->zw_query_information_process(
|
|
|
dd89bb |
params->hprocess,
|
|
|
dd89bb |
NT_PROCESS_BASIC_INFORMATION,
|
|
|
dd89bb |
¶ms->pbi,sizeof(params->pbi),
|
|
|
dd89bb |
0)))
|
|
|
dd89bb |
return __tt_create_process_cancel(params,status);
|
|
|
dd89bb |
|
|
|
dd89bb |
if (!params->rtblock)
|
|
|
dd89bb |
return NT_STATUS_SUCCESS;
|
|
|
dd89bb |
|
|
|
dd89bb |
/* rtdata */
|
|
|
dd89bb |
if ((status = __ntapi_tt_create_remote_runtime_data(params->hprocess,params->rtblock)))
|
|
|
dd89bb |
return __tt_create_process_cancel(params,status);
|
|
|
dd89bb |
|
|
|
dd89bb |
/* conditional resume */
|
|
|
dd89bb |
if (fresume_thread && (status = __ntapi->zw_resume_thread(params->hthread,0)))
|
|
|
dd89bb |
return __tt_create_process_cancel(params,status);
|
|
|
dd89bb |
|
|
|
dd89bb |
return NT_STATUS_SUCCESS;
|
|
|
dd89bb |
}
|