From ec0b962a70d7ffe8606d2fa553c328aa43186a1d Mon Sep 17 00:00:00 2001 From: midipix Date: Oct 30 2017 01:36:08 +0000 Subject: __ntapi_tt_spawn_foreign_process(): optionally use kernel32 as the backend. --- diff --git a/include/ntapi/nt_process.h b/include/ntapi/nt_process.h index facd639..1e2c630 100644 --- a/include/ntapi/nt_process.h +++ b/include/ntapi/nt_process.h @@ -185,6 +185,11 @@ typedef enum _nt_process_opcode_idx { #define NT_CREATE_PROCESS_EXT_CONSOLE_FLAG_INHERIT_STDOUT (0x08) #define NT_CREATE_PROCESS_EXT_CONSOLE_FLAG_INHERIT_STDERR (0x10) +/* tt_spawn_native_process / tt_spawn_foreign_process flags */ +#define NT_PROCESS_CREATE_FLAGS_DELEGATE_TO_SYSTEM_LIBRARY (0x00000001) +#define NT_PROCESS_CREATE_FLAGS_DELEGATE_TO_PTY_SERVER (0x00000002) +#define NT_PROCESS_CREATE_FLAGS_DELEGATE_TO_BRIDGE_PROCESS (0x00000004) + /* nt_runtime_data_block flag bits */ #define NT_RUNTIME_DATA_DUPLICATE_SESSION_HANDLES (0x01) @@ -659,7 +664,10 @@ typedef struct _nt_spawn_process_params { __in char ** envp; __in void * hready; __in nt_timeout * timeout; - __in int fsuspended; + __in uint32_t processflags; + __in uint32_t threadflags; + __in uint32_t spawnflags; + __in uint32_t reserved; __in nt_process_startup_info * startupinfo; } nt_spawn_process_params; 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);