diff --git a/include/ntapi/nt_process.h b/include/ntapi/nt_process.h index ccc2e14..d42ac4b 100644 --- a/include/ntapi/nt_process.h +++ b/include/ntapi/nt_process.h @@ -880,9 +880,10 @@ typedef int32_t __stdcall ntapi_rtl_clone_user_process( /* extensions */ -typedef intptr_t __fastcall ntapi_tt_fork( +typedef int32_t __fastcall ntapi_tt_fork( __out void ** hprocess, - __out void ** hthread); + __out void ** hthread, + __out nt_cid * cid); typedef int32_t __stdcall ntapi_tt_create_remote_process_params( diff --git a/src/process/ntapi_tt_fork.c b/src/process/ntapi_tt_fork.c index e503508..20c7c25 100644 --- a/src/process/ntapi_tt_fork.c +++ b/src/process/ntapi_tt_fork.c @@ -1,3 +1,4 @@ + /********************************************************/ /* ntapi: Native API core library */ /* Copyright (C) 2013--2021 SysDeer Technologies, LLC */ @@ -29,7 +30,7 @@ static int __ipc_memfn( return DALIST_EMEMFN; } -static intptr_t __fastcall __ntapi_tt_fork_finalize(void ** hprocess) +static int32_t __fastcall __ntapi_tt_fork_finalize(void ** hprocess) { int32_t status; int page; @@ -89,7 +90,7 @@ static intptr_t __fastcall __ntapi_tt_fork_finalize(void ** hprocess) rtdata->ipc_keys[4] = 0; rtdata->ipc_keys[5] = 0; - return 0; + return NT_STATUS_SUCCESS; } static int32_t __stdcall __fork_thread(void * ctx) @@ -112,7 +113,7 @@ static int32_t __stdcall __fork_thread(void * ctx) hready,0)); } -static intptr_t __fastcall __ntapi_tt_fork_child( +static int32_t __fastcall __ntapi_tt_fork_child( void * hresumed, void * hready, void ** hthread) @@ -185,7 +186,7 @@ static intptr_t __fastcall __ntapi_tt_fork_child( __ntapi->zw_close(hresumed); __ntapi->zw_close(hready); __ntapi->zw_close(tparams.hthread); - return 0; + return NT_STATUS_SUCCESS; } timeout.quad = (-1) * 10 * 1000 * 250; @@ -199,7 +200,7 @@ static intptr_t __fastcall __ntapi_tt_fork_child( __ntapi->zw_close(hresumed); __ntapi->zw_close(hready); __ntapi->zw_close(tparams.hthread); - return 0; + return NT_STATUS_SUCCESS; } __ntapi->zw_terminate_thread( @@ -217,7 +218,7 @@ static intptr_t __fastcall __ntapi_tt_fork_child( __ntapi->zw_close(hresumed); __ntapi->zw_close(hready); __ntapi->zw_close(tparams.hthread); - return 0; + return NT_STATUS_SUCCESS; } return __ntapi->zw_terminate_process( @@ -248,11 +249,8 @@ static intptr_t __fastcall __ntapi_tt_fork_parent( NT_SYNC_NON_ALERTABLE, &timeout); - if (status == NT_STATUS_SUCCESS) { - __ntapi->zw_close(hresumed); - __ntapi->zw_close(hready); + if (status == NT_STATUS_SUCCESS) return NT_STATUS_SUCCESS; - } __ntapi->zw_suspend_thread( *hthread,&prev); @@ -271,8 +269,6 @@ static intptr_t __fastcall __ntapi_tt_fork_parent( __ntapi->zw_resume_thread( *hthread,0); - __ntapi->zw_close(hresumed); - __ntapi->zw_close(hready); return NT_STATUS_SUCCESS; } @@ -289,12 +285,12 @@ static intptr_t __fastcall __ntapi_tt_fork_parent( return status; } -intptr_t __fastcall __ntapi_tt_fork( +int32_t __fastcall __ntapi_tt_fork( __out void ** hprocess, - __out void ** hthread) + __out void ** hthread, + __out nt_cid * cid) { int32_t status; - intptr_t pid; void * hresumed; void * hready; int i; @@ -303,42 +299,47 @@ intptr_t __fastcall __ntapi_tt_fork( &hresumed, NT_NOTIFICATION_EVENT, NT_EVENT_NOT_SIGNALED))) - return -1; + return status; if ((status = __ntapi->tt_create_inheritable_event( &hready, NT_NOTIFICATION_EVENT, NT_EVENT_NOT_SIGNALED))) - return -1; + return status; for (i=0; i<32; i++) { if (__ntapi->zw_create_user_process) - pid = __ntapi_tt_fork_v2(hprocess,hthread); + status = __ntapi_tt_fork_v2(hprocess,hthread,cid); else - pid = __ntapi_tt_fork_v1(hprocess,hthread); + status = __ntapi_tt_fork_v1(hprocess,hthread,cid); - if (pid == 0) { + if (status) { + __ntapi->zw_close(hresumed); + __ntapi->zw_close(hready); + return status; + } + + if (cid->process_id == 0) { __ntapi_tt_fork_child( hresumed,hready,hthread); return __ntapi_tt_fork_finalize( hprocess); + } - } else if (pid > 0) { - if (!(__ntapi_tt_fork_parent( - hprocess,hthread, - hresumed,hready))) - return pid; + status = __ntapi_tt_fork_parent( + hprocess,hthread, + hresumed,hready); - } else { + if (status == NT_STATUS_SUCCESS) { __ntapi->zw_close(hresumed); __ntapi->zw_close(hready); - return -1; + return NT_STATUS_SUCCESS; } } __ntapi->zw_close(hresumed); __ntapi->zw_close(hready); - return -1; + return NT_STATUS_UNSUCCESSFUL; } diff --git a/src/process/ntapi_tt_fork_v1.c b/src/process/ntapi_tt_fork_v1.c index d017cf0..7662b72 100644 --- a/src/process/ntapi_tt_fork_v1.c +++ b/src/process/ntapi_tt_fork_v1.c @@ -40,7 +40,7 @@ static intptr_t __tt_fork_cancel(void * hprocess,int32_t status) { __ntapi->zw_terminate_process(hprocess, status); __ntapi->zw_close(hprocess); - return (intptr_t)(-1); + return status; } __attr_protected__ @@ -62,6 +62,9 @@ intptr_t __fastcall __tt_fork_impl_v1( nt_client_id cid; nt_large_integer timeout; + cid.process_id = 0; + cid.thread_id = 0; + hprocess = 0; hthread = 0; @@ -78,7 +81,7 @@ intptr_t __fastcall __tt_fork_impl_v1( &oa, NT_CURRENT_PROCESS_HANDLE, 1,0,0,0))) - return (intptr_t)(-1); + return status; if ((status = __ntapi->zw_query_information_process( hprocess, @@ -129,7 +132,6 @@ intptr_t __fastcall __tt_fork_impl_v1( 0, 0, &timeout))) return __tt_fork_cancel(hprocess,status); - if ((status = __ntapi->zw_create_thread( &hthread, NT_THREAD_ALL_ACCESS, @@ -141,21 +143,25 @@ intptr_t __fastcall __tt_fork_impl_v1( if (cid.process_id > 0) { __internals->hany[0] = hprocess; __internals->hany[1] = hthread; + __internals->hany[2] = (void *)cid.process_id; + __internals->hany[3] = (void *)cid.thread_id; } else { __internals->hany[0] = 0; __internals->hany[1] = 0; + __internals->hany[2] = 0; + __internals->hany[3] = 0; } /* hoppla */ - return (int32_t)cid.process_id; + return NT_STATUS_SUCCESS; } -intptr_t __fastcall __ntapi_tt_fork_v1( +int32_t __fastcall __ntapi_tt_fork_v1( __out void ** hprocess, - __out void ** hthread) + __out void ** hthread, + __out nt_cid * cid) { int32_t status; - intptr_t pid; nt_large_integer timeout; void ** hport_session; void * htty_connected; @@ -172,24 +178,32 @@ intptr_t __fastcall __ntapi_tt_fork_v1( &(nt_timeout){{0,0}}); if (hport_session && *hport_session) { - if (__ntapi_tt_create_inheritable_event( + status = __ntapi_tt_create_inheritable_event( &htty_connected, NT_NOTIFICATION_EVENT, - NT_EVENT_NOT_SIGNALED)) { + NT_EVENT_NOT_SIGNALED); + + if (status) { at_store(&__internals->hlock,0); - return (intptr_t)(-1); + return status; } } - pid = __tt_fork_v1(); + if ((status = __tt_fork_v1())) { + at_store(&__internals->hlock,0); + return status; + } *hprocess = __internals->hany[0]; *hthread = __internals->hany[1]; + cid->process_id = (uintptr_t)__internals->hany[2]; + cid->thread_id = (uintptr_t)__internals->hany[3]; + at_store(&__internals->hlock,0); if (hport_session && *hport_session) { - if (pid == 0) { + if (cid->process_id == 0) { if ((status = __ntapi->tty_connect( hport_session, __internals->subsystem->base_named_objects, @@ -205,7 +219,7 @@ intptr_t __fastcall __ntapi_tt_fork_v1( htty_connected, 0); - } else if (pid > 0) { + } else { status = __ntapi->zw_wait_for_single_object( htty_connected, NT_SYNC_NON_ALERTABLE, @@ -216,11 +230,11 @@ intptr_t __fastcall __ntapi_tt_fork_v1( htty_connected, NT_SYNC_NON_ALERTABLE, 0))) - pid = __tt_fork_cancel(*hprocess,status); + status = __tt_fork_cancel(*hprocess,status); } __ntapi->zw_close(htty_connected); } - return pid; + return status; } diff --git a/src/process/ntapi_tt_fork_v2.c b/src/process/ntapi_tt_fork_v2.c index 1927b9c..b7a2ad5 100644 --- a/src/process/ntapi_tt_fork_v2.c +++ b/src/process/ntapi_tt_fork_v2.c @@ -20,19 +20,19 @@ static intptr_t __tt_fork_cancel(void * hprocess,int32_t status) { __ntapi->zw_terminate_process(hprocess, status); __ntapi->zw_close(hprocess); - return (intptr_t)(-1); + return status; } static intptr_t __tt_fork_impl_v2( - __out void ** hprocess, - __out void ** hthread) + __out void ** hprocess, + __out void ** hthread, + __out nt_cid * cid) { int32_t status; void ** hport_session; nt_object_attributes oa_process; nt_object_attributes oa_thread; nt_create_process_info process_info; - nt_cid cid; nt_sec_img_inf sec_img_inf; nt_timeout timeout; ntapi_internals * __internals; @@ -58,6 +58,8 @@ static intptr_t __tt_fork_impl_v2( oa_thread.sec_desc = 0; oa_thread.sec_qos = 0; + cid->process_id = 0; + cid->thread_id = 0; __ntapi->tt_aligned_block_memset( &process_info,0,sizeof(process_info)); @@ -67,13 +69,12 @@ static intptr_t __tt_fork_impl_v2( process_info.init_state.init_flags = NT_PROCESS_CREATE_FLAGS_NO_OBJECT_SYNC; __ntapi->tt_aligned_block_memset(&ext_params,0,sizeof(ext_params)); - __ntapi->tt_aligned_block_memset(&cid,0,sizeof(cid)); __ntapi->tt_aligned_block_memset(&sec_img_inf,0,sizeof(sec_img_inf)); ext_params.size_in_bytes = sizeof(ext_params); ext_params.process_info.ext_param_type = NT_CREATE_PROCESS_EXT_PARAM_GET_CLIENT_ID; - ext_params.process_info.ext_param_size = sizeof(cid); - ext_params.process_info.ext_param_addr = &cid; + ext_params.process_info.ext_param_size = sizeof(*cid); + ext_params.process_info.ext_param_addr = cid; ext_params.section_info.ext_param_type = NT_CREATE_PROCESS_EXT_PARAM_GET_SECTION_IMAGE_INFO; ext_params.section_info.ext_param_size = sizeof(sec_img_inf); @@ -94,10 +95,16 @@ static intptr_t __tt_fork_impl_v2( &process_info, (nt_create_process_ext_params *)&ext_params); - if (status == NT_STATUS_PROCESS_CLONED) - return 0; - else if (status) - return (intptr_t)(-1); + switch (status) { + case NT_STATUS_PROCESS_CLONED: + return NT_STATUS_SUCCESS; + + case NT_STATUS_SUCCESS: + break; + + default: + return status; + } __internals = __ntapi_internals(); hport_session = &__internals->hport_tty_session; @@ -106,7 +113,7 @@ static intptr_t __tt_fork_impl_v2( if (hport_session && *hport_session) if ((status = __ntapi->tty_client_process_register( *hport_session, - cid.process_id, + cid->process_id, 0,0,&timeout))) return __tt_fork_cancel(*hprocess,status); @@ -116,15 +123,15 @@ static intptr_t __tt_fork_impl_v2( return __tt_fork_cancel(*hprocess,status); /* hoppla */ - return (int32_t)cid.process_id; + return NT_STATUS_SUCCESS; } -intptr_t __fastcall __ntapi_tt_fork_v2( +int32_t __fastcall __ntapi_tt_fork_v2( __out void ** hprocess, - __out void ** hthread) + __out void ** hthread, + __out nt_cid * cid) { int32_t status; - intptr_t pid; nt_large_integer timeout; void ** hport_session; void * htty_connected; @@ -136,20 +143,19 @@ intptr_t __fastcall __ntapi_tt_fork_v2( htty_connected = 0; if (hport_session && *hport_session) - if (__ntapi_tt_create_inheritable_event( + if ((status = __ntapi_tt_create_inheritable_event( &htty_connected, NT_NOTIFICATION_EVENT, - NT_EVENT_NOT_SIGNALED)) - return (intptr_t)(-1); + NT_EVENT_NOT_SIGNALED))) + return status; - pid = __tt_fork_impl_v2(hprocess,hthread); + if ((status = __tt_fork_impl_v2(hprocess,hthread,cid))) + return status; if (!hport_session || !*hport_session) - return pid; - else if (pid < 0) - return pid; + return NT_STATUS_SUCCESS; - if (pid == 0) { + if (cid->process_id == 0) { at_store(&__internals->hlock,0); if ((status = __ntapi->tty_connect( @@ -177,11 +183,11 @@ intptr_t __fastcall __ntapi_tt_fork_v2( htty_connected, NT_SYNC_NON_ALERTABLE, 0))) - pid = __tt_fork_cancel(*hprocess,status); + status = __tt_fork_cancel(*hprocess,status); } __ntapi->zw_close(htty_connected); - return pid; + return status; }