diff --git a/src/thread/ntapi_tt_create_thread.c b/src/thread/ntapi_tt_create_thread.c index 9d2d829..50b23d9 100644 --- a/src/thread/ntapi_tt_create_thread.c +++ b/src/thread/ntapi_tt_create_thread.c @@ -20,7 +20,7 @@ #define __GRANULARITY 0x010000 #define __RESERVE_ROUND_UP 0x100000 -static int32_t __stdcall __create_thread_fail( +static int32_t __create_thread_fail( void * hprocess, void * stack_bottom, size_t stack_size, @@ -34,8 +34,7 @@ static int32_t __stdcall __create_thread_fail( return status; } -int32_t __stdcall __ntapi_tt_create_thread( - __in_out nt_thread_params * params) +int32_t __stdcall __ntapi_tt_create_thread(nt_thread_params * params) { int32_t status; ntapi_internals * __internals; @@ -45,6 +44,7 @@ int32_t __stdcall __ntapi_tt_create_thread( nt_port_message_csrss_process * csrss_msg_1st; nt_port_message_csrss_thread * csrss_msg_any; + char * base; void * stack_system_limit; uint32_t protect_type_old; @@ -96,65 +96,59 @@ int32_t __stdcall __ntapi_tt_create_thread( **/ /* stack structure: unused fields */ - stack.fixed_stack_base = (void *)0; - stack.fixed_stack_limit = (void *)0; + stack.fixed_stack_base = 0; + stack.fixed_stack_limit = 0; /* first we reserve */ - stack.expandable_stack_bottom = (void *)0; - status = __ntapi->zw_allocate_virtual_memory( - params->hprocess, - &stack.expandable_stack_bottom, - params->stack_zero_bits, - ¶ms->stack_size_reserve, - NT_MEM_RESERVE, - NT_PAGE_READWRITE); + stack.expandable_stack_bottom = 0; - if (status) return status; + if ((status = __ntapi->zw_allocate_virtual_memory( + params->hprocess, + &stack.expandable_stack_bottom, + params->stack_zero_bits, + ¶ms->stack_size_reserve, + NT_MEM_RESERVE, + NT_PAGE_READWRITE))) + return status; /* calculate base and limit */ - stack.expandable_stack_base = - (void *)((intptr_t)stack.expandable_stack_bottom - + params->stack_size_reserve); + base = stack.expandable_stack_bottom; + base += params->stack_size_reserve; - stack.expandable_stack_limit = - (void *)((intptr_t)stack.expandable_stack_base - - params->stack_size_commit); + stack.expandable_stack_base = base; + stack.expandable_stack_limit = base - params->stack_size_commit; /* guard page */ - commit = params->stack_size_commit + __PAGE_SIZE; - stack_system_limit = - (void *)((intptr_t)stack.expandable_stack_base - - commit); + commit = params->stack_size_commit + __PAGE_SIZE; + stack_system_limit = base - commit; /* then we commit */ - status = __ntapi->zw_allocate_virtual_memory( - params->hprocess, - &stack_system_limit, - 0, - &commit, - NT_MEM_COMMIT, - NT_PAGE_READWRITE); - - if (status) return __create_thread_fail( - params->hprocess, - stack.expandable_stack_bottom, - params->stack_size_reserve, - status); + if ((status = __ntapi->zw_allocate_virtual_memory( + params->hprocess, + &stack_system_limit, + 0,&commit, + NT_MEM_COMMIT, + NT_PAGE_READWRITE))) + return __create_thread_fail( + params->hprocess, + stack.expandable_stack_bottom, + params->stack_size_reserve, + status); /* finally we protect the guard page */ size = __PAGE_SIZE; - status = __ntapi->zw_protect_virtual_memory( - params->hprocess, - &stack_system_limit, - &size, - NT_PAGE_READWRITE | NT_MEM_PAGE_GUARD, - &protect_type_old); - - if (status) return __create_thread_fail( - params->hprocess, - stack.expandable_stack_bottom, - params->stack_size_reserve, - status); + + if ((status = __ntapi->zw_protect_virtual_memory( + params->hprocess, + &stack_system_limit, + &size, + NT_PAGE_READWRITE | NT_MEM_PAGE_GUARD, + &protect_type_old))) + return __create_thread_fail( + params->hprocess, + stack.expandable_stack_bottom, + params->stack_size_reserve, + status); /* context */ if (params->reg_context) { @@ -168,8 +162,7 @@ int32_t __stdcall __ntapi_tt_create_thread( __INIT_CONTEXT(context); context.INSTRUCTION_POINTER_REGISTER = (uintptr_t)params->start; - context.STACK_POINTER_REGISTER = (uintptr_t)(stack.expandable_stack_base) - - sizeof(intptr_t); + context.STACK_POINTER_REGISTER = (uintptr_t)(base) - sizeof(intptr_t); } @@ -260,26 +253,22 @@ int32_t __stdcall __ntapi_tt_create_thread( /* create thread */ - if ((!__ntapi->zw_create_user_process) | (params->creation_flags & NT_CREATE_SUSPENDED)) - fsuspended = 1; - else - fsuspended = 0; - - status = __ntapi->zw_create_thread( - ¶ms->hthread, - NT_THREAD_ALL_ACCESS, - params->obj_attr, - params->hprocess, - &cid, - &context, - &stack, - fsuspended); - - if (status) return __create_thread_fail( - params->hprocess, - stack.expandable_stack_bottom, - params->stack_size_reserve, - status); + fsuspended = (params->creation_flags & NT_CREATE_SUSPENDED) + ? 1 : __ntapi->zw_create_user_process + ? 0 : 1; + + if ((status = __ntapi->zw_create_thread( + ¶ms->hthread, + NT_THREAD_ALL_ACCESS, + params->obj_attr, + params->hprocess, + &cid,&context,&stack, + fsuspended))) + return __create_thread_fail( + params->hprocess, + stack.expandable_stack_bottom, + params->stack_size_reserve, + status); /* for os versions prior to hasta la */ if (!__ntapi->zw_create_user_process) { @@ -330,26 +319,27 @@ int32_t __stdcall __ntapi_tt_create_thread( /* and finally */ params->thread_id = (uint32_t)cid.thread_id; + return NT_STATUS_SUCCESS; } -int32_t __stdcall __ntapi_tt_create_local_thread( - __in_out nt_thread_params * params) +int32_t __stdcall __ntapi_tt_create_local_thread(nt_thread_params * params) { + nt_status status; + void * hprocess; void * image_base; struct pe_stack_heap_info stack_heap_info; nt_client_id cid; nt_object_attributes oa; - nt_status status; /* oa init */ oa.len = sizeof(oa); - oa.root_dir = (void *)0; - oa.obj_name = (nt_unicode_string *)0; + oa.root_dir = 0; + oa.obj_name = 0; oa.obj_attr = 0; - oa.sec_desc = (nt_sd *)0; - oa.sec_qos = (nt_sqos *)0; + oa.sec_desc = 0; + oa.sec_qos = 0; /* init cid */ cid.process_id = pe_get_current_process_id(); @@ -357,27 +347,30 @@ int32_t __stdcall __ntapi_tt_create_local_thread( /* obtain a handle to our own process */ /* TODO: use cached handle, no close */ - status = __ntapi->zw_open_process( - ¶ms->hprocess, - NT_PROCESS_ALL_ACCESS, - &oa, - &cid); + if (params->hprocess) + hprocess = 0; - if (status) return status; + else if ((status = __ntapi->zw_open_process( + &hprocess, + NT_PROCESS_ALL_ACCESS, + &oa,&cid))) + return status; /* retrieve the stack defaults as needed */ - if (!(params->stack_size_commit && params->stack_size_reserve) && !(params->stack_info)) { - /* image_base*/ - image_base = pe_get_first_module_handle(); + if (params->stack_info) + (void)0; - if (!(intptr_t)image_base) - return NT_STATUS_INVALID_IMPORT_OF_NON_DLL; + else if (params->stack_size_commit && params->stack_size_reserve) + (void)0; - status = pe_get_image_stack_heap_info( - image_base, - &stack_heap_info); + else { + /* image_base*/ + if (!(image_base = pe_get_first_module_handle())) + return NT_STATUS_INVALID_IMPORT_OF_NON_DLL; - if (status) + if ((status = pe_get_image_stack_heap_info( + image_base, + &stack_heap_info))) return NT_STATUS_INVALID_IMAGE_FORMAT; /* stack_size_commit */ @@ -393,16 +386,22 @@ int32_t __stdcall __ntapi_tt_create_local_thread( } params->creation_flags |= NT_CREATE_LOCAL_THREAD; - status = __ntapi_tt_create_thread(params); + + if (hprocess) { + params->hprocess = hprocess; + + status = __ntapi_tt_create_thread(params); + __ntapi->zw_close(hprocess); + + return status; + } /* TODO: use cached handle, no close */ - __ntapi->zw_close(params->hprocess); - return status; + return __ntapi_tt_create_thread(params); } -int32_t __stdcall __ntapi_tt_create_remote_thread( - __in_out nt_thread_params * params) +int32_t __stdcall __ntapi_tt_create_remote_thread(nt_thread_params * params) { return __ntapi_tt_create_thread(params); } @@ -410,17 +409,17 @@ int32_t __stdcall __ntapi_tt_create_remote_thread( void * __cdecl __ntapi_csr_port_handle(nt_status * pstatus) { - ntapi_internals * __internals; + nt_status status; + ntapi_internals * __internals; + pstatus = pstatus ? pstatus : &status; __internals = __ntapi_internals(); if (__internals->csr_port_handle_addr) { - if (pstatus) - *pstatus = NT_STATUS_SUCCESS; + *pstatus = NT_STATUS_SUCCESS; return *__internals->csr_port_handle_addr; } else { - if (pstatus) - *pstatus = NT_STATUS_UNSUCCESSFUL; - return (void *)0; + *pstatus = NT_STATUS_UNSUCCESSFUL; + return 0; } }