/********************************************************/
/* ntapi: Native API core library */
/* Copyright (C) 2013--2021 SysDeer Technologies, LLC */
/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
/********************************************************/
#include <psxtypes/psxtypes.h>
#include <ntapi/nt_object.h>
#include <ntapi/nt_debug.h>
#include <ntapi/nt_guid.h>
#include <ntapi/nt_acl.h>
#include <ntapi/nt_tty.h>
#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;
}