/********************************************************/ /* ntapi: Native API core library */ /* Copyright (C) 2013--2021 SysDeer Technologies, LLC */ /* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */ /********************************************************/ #include #include #include #include #include #include #include "ntapi_impl.h" static int32_t __log_exception_to_server( nt_dbg_wait_state_change * dbgstate, void * hserver) { int32_t status; nt_tty_log_msg msg; if (!hserver) return NT_STATUS_SUCCESS; __ntapi->tt_aligned_block_memset( &msg,0,sizeof(msg)); msg.header.msg_type = NT_LPC_NEW_MESSAGE; msg.header.data_size = sizeof(msg.data); msg.header.msg_size = sizeof(msg); msg.data.ttyinfo.opcode = NT_TTY_LOG_ENTRY; msg.data.loginfo.type = NT_TTY_LOG_INFO_EXCEPTION_RECORD; msg.data.loginfo.meta = dbgstate->_u.exception_info.exception_priority; msg.data.loginfo.cid.process_id = dbgstate->cid.process_id; msg.data.loginfo.cid.thread_id = dbgstate->cid.thread_id; __ntapi->tt_generic_memcpy( &msg.data.loginfo.data, &dbgstate->_u.exception_info.exception_record, sizeof(nt_exception_record)); if ((status = __ntapi->zw_request_wait_reply_port(hserver,&msg,&msg))) return status; else if (msg.data.ttyinfo.status) return msg.data.ttyinfo.status; return NT_STATUS_SUCCESS; } int32_t __stdcall __ntapi_tt_debug_execution_flow( __in void * hdbgobj, __in void * hprocess, __in void * hserver, __in void * hlogfile, __in uint32_t evtmask, __in uint64_t * nevents) { int32_t status; int32_t response; int floop; uint64_t nevts; uint64_t necap; nt_dbg_wait_state_change dbgstate; (void)hlogfile; necap = (nevents && *nevents) ? *nevents : (uint64_t)(-1); for (nevts=0, floop=1; floop && (nevts < necap); nevts++) { if ((status = __ntapi->zw_wait_for_debug_event( hdbgobj, NT_SYNC_NON_ALERTABLE, 0,&dbgstate))) return status; switch (dbgstate.state) { case NT_DBG_STATE_EXCEPTION: if (evtmask & NT_DBG_FLOW_MASK_EXCEPTION) { __log_exception_to_server(&dbgstate,hserver); } response = NT_DBG_EXCEPTION_NOT_HANDLED; break; case NT_DBG_STATE_EXIT_PROCESS: response = NT_DBG_CONTINUE; floop = 0; break; default: response = NT_DBG_CONTINUE; break; } switch (dbgstate.state) { case NT_DBG_STATE_CREATE_THREAD: __ntapi->zw_close(dbgstate._u.thread_info.hthread); break; case NT_DBG_STATE_CREATE_PROCESS: __ntapi->zw_close(dbgstate._u.process_info.hprocess); __ntapi->zw_close(dbgstate._u.process_info.hthread); __ntapi->zw_close(dbgstate._u.process_info.image_handle); break; case NT_DBG_STATE_DLL_LOAD: __ntapi->zw_close(dbgstate._u.load_module.image_handle); break; default: break; } __ntapi->zw_debug_continue( hdbgobj, &dbgstate.cid, response); } if (evtmask & NT_DBG_FLOW_MASK_DETACH_AND_CLOSE) { __ntapi->zw_remove_process_debug( hprocess,hdbgobj); __ntapi->zw_close( hdbgobj); } return NT_STATUS_SUCCESS; }