Blame src/process/ntapi_tt_create_native_process_v2.c

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
				&params->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
			&params->hprocess,
dd89bb
			&params->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
			&params->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 */
c88b65
	struct _nt_runtime_data * rtdata;
ec1073
	rtdata = (struct _nt_runtime_data *)params->rtblock->addr;
c88b65
	rtdata->flags &= ~NT_RUNTIME_DATA_ARGV_ENVP_RELOCATED;
c88b65
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
}