|
|
c164ff |
/********************************************************/
|
|
|
c164ff |
/* ntapi: Native API core library */
|
|
|
64e606 |
/* Copyright (C) 2013--2021 SysDeer Technologies, LLC */
|
|
|
c164ff |
/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
|
|
|
c164ff |
/********************************************************/
|
|
|
c164ff |
|
|
|
c164ff |
#include <psxtypes/psxtypes.h>
|
|
|
c164ff |
#include <pemagine/pemagine.h>
|
|
|
c164ff |
#include <ntapi/nt_status.h>
|
|
|
c164ff |
#include <ntapi/nt_object.h>
|
|
|
c164ff |
#include <ntapi/nt_thread.h>
|
|
|
c164ff |
#include <ntapi/nt_process.h>
|
|
|
c164ff |
#include <ntapi/nt_string.h>
|
|
|
c164ff |
#include <ntapi/ntapi.h>
|
|
|
c164ff |
#include "ntapi_impl.h"
|
|
|
c164ff |
|
|
|
b625d1 |
#define NT_PROCESS_SPAWN_FLAG_DEBUG_MASK \
|
|
|
b625d1 |
(NT_PROCESS_SPAWN_FLAG_DEBUG_EXECUTION \
|
|
|
b625d1 |
| NT_PROCESS_SPAWN_FLAG_DEBUG_SUSPENDED)
|
|
|
b625d1 |
|
|
|
b862c7 |
#define __SPAWN_NATIVE_PROCESS_RUNTIME_BLOCK_IMGBUF_SIZE (0x10000)
|
|
|
11cc8a |
#define __SPAWN_NATIVE_PROCESS_RUNTIME_BLOCK_ALLOC_SIZE_DEF (0x80000)
|
|
|
11cc8a |
#define __SPAWN_NATIVE_PROCESS_RUNTIME_BLOCK_ALLOC_SIZE_MAX (0x800000)
|
|
|
b862c7 |
|
|
|
c164ff |
static int32_t __stdcall __tt_spawn_return(
|
|
|
c164ff |
nt_runtime_data_block * rtblock,
|
|
|
a88bfb |
void * himgfile,
|
|
|
c164ff |
void * hprocess,
|
|
|
c164ff |
void * hthread,
|
|
|
c164ff |
int32_t status)
|
|
|
c164ff |
{
|
|
|
c164ff |
nt_runtime_data * rtdata;
|
|
|
c164ff |
|
|
|
c164ff |
rtdata = (nt_runtime_data *)rtblock->addr;
|
|
|
c164ff |
|
|
|
c164ff |
if (hprocess) {
|
|
|
c164ff |
__ntapi->zw_terminate_process(
|
|
|
c164ff |
hprocess,status);
|
|
|
c164ff |
|
|
|
c164ff |
__ntapi->zw_close(hprocess);
|
|
|
c164ff |
__ntapi->zw_close(hthread);
|
|
|
c164ff |
}
|
|
|
c164ff |
|
|
|
c164ff |
if (rtdata->hready)
|
|
|
c164ff |
__ntapi->zw_close(
|
|
|
c164ff |
rtdata->hready);
|
|
|
c164ff |
|
|
|
a88bfb |
if (himgfile)
|
|
|
a88bfb |
__ntapi->zw_close(himgfile);
|
|
|
a88bfb |
|
|
|
c164ff |
__ntapi->zw_free_virtual_memory(
|
|
|
c164ff |
NT_CURRENT_PROCESS_HANDLE,
|
|
|
c164ff |
&rtblock->addr,
|
|
|
c164ff |
&rtblock->size,
|
|
|
c164ff |
NT_MEM_RELEASE);
|
|
|
c164ff |
|
|
|
c164ff |
return status;
|
|
|
c164ff |
}
|
|
|
c164ff |
|
|
|
c164ff |
int32_t __stdcall __ntapi_tt_spawn_native_process(nt_spawn_process_params * sparams)
|
|
|
c164ff |
{
|
|
|
c164ff |
int32_t status;
|
|
|
c164ff |
nt_create_process_params cparams;
|
|
|
c164ff |
nt_tty_session_info session;
|
|
|
c164ff |
nt_runtime_data_block rtblock;
|
|
|
c164ff |
nt_runtime_data_block crtblock;
|
|
|
c164ff |
nt_runtime_data * rtctx;
|
|
|
c164ff |
nt_runtime_data * rdata;
|
|
|
c164ff |
nt_unicode_string * imgname;
|
|
|
c164ff |
nt_peb * peb;
|
|
|
11cc8a |
size_t asize;
|
|
|
c164ff |
char * patharg;
|
|
|
c164ff |
void * hat;
|
|
|
c164ff |
void * hfile;
|
|
|
a88bfb |
void * himgfile;
|
|
|
fd587c |
char * src;
|
|
|
fd587c |
char * dst;
|
|
|
fd587c |
int envc;
|
|
|
fd587c |
char ** penv;
|
|
|
fd587c |
char ** pref;
|
|
|
c164ff |
char ** parg;
|
|
|
c164ff |
char ** rargv;
|
|
|
c164ff |
char ** renvp;
|
|
|
c164ff |
wchar16_t ** pwarg;
|
|
|
f2efc5 |
wchar16_t * wenv;
|
|
|
c164ff |
wchar16_t * wch;
|
|
|
b6fdb6 |
wchar16_t * wcap;
|
|
|
c164ff |
void * hchild[2];
|
|
|
c164ff |
wchar16_t * imgbuf;
|
|
|
ec0b96 |
uint32_t fsuspended;
|
|
|
da4030 |
size_t buflen;
|
|
|
da4030 |
size_t written;
|
|
|
fd587c |
size_t needed;
|
|
|
fd587c |
uintptr_t addr;
|
|
|
103960 |
char * raddr;
|
|
|
103960 |
size_t rsize;
|
|
|
c164ff |
|
|
|
c164ff |
/* rtctx (convenience) */
|
|
|
c164ff |
rtctx = sparams->rtctx;
|
|
|
c164ff |
|
|
|
c164ff |
/* validation */
|
|
|
c164ff |
if (!sparams->himage && !sparams->patharg)
|
|
|
c164ff |
return NT_STATUS_OBJECT_PATH_INVALID;
|
|
|
c164ff |
|
|
|
c164ff |
if (rtctx->argc || rtctx->argv || rtctx->envc || rtctx->envp)
|
|
|
c164ff |
return NT_STATUS_INVALID_PARAMETER;
|
|
|
c164ff |
|
|
|
c164ff |
if (rtctx->hready || rtctx->hsession)
|
|
|
c164ff |
return NT_STATUS_INVALID_PARAMETER_MIX;
|
|
|
c164ff |
|
|
|
c164ff |
if (!(peb = (nt_peb *)pe_get_peb_address()))
|
|
|
c164ff |
return NT_STATUS_INTERNAL_ERROR;
|
|
|
c164ff |
|
|
|
c164ff |
if (!peb->process_params)
|
|
|
c164ff |
return NT_STATUS_INTERNAL_ERROR;
|
|
|
c164ff |
|
|
|
c164ff |
/* hat */
|
|
|
3c26f0 |
hat = (sparams->hroot && (sparams->argv[0][0] == '/'))
|
|
|
3c26f0 |
? sparams->hroot
|
|
|
c164ff |
: rtctx->hcwd
|
|
|
c164ff |
? rtctx->hcwd
|
|
|
c164ff |
: peb->process_params->cwd_handle;
|
|
|
c164ff |
|
|
|
c164ff |
/* patharg */
|
|
|
c03267 |
patharg = sparams->patharg
|
|
|
c03267 |
? (sparams->patharg[0] == '/')
|
|
|
c03267 |
? (sparams->patharg[1] == '?')
|
|
|
c03267 |
? &sparams->patharg[0]
|
|
|
c03267 |
: &sparams->patharg[1]
|
|
|
c03267 |
: &sparams->patharg[0]
|
|
|
c03267 |
: 0;
|
|
|
c164ff |
|
|
|
11cc8a |
/* quickly determine whether a large buffer is needed */
|
|
|
11cc8a |
for (asize=0,parg=sparams->argv; parg && *parg; asize++) {
|
|
|
11cc8a |
asize += __ntapi_tt_string_null_offset_multibyte(*parg++);
|
|
|
11cc8a |
|
|
|
11cc8a |
if (asize > (__SPAWN_NATIVE_PROCESS_RUNTIME_BLOCK_ALLOC_SIZE_DEF >> 4))
|
|
|
11cc8a |
parg = 0;
|
|
|
11cc8a |
}
|
|
|
11cc8a |
|
|
|
11cc8a |
for (penv=sparams->envp; penv && *penv; asize++) {
|
|
|
11cc8a |
asize += __ntapi_tt_string_null_offset_multibyte(*penv++);
|
|
|
11cc8a |
|
|
|
11cc8a |
if (asize > (__SPAWN_NATIVE_PROCESS_RUNTIME_BLOCK_ALLOC_SIZE_DEF >> 4))
|
|
|
11cc8a |
penv = 0;
|
|
|
11cc8a |
}
|
|
|
11cc8a |
|
|
|
11cc8a |
if (parg && penv) {
|
|
|
11cc8a |
asize += (parg - sparams->argv) * sizeof(char *);
|
|
|
11cc8a |
asize += (penv - sparams->envp) * sizeof(char *);
|
|
|
11cc8a |
}
|
|
|
11cc8a |
|
|
|
11cc8a |
asize = (asize <= (__SPAWN_NATIVE_PROCESS_RUNTIME_BLOCK_ALLOC_SIZE_DEF >> 4))
|
|
|
11cc8a |
? __SPAWN_NATIVE_PROCESS_RUNTIME_BLOCK_ALLOC_SIZE_DEF
|
|
|
11cc8a |
: __SPAWN_NATIVE_PROCESS_RUNTIME_BLOCK_ALLOC_SIZE_MAX;
|
|
|
11cc8a |
|
|
|
c164ff |
/* rtblock, rdata */
|
|
|
c164ff |
rtblock.addr = 0;
|
|
|
11cc8a |
rtblock.size = asize;
|
|
|
c164ff |
rtblock.remote_addr = 0;
|
|
|
c164ff |
rtblock.remote_size = 0;
|
|
|
c164ff |
rtblock.flags = 0;
|
|
|
c164ff |
|
|
|
c164ff |
if ((status = __ntapi->zw_allocate_virtual_memory(
|
|
|
c164ff |
NT_CURRENT_PROCESS_HANDLE,
|
|
|
c164ff |
&rtblock.addr,0,
|
|
|
c164ff |
&rtblock.size,
|
|
|
c164ff |
NT_MEM_COMMIT,
|
|
|
c164ff |
NT_PAGE_READWRITE)))
|
|
|
c164ff |
return status;
|
|
|
c164ff |
|
|
|
c164ff |
__ntapi->tt_aligned_block_memset(
|
|
|
c164ff |
rtblock.addr,0,rtblock.size);
|
|
|
c164ff |
|
|
|
c164ff |
__ntapi->tt_aligned_block_memcpy(
|
|
|
c164ff |
(uintptr_t *)(rdata = (nt_runtime_data *)rtblock.addr),
|
|
|
c164ff |
(const uintptr_t *)rtctx,
|
|
|
c164ff |
sizeof(*rtctx));
|
|
|
c164ff |
|
|
|
804edf |
/* abi */
|
|
|
804edf |
if (!(__ntapi->tt_guid_compare(&rdata->abi,&(nt_guid)NT_PROCESS_GUID_UNSPEC)))
|
|
|
804edf |
__ntapi->tt_guid_copy(
|
|
|
804edf |
&rdata->abi,
|
|
|
804edf |
&(nt_guid)NT_PROCESS_GUID_RTDATA);
|
|
|
804edf |
|
|
|
c164ff |
/* imgbuf */
|
|
|
c164ff |
imgbuf = (wchar16_t *)rtblock.addr;
|
|
|
11cc8a |
imgbuf += rtblock.size / sizeof(*imgbuf);
|
|
|
b862c7 |
imgbuf -= __SPAWN_NATIVE_PROCESS_RUNTIME_BLOCK_IMGBUF_SIZE / sizeof(*imgbuf);
|
|
|
c164ff |
|
|
|
c164ff |
/* hfile */
|
|
|
a88bfb |
if (sparams->himage) {
|
|
|
a88bfb |
hfile = sparams->himage;
|
|
|
a88bfb |
himgfile = 0;
|
|
|
a88bfb |
|
|
|
a88bfb |
} else if ((status = __ntapi_tt_open_file_utf8(
|
|
|
c164ff |
&hfile,hat,patharg,1,
|
|
|
a88bfb |
imgbuf,__SPAWN_NATIVE_PROCESS_RUNTIME_BLOCK_IMGBUF_SIZE))) {
|
|
|
a88bfb |
return __tt_spawn_return(
|
|
|
a88bfb |
&rtblock,0,0,0,
|
|
|
a88bfb |
status);
|
|
|
a88bfb |
|
|
|
a88bfb |
himgfile = hfile;
|
|
|
a88bfb |
}
|
|
|
c164ff |
|
|
|
c164ff |
/* imgname */
|
|
|
c164ff |
if ((status = __ntapi->zw_query_object(
|
|
|
c164ff |
hfile,
|
|
|
c164ff |
NT_OBJECT_NAME_INFORMATION,
|
|
|
b862c7 |
imgbuf,__SPAWN_NATIVE_PROCESS_RUNTIME_BLOCK_IMGBUF_SIZE,
|
|
|
da4030 |
&(uint32_t){0})))
|
|
|
c164ff |
return __tt_spawn_return(
|
|
|
a88bfb |
&rtblock,himgfile,0,0,
|
|
|
a88bfb |
status);
|
|
|
c164ff |
|
|
|
c164ff |
imgname = (nt_unicode_string *)imgbuf;
|
|
|
c164ff |
|
|
|
b6fdb6 |
/* imgbuf must remain intact until after creation of the child process */
|
|
|
da4030 |
buflen = rtblock.size;
|
|
|
da4030 |
buflen -= sizeof(*rdata);
|
|
|
b6fdb6 |
buflen -= __SPAWN_NATIVE_PROCESS_RUNTIME_BLOCK_IMGBUF_SIZE;
|
|
|
da4030 |
|
|
|
b6fdb6 |
/* argv, envp */
|
|
|
c164ff |
if ((status = __ntapi->tt_array_copy_utf8(
|
|
|
c164ff |
&rdata->argc,
|
|
|
c164ff |
(const char **)sparams->argv,
|
|
|
c164ff |
(const char **)sparams->envp,
|
|
|
2104cf |
sparams->interp,
|
|
|
c164ff |
sparams->optarg,
|
|
|
15812f |
sparams->script,
|
|
|
c164ff |
rtblock.addr,
|
|
|
c164ff |
rdata->buffer,
|
|
|
da4030 |
buflen,&written)))
|
|
|
c164ff |
return __tt_spawn_return(
|
|
|
a88bfb |
&rtblock,himgfile,0,0,
|
|
|
a88bfb |
status);
|
|
|
c164ff |
|
|
|
da4030 |
rdata->argv = (char **)&((nt_runtime_data *)0)->buffer;
|
|
|
da4030 |
rdata->envp = rdata->argv + rdata->argc + 1;
|
|
|
c164ff |
|
|
|
da4030 |
rdata->wargv = (wchar16_t **)rdata->buffer;
|
|
|
da4030 |
rdata->wargv += written / sizeof(wchar16_t **) + 1;
|
|
|
da4030 |
rdata->wenvp = rdata->wargv + rdata->argc + 1;
|
|
|
c164ff |
|
|
|
c164ff |
rargv = rdata->argv + ((uintptr_t)rtblock.addr / sizeof(char *));
|
|
|
c164ff |
renvp = rdata->envp + ((uintptr_t)rtblock.addr / sizeof(char *));
|
|
|
c164ff |
|
|
|
c164ff |
for (rdata->envc=0, parg=sparams->envp; *parg; parg++)
|
|
|
c164ff |
rdata->envc++;
|
|
|
c164ff |
|
|
|
c164ff |
pwarg = rdata->wenvp + rdata->envc + 1;
|
|
|
da4030 |
wch = (wchar16_t *)pwarg;
|
|
|
da4030 |
|
|
|
b6fdb6 |
wcap = (wchar16_t *)rtblock.addr;
|
|
|
b6fdb6 |
wcap += rtblock.size / sizeof(wchar16_t);
|
|
|
da4030 |
|
|
|
b6fdb6 |
buflen = (wcap - wch) * sizeof(wchar16_t);
|
|
|
b6fdb6 |
buflen -= __SPAWN_NATIVE_PROCESS_RUNTIME_BLOCK_IMGBUF_SIZE;
|
|
|
c164ff |
|
|
|
c164ff |
if ((status = __ntapi->tt_array_convert_utf8_to_utf16(
|
|
|
c164ff |
rargv,
|
|
|
c164ff |
rdata->wargv,
|
|
|
da4030 |
rdata,wch,
|
|
|
da4030 |
buflen,&written)))
|
|
|
c164ff |
return __tt_spawn_return(
|
|
|
a88bfb |
&rtblock,himgfile,0,0,
|
|
|
a88bfb |
status);
|
|
|
c164ff |
|
|
|
b6fdb6 |
wch += written / sizeof(wchar16_t);
|
|
|
da4030 |
buflen -= written;
|
|
|
c164ff |
|
|
|
c164ff |
if ((status = __ntapi->tt_array_convert_utf8_to_utf16(
|
|
|
c164ff |
renvp,
|
|
|
c164ff |
rdata->wenvp,
|
|
|
da4030 |
rdata,wch,
|
|
|
da4030 |
buflen,&written)))
|
|
|
c164ff |
return __tt_spawn_return(
|
|
|
a88bfb |
&rtblock,himgfile,0,0,
|
|
|
a88bfb |
status);
|
|
|
c164ff |
|
|
|
c164ff |
rdata->wargv -= (uintptr_t)rtblock.addr / sizeof(wchar16_t *);
|
|
|
c164ff |
rdata->wenvp -= (uintptr_t)rtblock.addr / sizeof(wchar16_t *);
|
|
|
c164ff |
|
|
|
f2efc5 |
wenv = wch;
|
|
|
b6fdb6 |
wch += written / sizeof(wchar16_t);
|
|
|
da4030 |
buflen -= written;
|
|
|
da4030 |
|
|
|
fd587c |
/* w32 environment */
|
|
|
fd587c |
if (rtctx->w32_envp) {
|
|
|
fd587c |
addr = (uintptr_t)wch;
|
|
|
fd587c |
addr += sizeof(uintptr_t) - 1;
|
|
|
fd587c |
addr /= sizeof(uintptr_t);
|
|
|
fd587c |
addr *= sizeof(uintptr_t);
|
|
|
fd587c |
|
|
|
fd587c |
penv = rtctx->w32_envp;
|
|
|
fd587c |
needed = sizeof(char *);
|
|
|
fd587c |
|
|
|
fd587c |
for (envc=0; *penv; envc++) {
|
|
|
fd587c |
needed += sizeof(char *);
|
|
|
fd587c |
needed += __ntapi->tt_string_null_offset_multibyte(*penv);
|
|
|
fd587c |
penv++;
|
|
|
fd587c |
}
|
|
|
fd587c |
|
|
|
fd587c |
needed += sizeof(uintptr_t) - 1;
|
|
|
fd587c |
needed /= sizeof(uintptr_t);
|
|
|
fd587c |
needed *= sizeof(uintptr_t);
|
|
|
fd587c |
|
|
|
fd587c |
if (buflen < needed)
|
|
|
fd587c |
return __tt_spawn_return(
|
|
|
a88bfb |
&rtblock,himgfile,0,0,
|
|
|
a88bfb |
NT_STATUS_BUFFER_TOO_SMALL);
|
|
|
fd587c |
|
|
|
fd587c |
rdata->w32_envp = (char **)(addr - (uintptr_t)rtblock.addr);
|
|
|
fd587c |
|
|
|
fd587c |
pref = (char **)addr;
|
|
|
fd587c |
dst = (char *)&pref[++envc];
|
|
|
fd587c |
|
|
|
fd587c |
|
|
|
fd587c |
for (penv=rtctx->w32_envp; *penv; penv++) {
|
|
|
fd587c |
*pref++ = dst - (uintptr_t)rtblock.addr;
|
|
|
fd587c |
|
|
|
fd587c |
for (src=*penv; *src; src++,dst++)
|
|
|
fd587c |
*dst = *src;
|
|
|
fd587c |
|
|
|
fd587c |
*dst++ = 0;
|
|
|
fd587c |
}
|
|
|
fd587c |
|
|
|
fd587c |
wch += needed / sizeof(wchar16_t);
|
|
|
fd587c |
buflen -= needed;
|
|
|
fd587c |
}
|
|
|
fd587c |
|
|
|
c164ff |
/* session */
|
|
|
c164ff |
if (sparams->hready) {
|
|
|
c164ff |
if ((status = __ntapi->zw_duplicate_object(
|
|
|
c164ff |
NT_CURRENT_PROCESS_HANDLE,
|
|
|
c164ff |
sparams->hready,
|
|
|
c164ff |
NT_CURRENT_PROCESS_HANDLE,
|
|
|
c164ff |
&rdata->hready,
|
|
|
c164ff |
0,0,
|
|
|
c164ff |
NT_DUPLICATE_SAME_ACCESS|NT_DUPLICATE_SAME_ATTRIBUTES)))
|
|
|
c164ff |
return __tt_spawn_return(
|
|
|
a88bfb |
&rtblock,himgfile,0,0,
|
|
|
a88bfb |
status);
|
|
|
c164ff |
} else {
|
|
|
c164ff |
if ((status = __ntapi->tt_create_inheritable_event(
|
|
|
c164ff |
&rdata->hready,
|
|
|
c164ff |
NT_NOTIFICATION_EVENT,
|
|
|
c164ff |
NT_EVENT_NOT_SIGNALED)))
|
|
|
c164ff |
return __tt_spawn_return(
|
|
|
a88bfb |
&rtblock,himgfile,0,0,
|
|
|
a88bfb |
status);
|
|
|
c164ff |
}
|
|
|
c164ff |
|
|
|
ec0b96 |
/* process flags */
|
|
|
ec0b96 |
if (sparams->processflags & NT_PROCESS_CREATE_FLAGS_CREATE_THREAD_SUSPENDED)
|
|
|
ec0b96 |
fsuspended = NT_CREATE_SUSPENDED;
|
|
|
ec0b96 |
|
|
|
ec0b96 |
else if (sparams->threadflags & NT_CREATE_SUSPENDED)
|
|
|
ec0b96 |
fsuspended = NT_CREATE_SUSPENDED;
|
|
|
ec0b96 |
|
|
|
b625d1 |
else if (sparams->spawnflags & NT_PROCESS_SPAWN_FLAG_DEBUG_SUSPENDED)
|
|
|
b625d1 |
fsuspended = NT_CREATE_SUSPENDED;
|
|
|
b625d1 |
|
|
|
b625d1 |
else if (sparams->spawnflags & NT_PROCESS_SPAWN_FLAG_DEBUG_EXECUTION)
|
|
|
b625d1 |
fsuspended = NT_CREATE_SUSPENDED;
|
|
|
b625d1 |
|
|
|
c164ff |
/* cparams */
|
|
|
c164ff |
__ntapi->tt_aligned_block_memset(
|
|
|
c164ff |
&cparams,0,sizeof(cparams));
|
|
|
c164ff |
|
|
|
c164ff |
__ntapi->tt_generic_memcpy(
|
|
|
c164ff |
&crtblock,&rtblock,sizeof(rtblock));
|
|
|
c164ff |
|
|
|
c164ff |
cparams.image_name = imgname->buffer;
|
|
|
c164ff |
cparams.creation_flags_process = NT_PROCESS_CREATE_FLAGS_INHERIT_HANDLES;
|
|
|
c164ff |
cparams.creation_flags_thread = NT_PROCESS_CREATE_FLAGS_CREATE_THREAD_SUSPENDED;
|
|
|
f2efc5 |
cparams.environment = wenv;
|
|
|
c164ff |
|
|
|
91299b |
/* crtblock: alloc size: _needed_only_, round up to system granularity */
|
|
|
da4030 |
crtblock.size = (size_t)wch - (size_t)rdata;
|
|
|
da4030 |
crtblock.size += 0xFFFF;
|
|
|
da4030 |
crtblock.size |= 0xFFFF;
|
|
|
da4030 |
crtblock.size ^= 0xFFFF;
|
|
|
da4030 |
cparams.rtblock = &crtblock;
|
|
|
c164ff |
|
|
|
c164ff |
/* hoppla */
|
|
|
c164ff |
if ((status = __ntapi->tt_create_native_process(&cparams)))
|
|
|
c164ff |
return __tt_spawn_return(
|
|
|
a88bfb |
&rtblock,himgfile,0,0,
|
|
|
a88bfb |
status);
|
|
|
39c844 |
|
|
|
b625d1 |
/* debug */
|
|
|
b625d1 |
if (sparams->spawnflags & NT_PROCESS_SPAWN_FLAG_DEBUG_MASK)
|
|
|
b625d1 |
if ((status = __ntapi->tt_debug_create_attach_object(
|
|
|
b625d1 |
&sparams->hdbgobj,
|
|
|
b625d1 |
cparams.hprocess,
|
|
|
b625d1 |
NT_DEBUG_KILL_ON_EXIT)))
|
|
|
b625d1 |
return __tt_spawn_return(
|
|
|
b625d1 |
&rtblock,
|
|
|
a88bfb |
himgfile,
|
|
|
b625d1 |
cparams.hprocess,
|
|
|
b625d1 |
cparams.hthread,
|
|
|
b625d1 |
status);
|
|
|
b625d1 |
|
|
|
103960 |
/* additional context */
|
|
|
103960 |
if (rtctx->ctx_addr) {
|
|
|
103960 |
rdata->ctx_addr = 0;
|
|
|
103960 |
rdata->ctx_commit = rtctx->ctx_size;
|
|
|
103960 |
|
|
|
103960 |
rdata->ctx_commit += (__NT_INTERNAL_PAGE_SIZE - 1);
|
|
|
103960 |
rdata->ctx_commit |= (__NT_INTERNAL_PAGE_SIZE - 1);
|
|
|
103960 |
rdata->ctx_commit ^= (__NT_INTERNAL_PAGE_SIZE - 1);
|
|
|
103960 |
|
|
|
103960 |
if ((status = __ntapi->zw_allocate_virtual_memory(
|
|
|
103960 |
cparams.hprocess,
|
|
|
103960 |
&rdata->ctx_addr,0,
|
|
|
103960 |
&rdata->ctx_commit,
|
|
|
103960 |
NT_MEM_COMMIT,
|
|
|
103960 |
NT_PAGE_READWRITE)))
|
|
|
103960 |
return __tt_spawn_return(
|
|
|
103960 |
&rtblock,
|
|
|
a88bfb |
himgfile,
|
|
|
103960 |
cparams.hprocess,
|
|
|
103960 |
cparams.hthread,
|
|
|
103960 |
status);
|
|
|
103960 |
|
|
|
103960 |
if ((status = __ntapi->zw_write_virtual_memory(
|
|
|
103960 |
cparams.hprocess,
|
|
|
103960 |
rdata->ctx_addr,
|
|
|
103960 |
rtctx->ctx_addr,
|
|
|
103960 |
rtctx->ctx_size,
|
|
|
103960 |
&rdata->ctx_size)))
|
|
|
103960 |
return __tt_spawn_return(
|
|
|
103960 |
&rtblock,
|
|
|
a88bfb |
himgfile,
|
|
|
103960 |
cparams.hprocess,
|
|
|
103960 |
cparams.hthread,
|
|
|
103960 |
status);
|
|
|
103960 |
|
|
|
103960 |
raddr = crtblock.remote_addr;
|
|
|
103960 |
raddr += __offsetof(nt_runtime_data,ctx_addr);
|
|
|
103960 |
|
|
|
103960 |
rsize = __offsetof(nt_runtime_data,ctx_offset);
|
|
|
103960 |
rsize -= __offsetof(nt_runtime_data,ctx_addr);
|
|
|
103960 |
|
|
|
103960 |
if ((status = __ntapi->zw_write_virtual_memory(
|
|
|
103960 |
cparams.hprocess,
|
|
|
103960 |
raddr,(char *)&rdata->ctx_addr,
|
|
|
103960 |
rsize,&rsize)))
|
|
|
103960 |
return __tt_spawn_return(
|
|
|
103960 |
&rtblock,
|
|
|
a88bfb |
himgfile,
|
|
|
103960 |
cparams.hprocess,
|
|
|
103960 |
cparams.hthread,
|
|
|
103960 |
status);
|
|
|
103960 |
}
|
|
|
103960 |
|
|
|
c164ff |
/* tty session (optional) */
|
|
|
c164ff |
if (sparams->hsession) {
|
|
|
c164ff |
if ((status = __ntapi->tty_client_process_register(
|
|
|
c164ff |
sparams->hsession,
|
|
|
c164ff |
cparams.pbi.unique_process_id,
|
|
|
c164ff |
0,NT_TTY_INHERIT_HANDLES,0)))
|
|
|
c164ff |
return __tt_spawn_return(
|
|
|
c164ff |
&rtblock,
|
|
|
a88bfb |
himgfile,
|
|
|
c164ff |
cparams.hprocess,
|
|
|
c164ff |
cparams.hthread,
|
|
|
c164ff |
status);
|
|
|
c164ff |
|
|
|
c164ff |
session.pid = rtctx->alt_cid_self.pid;
|
|
|
c164ff |
session.pgid = rtctx->alt_cid_self.pgid;
|
|
|
c164ff |
session.sid = rtctx->alt_cid_self.sid;
|
|
|
3e609e |
session.syspid = (uint32_t)cparams.pbi.unique_process_id;
|
|
|
c164ff |
|
|
|
875bdc |
if ((status = __ntapi->tty_client_session_set(
|
|
|
875bdc |
sparams->hsession,
|
|
|
875bdc |
&session)))
|
|
|
c164ff |
return __tt_spawn_return(
|
|
|
c164ff |
&rtblock,
|
|
|
a88bfb |
himgfile,
|
|
|
c164ff |
cparams.hprocess,
|
|
|
c164ff |
cparams.hthread,
|
|
|
c164ff |
status);
|
|
|
c164ff |
}
|
|
|
c164ff |
|
|
|
c164ff |
/* output */
|
|
|
c164ff |
sparams->hprocess = cparams.hprocess;
|
|
|
c164ff |
sparams->hthread = cparams.hthread;
|
|
|
c164ff |
sparams->rdata = crtblock.remote_addr;
|
|
|
c164ff |
|
|
|
c164ff |
sparams->cid.process_id = cparams.pbi.unique_process_id;
|
|
|
c164ff |
sparams->cid.thread_id = cparams.cid.thread_id;
|
|
|
c164ff |
|
|
|
c164ff |
__ntapi->tt_generic_memcpy(
|
|
|
c164ff |
&sparams->pbi,
|
|
|
c164ff |
&cparams.pbi,
|
|
|
c164ff |
sizeof(nt_pbi));
|
|
|
c164ff |
|
|
|
c164ff |
/* create suspended? */
|
|
|
ec0b96 |
if (fsuspended)
|
|
|
c164ff |
return __tt_spawn_return(
|
|
|
a88bfb |
&rtblock,himgfile,0,0,NT_STATUS_SUCCESS);
|
|
|
c164ff |
|
|
|
c164ff |
/* tada */
|
|
|
c164ff |
if ((status = __ntapi->zw_resume_thread(cparams.hthread,0)))
|
|
|
c164ff |
return __tt_spawn_return(
|
|
|
c164ff |
&rtblock,
|
|
|
a88bfb |
himgfile,
|
|
|
c164ff |
cparams.hprocess,
|
|
|
c164ff |
cparams.hthread,
|
|
|
c164ff |
status);
|
|
|
c164ff |
|
|
|
c164ff |
/* hready */
|
|
|
c164ff |
hchild[1] = cparams.hprocess;
|
|
|
c164ff |
hchild[0] = rdata->hready;
|
|
|
c164ff |
|
|
|
c164ff |
__ntapi->zw_wait_for_multiple_objects(
|
|
|
c164ff |
2,hchild,
|
|
|
c164ff |
NT_WAIT_ANY,
|
|
|
c164ff |
NT_SYNC_NON_ALERTABLE,
|
|
|
c164ff |
sparams->timeout);
|
|
|
c164ff |
|
|
|
c164ff |
if ((status = __ntapi->zw_query_event(
|
|
|
c164ff |
rdata->hready,
|
|
|
c164ff |
NT_EVENT_BASIC_INFORMATION,
|
|
|
c164ff |
&sparams->eready,
|
|
|
c164ff |
sizeof(sparams->eready),
|
|
|
c164ff |
&(size_t){0})))
|
|
|
c164ff |
return __tt_spawn_return(
|
|
|
c164ff |
&rtblock,
|
|
|
a88bfb |
himgfile,
|
|
|
c164ff |
cparams.hprocess,
|
|
|
c164ff |
cparams.hthread,
|
|
|
c164ff |
status);
|
|
|
c164ff |
|
|
|
c164ff |
/* all done */
|
|
|
c164ff |
return __tt_spawn_return(
|
|
|
a88bfb |
&rtblock,himgfile,0,0,NT_STATUS_SUCCESS);
|
|
|
c164ff |
}
|