From dd89bb8ad4fe184a34b5dbdda237e640fc82121b Mon Sep 17 00:00:00 2001 From: midipix Date: Mon, 27 Jul 2015 04:01:18 -0400 Subject: entered advanced internal development stage. --- src/process/ntapi_tt_fork_v1.c | 218 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 src/process/ntapi_tt_fork_v1.c (limited to 'src/process/ntapi_tt_fork_v1.c') diff --git a/src/process/ntapi_tt_fork_v1.c b/src/process/ntapi_tt_fork_v1.c new file mode 100644 index 0000000..de917ef --- /dev/null +++ b/src/process/ntapi_tt_fork_v1.c @@ -0,0 +1,218 @@ +/********************************************************/ +/* ntapi: Native API core library */ +/* Copyright (C) 2013,2014,2015 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ +/********************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ntapi_impl.h" + +intptr_t __cdecl __attr_hidden__ __tt_fork_v1(void); +uint32_t __fastcall __attr_hidden__ __tt_fork_child_entry_point(uintptr_t saved_regs_stack_pointer); +uint32_t __fastcall __attr_hidden__ __tt_fork_child_entry_point_adj(uintptr_t saved_regs_stack_pointer); + +/** legacy fork chronology: + * + * parent: + * __ntapi_tt_fork -> + * __tt_fork -> + * __tt_fork_impl -> + * return to __tt_fork --> + * __ntapi_tt_fork + * -> return to caller + * + * child: + * __tt_fork_child_entry_point[_adj] -> + * __ntapi_tt_fork (internal return) -> + * -> return to caller +**/ + + +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); +} + +intptr_t __fastcall __tt_fork_impl_v1( + uintptr_t saved_regs_stack_pointer, + uintptr_t stack_adjustment) +{ + int32_t status; + void * hprocess; + void * hthread; + void ** hport_session; + ntapi_internals * __internals; + + nt_object_attributes oa; + nt_process_basic_information pbi; + nt_thread_context context; + nt_user_stack stack; + nt_memory_basic_information mbi; + nt_client_id cid; + nt_large_integer timeout; + + hprocess = hthread = (void *)0; + + oa.len = sizeof(nt_object_attributes); + oa.root_dir = 0; + oa.obj_name = 0; + oa.obj_attr = 0; + oa.sec_desc = 0; + oa.sec_qos = 0; + + if ((status = __ntapi->zw_create_process( + &hprocess, + NT_PROCESS_ALL_ACCESS, + &oa, + NT_CURRENT_PROCESS_HANDLE, + 1,0,0,0))) + return (intptr_t)(-1); + + if ((status = __ntapi->zw_query_information_process( + hprocess, + NT_PROCESS_BASIC_INFORMATION, + (void *)&pbi, + sizeof(nt_process_basic_information), + 0))) + return __tt_fork_cancel(hprocess,status); + + + + __ntapi->tt_aligned_block_memset( + &context,0,sizeof(nt_thread_context)); + + __INIT_CONTEXT(context); + context.STACK_POINTER_REGISTER = saved_regs_stack_pointer; + context.FAST_CALL_ARG0 = saved_regs_stack_pointer; + + context.INSTRUCTION_POINTER_REGISTER = stack_adjustment + ? (uintptr_t)__tt_fork_child_entry_point_adj + : (uintptr_t)__tt_fork_child_entry_point; + + + + if ((status = __ntapi->zw_query_virtual_memory( + NT_CURRENT_PROCESS_HANDLE, + (void *)context.STACK_POINTER_REGISTER, + NT_MEMORY_BASIC_INFORMATION, + &mbi,sizeof(nt_memory_basic_information),0))) + return __tt_fork_cancel(hprocess,status); + + stack.fixed_stack_base = (void *)0; + stack.fixed_stack_limit = (void *)0; + stack.expandable_stack_base = (void *)((uintptr_t)mbi.base_address + mbi.region_size); + stack.expandable_stack_limit = (void *)mbi.base_address; + stack.expandable_stack_bottom = (void *)mbi.allocation_base; + + + + __internals = __ntapi_internals(); + hport_session = &__internals->hport_tty_session; + timeout.quad = (-1) * 10 * 1000 * __NT_FORK_CHILD_WAIT_MILLISEC; + + if (hport_session && *hport_session) + if ((status = __ntapi->tty_client_process_register( + *hport_session, + pbi.unique_process_id, + 0, 0, &timeout))) + return __tt_fork_cancel(hprocess,status); + + + if ((status = __ntapi->zw_create_thread( + &hthread, + NT_THREAD_ALL_ACCESS, + &oa,hprocess,&cid, + &context,&stack,0))) + return __tt_fork_cancel(hprocess,status); + + + if (cid.process_id > 0) { + __internals->hany[0] = hprocess; + __internals->hany[1] = hthread; + } else { + __internals->hany[0] = 0; + __internals->hany[1] = 0; + } + + /* hoppla */ + return (int32_t)cid.process_id; +} + +intptr_t __fastcall __ntapi_tt_fork_v1( + __out void ** hprocess, + __out void ** hthread) +{ + int32_t status; + intptr_t pid; + nt_large_integer timeout; + void ** hport_session; + void * hevent_tty_connected; + ntapi_internals * __internals; + + __internals = __ntapi_internals(); + hport_session = &__internals->hport_tty_session; + timeout.quad = (-1) * 10 * 1000 * __NT_FORK_CHILD_WAIT_MILLISEC; + + if (at_locked_cas(&__internals->hlock,0,1)) + return (intptr_t)(-1); + + if (hport_session && *hport_session) + if (__ntapi_tt_create_inheritable_event( + &hevent_tty_connected, + NT_NOTIFICATION_EVENT, + NT_EVENT_NOT_SIGNALED)) + return (intptr_t)(-1); + + pid = __tt_fork_v1(); + + *hprocess = __internals->hany[0]; + *hthread = __internals->hany[1]; + + at_store(&__internals->hlock,0); + + if (hport_session && *hport_session) { + if (pid == 0) { + if ((status = __ntapi->tty_connect( + hport_session, + __internals->subsystem->base_named_objects, + NT_SECURITY_IMPERSONATION))) + return __tt_fork_cancel(NT_CURRENT_PROCESS_HANDLE,status); + + __internals->hdev_mount_point_mgr = 0; + + if (__internals->rtdata) + __internals->rtdata->hsession = *hport_session; + + __ntapi->zw_set_event( + hevent_tty_connected, + 0); + + } else if (pid > 0) { + status = __ntapi->zw_wait_for_single_object( + hevent_tty_connected, + NT_SYNC_NON_ALERTABLE, + &timeout); + + if (status && __PSX_DEBUG) + if ((status = __ntapi->zw_wait_for_single_object( + hevent_tty_connected, + NT_SYNC_NON_ALERTABLE, + 0))) + pid = __tt_fork_cancel(*hprocess,status); + } + + __ntapi->zw_close(hevent_tty_connected); + } + + return pid; +} -- cgit v1.2.3