summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/process/ntapi_tt_spawn_foreign_process.c107
-rw-r--r--src/process/ntapi_tt_spawn_native_process.c10
2 files changed, 105 insertions, 12 deletions
diff --git a/src/process/ntapi_tt_spawn_foreign_process.c b/src/process/ntapi_tt_spawn_foreign_process.c
index cc9fac4..ea5f0cf 100644
--- a/src/process/ntapi_tt_spawn_foreign_process.c
+++ b/src/process/ntapi_tt_spawn_foreign_process.c
@@ -15,6 +15,19 @@
#include "ntapi_impl.h"
+typedef int32_t win32_create_process_utf16(
+ __in_opt wchar16_t * appname,
+ __in_out_opt wchar16_t * cmdline,
+ __in_opt nt_sa * process_sa_attr,
+ __in_opt nt_sa * thread_sa_attr,
+ __in int32_t inherit_handles,
+ __in uint32_t creation_flags,
+ __in wchar16_t * environment,
+ __in_opt wchar16_t * cwd,
+ __in nt_process_startup_info * startup_info,
+ __out nt_process_info * process_info);
+
+
static int32_t __stdcall __tt_spawn_return(
nt_runtime_data_block * rtblock,
void * hprocess,
@@ -41,11 +54,13 @@ static int32_t __stdcall __tt_spawn_return(
int32_t __stdcall __ntapi_tt_spawn_foreign_process(nt_spawn_process_params * sparams)
{
int32_t status;
+ nt_process_info processinfo;
nt_create_process_params cparams;
nt_runtime_data_block rtblock;
nt_unicode_string * imgname;
nt_peb * peb;
char * patharg;
+ void * hkernel32;
void * hat;
void * hfile;
uint32_t written;
@@ -56,18 +71,20 @@ int32_t __stdcall __ntapi_tt_spawn_foreign_process(nt_spawn_process_params * spa
char * ch_arg;
char * ch_cap;
int fquote;
+ uint32_t finherit;
+ uint32_t fsuspended;
wchar16_t * cmdline;
nt_strconv_mbtonative uparams;
nt_unicode_string nt_image;
nt_unicode_string nt_cmd_line;
+ win32_create_process_utf16 * create_process_fn;
+ char create_process_fn_name[]
+ = "CreateProcessW";
/* validation */
if (!sparams->argv)
return NT_STATUS_INVALID_PARAMETER;
- if (!sparams->startupinfo)
- return NT_STATUS_INVALID_PARAMETER;
-
if (!sparams->himage && !sparams->patharg)
return NT_STATUS_OBJECT_PATH_INVALID;
@@ -80,6 +97,15 @@ int32_t __stdcall __ntapi_tt_spawn_foreign_process(nt_spawn_process_params * spa
if (sparams->rtctx || sparams->hsession || sparams->hready)
return NT_STATUS_INVALID_PARAMETER;
+ /* hkernel32 */
+ if (!(hkernel32 = pe_get_kernel32_module_handle()))
+ return NT_STATUS_DLL_NOT_FOUND;
+
+ if (!(create_process_fn = (win32_create_process_utf16 *)
+ (pe_get_procedure_address(
+ hkernel32,create_process_fn_name))))
+ return NT_STATUS_PROCEDURE_NOT_FOUND;
+
/* hat */
hat = (sparams->hroot && (sparams->argv[0][0] == '/'))
? sparams->hroot
@@ -272,14 +298,73 @@ int32_t __stdcall __ntapi_tt_spawn_foreign_process(nt_spawn_process_params * spa
__ntapi->rtl_normalize_process_params(cparams.process_params);
- cparams.process_params->hstdin = sparams->startupinfo->hstdin;
- cparams.process_params->hstdout = sparams->startupinfo->hstdout;
- cparams.process_params->hstderr = sparams->startupinfo->hstderr;
+ if (sparams->startupinfo) {
+ cparams.process_params->hstdin = sparams->startupinfo->hstdin;
+ cparams.process_params->hstdout = sparams->startupinfo->hstdout;
+ cparams.process_params->hstderr = sparams->startupinfo->hstderr;
+ }
- /* hoppla */
- if ((status = __ntapi->tt_create_native_process(&cparams)))
- return __tt_spawn_return(
- &rtblock,0,0,status);
+ /* inherit handles? */
+ if (cparams.process_params->hstdin
+ || cparams.process_params->hstdout
+ || cparams.process_params->hstderr)
+ finherit = 1;
+
+ else if (sparams->processflags & NT_PROCESS_CREATE_FLAGS_INHERIT_HANDLES)
+ finherit = 1;
+
+ else
+ finherit = 0;
+
+ /* process flags */
+ if (sparams->processflags & NT_PROCESS_CREATE_FLAGS_CREATE_THREAD_SUSPENDED)
+ fsuspended = NT_CREATE_SUSPENDED;
+
+ else if (sparams->threadflags & NT_CREATE_SUSPENDED)
+ fsuspended = NT_CREATE_SUSPENDED;
+
+ else
+ fsuspended = 0;
+
+ /* hoppla: try either via kernel32 (sparams->startupinfo), or natively */
+ if (sparams->spawnflags & NT_PROCESS_CREATE_FLAGS_DELEGATE_TO_SYSTEM_LIBRARY) {
+ processinfo.hprocess = 0;
+ processinfo.hthread = 0;
+ processinfo.process_id = 0;
+ processinfo.thread_id = 0;
+
+ if (!(create_process_fn(
+ nt_image.buffer,
+ nt_cmd_line.buffer,
+ 0,
+ 0,
+ finherit,
+ fsuspended,
+ 0,
+ 0,
+ sparams->startupinfo,
+ &processinfo)))
+ return __tt_spawn_return(
+ &rtblock,0,0,status);
+
+ if ((status = __ntapi->zw_query_information_process(
+ processinfo.hprocess,
+ NT_PROCESS_BASIC_INFORMATION,
+ &cparams.pbi,sizeof(cparams.pbi),
+ 0)))
+ return __tt_spawn_return(
+ &rtblock,0,0,status);
+
+ cparams.hprocess = processinfo.hprocess;
+ cparams.hthread = processinfo.hthread;
+
+ cparams.cid.process_id = processinfo.process_id;
+ cparams.cid.thread_id = processinfo.thread_id;
+ } else {
+ if ((status = __ntapi->tt_create_native_process(&cparams)))
+ return __tt_spawn_return(
+ &rtblock,0,0,status);
+ }
/* tidy up */
if (!sparams->himage)
@@ -298,7 +383,7 @@ int32_t __stdcall __ntapi_tt_spawn_foreign_process(nt_spawn_process_params * spa
sizeof(nt_pbi));
/* create suspended? */
- if (sparams->fsuspended)
+ if (fsuspended)
return __tt_spawn_return(
&rtblock,0,0,NT_STATUS_SUCCESS);
diff --git a/src/process/ntapi_tt_spawn_native_process.c b/src/process/ntapi_tt_spawn_native_process.c
index 1458e78..ae62d35 100644
--- a/src/process/ntapi_tt_spawn_native_process.c
+++ b/src/process/ntapi_tt_spawn_native_process.c
@@ -67,6 +67,7 @@ int32_t __stdcall __ntapi_tt_spawn_native_process(nt_spawn_process_params * spar
void * hchild[2];
uint32_t written;
wchar16_t * imgbuf;
+ uint32_t fsuspended;
/* rtctx (convenience) */
rtctx = sparams->rtctx;
@@ -229,6 +230,13 @@ int32_t __stdcall __ntapi_tt_spawn_native_process(nt_spawn_process_params * spar
&rtblock,0,0,status);
}
+ /* process flags */
+ if (sparams->processflags & NT_PROCESS_CREATE_FLAGS_CREATE_THREAD_SUSPENDED)
+ fsuspended = NT_CREATE_SUSPENDED;
+
+ else if (sparams->threadflags & NT_CREATE_SUSPENDED)
+ fsuspended = NT_CREATE_SUSPENDED;
+
/* cparams */
__ntapi->tt_aligned_block_memset(
&cparams,0,sizeof(cparams));
@@ -293,7 +301,7 @@ int32_t __stdcall __ntapi_tt_spawn_native_process(nt_spawn_process_params * spar
sizeof(nt_pbi));
/* create suspended? */
- if (sparams->fsuspended)
+ if (fsuspended)
return __tt_spawn_return(
&rtblock,0,0,NT_STATUS_SUCCESS);