summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2019-05-28 17:46:28 +0000
committermidipix <writeonce@midipix.org>2019-05-28 20:59:10 +0000
commit2a7f67d71f9d34c49de6a81e7deab10882bf930f (patch)
tree3249cacf442c3563f6b3c511f260dcc94b908f7b
parentd7c519f4b44e965eb57bb94f0fa60795450a523d (diff)
downloadntapi-2a7f67d71f9d34c49de6a81e7deab10882bf930f.tar.bz2
ntapi-2a7f67d71f9d34c49de6a81e7deab10882bf930f.tar.xz
debug helpers: __ntapi_tt_debug_break_process(): initial implementation.
-rw-r--r--include/ntapi/nt_debug.h5
-rw-r--r--include/ntapi/ntapi.h1
-rw-r--r--project/common.mk1
-rw-r--r--src/debug/ntapi_tt_debug_break_process.c126
-rw-r--r--src/internal/ntapi.c1
-rw-r--r--src/internal/ntapi_fnapi.h1
6 files changed, 135 insertions, 0 deletions
diff --git a/include/ntapi/nt_debug.h b/include/ntapi/nt_debug.h
index f555416..f5a1d40 100644
--- a/include/ntapi/nt_debug.h
+++ b/include/ntapi/nt_debug.h
@@ -350,4 +350,9 @@ typedef int32_t __stdcall ntapi_tt_debug_execution_flow(
__in uint32_t evtmask,
__in uint64_t * nevents);
+typedef int32_t __stdcall ntapi_tt_debug_break_process(
+ __in void * hprocess,
+ __out void ** hthread,
+ __out nt_cid * cid);
+
#endif
diff --git a/include/ntapi/ntapi.h b/include/ntapi/ntapi.h
index 493edb2..96b0974 100644
--- a/include/ntapi/ntapi.h
+++ b/include/ntapi/ntapi.h
@@ -670,6 +670,7 @@ typedef struct _ntapi_vtbl {
ntapi_tt_create_debug_object * tt_create_debug_object;
ntapi_tt_create_attach_debug_object * tt_create_attach_debug_object;
ntapi_tt_debug_execution_flow * tt_debug_execution_flow;
+ ntapi_tt_debug_break_process * tt_debug_break_process;
} ntapi_vtbl;
diff --git a/project/common.mk b/project/common.mk
index 5009148..508cc13 100644
--- a/project/common.mk
+++ b/project/common.mk
@@ -16,6 +16,7 @@ COMMON_SRCS = \
src/daemon/ntapi_dsr_init.c \
src/daemon/ntapi_dsr_internal_connection.c \
src/debug/ntapi_tt_create_debug_object.c \
+ src/debug/ntapi_tt_debug_break_process.c \
src/debug/ntapi_tt_debug_execution_flow.c \
src/fs/ntapi_tt_get_file_handle_type.c \
src/fs/ntapi_tt_istat.c \
diff --git a/src/debug/ntapi_tt_debug_break_process.c b/src/debug/ntapi_tt_debug_break_process.c
new file mode 100644
index 0000000..3ad0daf
--- /dev/null
+++ b/src/debug/ntapi_tt_debug_break_process.c
@@ -0,0 +1,126 @@
+/********************************************************/
+/* ntapi: Native API core library */
+/* Copyright (C) 2013--2019 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.NTAPI. */
+/********************************************************/
+
+#include <psxtypes/psxtypes.h>
+#include <ntapi/nt_object.h>
+#include <ntapi/nt_debug.h>
+#include "ntapi_impl.h"
+
+static int32_t __tt_debug_break_process_fail(void * hthread, int32_t status)
+{
+ __ntapi->zw_terminate_thread(
+ hthread,status);
+
+ return status;
+}
+
+struct __dbg_hoppla {
+ void * caller;
+ void * cx;
+ intptr_t dx;
+ intptr_t r9;
+ intptr_t r8;
+};
+
+int32_t __stdcall __ntapi_tt_debug_break_process(
+ __in void * hprocess,
+ __out void ** hthread,
+ __out nt_cid * cid)
+{
+ int32_t status;
+ nt_thread_params tparams;
+ nt_thread_context context;
+ nt_user_stack spinfo;
+ struct __dbg_hoppla hoppla;
+ uintptr_t sptop;
+ uintptr_t spreg;
+ int32_t (*dbg_break_point)(void *);
+
+ /* interrupt & return */
+ dbg_break_point = pe_get_procedure_address(
+ pe_get_ntdll_module_handle(),
+ "DbgBreakPoint");
+
+ /* thread params */
+ __ntapi->tt_aligned_block_memset(
+ &tparams,0,
+ sizeof(tparams));
+
+ __ntapi->tt_aligned_block_memset(
+ &spinfo,0,
+ sizeof(spinfo));
+
+ tparams.start = dbg_break_point;
+ tparams.hprocess = hprocess;
+ tparams.stack_size_commit = 0x1000;
+ tparams.stack_size_reserve = 0x1000;
+ tparams.stack_info = &spinfo;
+ tparams.creation_flags = NT_CREATE_SUSPENDED;
+
+ if ((status = __ntapi->tt_create_thread(&tparams)))
+ return status;
+
+ /* context */
+ __ntapi->tt_aligned_block_memset(
+ &context,0,
+ sizeof(context));
+
+ context.uc_context_flags = NT_CONTEXT_JUST_EVERYTHING;
+
+ if ((status = __ntapi->zw_get_context_thread(
+ tparams.hthread,
+ &context)))
+ return __tt_debug_break_process_fail(
+ tparams.hthread,
+ status);
+
+ /* return address:=) */
+ hoppla.caller = __ntapi->zw_terminate_thread;
+ hoppla.cx = NT_CURRENT_THREAD_HANDLE;
+ hoppla.dx = NT_STATUS_BREAKPOINT;
+ hoppla.r8 = 0;
+ hoppla.r9 = 0;
+
+ sptop = (uintptr_t)tparams.stack_info->expandable_stack_base;
+ spreg = context.STACK_POINTER_REGISTER;
+
+ if (sptop - spreg < sizeof(hoppla))
+ spreg -= sizeof(hoppla);
+
+ if ((status = __ntapi->zw_write_virtual_memory(
+ hprocess,
+ (void *)spreg,
+ (char *)&hoppla,
+ sizeof(hoppla),0)))
+ return __tt_debug_break_process_fail(
+ tparams.hthread,
+ status);
+
+ /* (fast call args not needed on x86) */
+ context.STACK_POINTER_REGISTER = spreg;
+ context.FAST_CALL_ARG0 = (uintptr_t)hoppla.cx;
+ context.FAST_CALL_ARG1 = hoppla.dx;
+
+ if ((status = __ntapi->zw_set_context_thread(
+ tparams.hthread,
+ &context)))
+ return __tt_debug_break_process_fail(
+ tparams.hthread,
+ status);
+
+ /* at last... */
+ if ((status = __ntapi->zw_resume_thread(tparams.hthread,0)))
+ return __tt_debug_break_process_fail(
+ tparams.hthread,
+ status);
+
+ /* yay */
+ *hthread = tparams.hthread;
+ cid->thread_id = tparams.cid.thread_id;
+ cid->process_id = tparams.cid.process_id;
+
+ return NT_STATUS_SUCCESS;
+}
diff --git a/src/internal/ntapi.c b/src/internal/ntapi.c
index 5122305..eff7eb1 100644
--- a/src/internal/ntapi.c
+++ b/src/internal/ntapi.c
@@ -447,6 +447,7 @@ static int32_t __fastcall __ntapi_init_once(ntapi_vtbl ** pvtbl)
__ntapi->tt_create_debug_object = __ntapi_tt_create_debug_object;
__ntapi->tt_create_attach_debug_object = __ntapi_tt_create_attach_debug_object;
__ntapi->tt_debug_execution_flow = __ntapi_tt_debug_execution_flow;
+ __ntapi->tt_debug_break_process = __ntapi_tt_debug_break_process;
/* OS version dependent functions */
diff --git a/src/internal/ntapi_fnapi.h b/src/internal/ntapi_fnapi.h
index 6c20fbf..2f79a57 100644
--- a/src/internal/ntapi_fnapi.h
+++ b/src/internal/ntapi_fnapi.h
@@ -338,6 +338,7 @@ NTAPI_UFN(log_msg);
NTAPI_UFN(tt_create_debug_object);
NTAPI_UFN(tt_create_attach_debug_object);
NTAPI_UFN(tt_debug_execution_flow);
+NTAPI_UFN(tt_debug_break_process);
/* csrss */
NTAPI_VFN(tt_get_csr_port_handle_addr_by_logic,i386);