Add support for Windows on ARM (#1502)
* Support building for Windows on ARM * Fix usage of reserved function name on ARM * Fix architecture dependent `CONTEXT` fields access * Fixes for debugging on Windows on ARM * Fix breakpoint behavior on windows on ARM * Fix register profile when debugging * Remove `drx` error message if not supported * Add support for hardware breakpoints * Disable support for hardware single-stepping * Fix Windows Message breakpoints on ARM * Fix software single-stepping on return instruction on ARM * Consider link register as destination for return instructions * Fix setting debug bits to 16 * Rename `r12` to `ip` for windows arm register profile * Remove debug bits hardcoding on windows * Add 32bit registers to Windows ARM64 register profile * Fix software step breakpoint alignment when entering thumb mode * Define `RZ_TEST_ARCH` for `arm` and `arm64` * Use `StackWalk64` API for backtracing on Windows * Fix software single-stepping ARM in thumb mode * Sync `asm.bits` with debugger * Cleanup windows_debug.c * Add SPDX for cross-arm64-windows.txt * Add floating point control register flags * Fix Windows Arm register profile alignment * Keep `drx` warning
This commit is contained in:
parent
73fa2b30a5
commit
53a7694631
21 changed files with 816 additions and 283 deletions
|
|
@ -22,6 +22,10 @@
|
|||
#define RZ_TEST_ARCH "x86"
|
||||
#elif __x86_64__
|
||||
#define RZ_TEST_ARCH "x64"
|
||||
#elif __arm__
|
||||
#define RZ_TEST_ARCH "arm"
|
||||
#elif __arm64__
|
||||
#define RZ_TEST_ARCH "arm64"
|
||||
#else
|
||||
#define RZ_TEST_ARCH "unknown"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -696,14 +696,6 @@ static bool cb_asmbits(void *user, void *data) {
|
|||
bool load_from_debug = rz_config_get_b(core->config, "cfg.debug");
|
||||
if (load_from_debug) {
|
||||
if (core->dbg->cur && core->dbg->cur->reg_profile) {
|
||||
// XXX. that should depend on the plugin, not the host os
|
||||
#if __WINDOWS__
|
||||
#if !defined(_WIN64)
|
||||
core->dbg->bits = RZ_SYS_BITS_32;
|
||||
#else
|
||||
core->dbg->bits = RZ_SYS_BITS_64;
|
||||
#endif
|
||||
#endif
|
||||
char *rp = core->dbg->cur->reg_profile(core->dbg);
|
||||
rz_reg_set_profile_string(core->dbg->reg, rp);
|
||||
rz_reg_set_profile_string(core->analysis->reg, rp);
|
||||
|
|
@ -3383,7 +3375,11 @@ RZ_API int rz_core_config_init(RzCore *core) {
|
|||
|
||||
SETCB("dbg.bpinmaps", "true", &cb_dbg_bpinmaps, "Activate breakpoints only if they are inside a valid map");
|
||||
SETCB("dbg.forks", "false", &cb_dbg_forks, "Stop execution if fork() is done (see dbg.threads)");
|
||||
#if __WINDOWS__
|
||||
n = NODECB("dbg.btalgo", "default", &cb_dbg_btalgo);
|
||||
#else
|
||||
n = NODECB("dbg.btalgo", "fuzzy", &cb_dbg_btalgo);
|
||||
#endif
|
||||
SETDESC(n, "Select backtrace algorithm");
|
||||
SETOPTIONS(n, "default", "fuzzy", "analysis", "trace", NULL);
|
||||
SETCB("dbg.threads", "false", &cb_stopthreads, "Stop all threads when debugger breaks (see dbg.forks)");
|
||||
|
|
|
|||
|
|
@ -585,6 +585,25 @@ RZ_API void rz_core_debug_ri(RzCore *core, RzReg *reg, int mode) {
|
|||
ht_up_free(db);
|
||||
}
|
||||
|
||||
RZ_IPI void rz_core_debug_sync_bits(RzCore *core) {
|
||||
if (rz_config_get_b(core->config, "cfg.debug")) {
|
||||
switch (core->dbg->bits) {
|
||||
case RZ_SYS_BITS_8:
|
||||
rz_config_set_i(core->config, "asm.bits", 8);
|
||||
break;
|
||||
case RZ_SYS_BITS_16:
|
||||
rz_config_set_i(core->config, "asm.bits", 16);
|
||||
break;
|
||||
case RZ_SYS_BITS_32:
|
||||
rz_config_set_i(core->config, "asm.bits", 32);
|
||||
break;
|
||||
case RZ_SYS_BITS_64:
|
||||
rz_config_set_i(core->config, "asm.bits", 64);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RZ_IPI void rz_core_debug_single_step_in(RzCore *core) {
|
||||
if (rz_config_get_b(core->config, "cfg.debug")) {
|
||||
if (core->print->cur_enabled) {
|
||||
|
|
|
|||
|
|
@ -703,6 +703,7 @@ RZ_IPI void rz_core_dbg_follow_seek_register(RzCore *core) {
|
|||
if ((pc < core->offset) || (pc > (core->offset + follow))) {
|
||||
rz_core_seek_to_register(core, "PC", false);
|
||||
}
|
||||
rz_core_debug_sync_bits(core);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ RZ_IPI bool rz_core_debug_reg_set(RzCore *core, const char *regname, ut64 val, c
|
|||
RZ_IPI bool rz_core_debug_reg_list(RzCore *core, int type, int size, bool skip_covered, PJ *pj, int rad, const char *use_color);
|
||||
RZ_IPI void rz_core_debug_regs2flags(RzCore *core);
|
||||
RZ_IPI void rz_core_regs2flags(RzCore *core);
|
||||
RZ_IPI void rz_core_debug_sync_bits(RzCore *core);
|
||||
RZ_IPI void rz_core_debug_single_step_in(RzCore *core);
|
||||
RZ_IPI void rz_core_debug_single_step_over(RzCore *core);
|
||||
RZ_IPI void rz_core_debug_breakpoint_toggle(RzCore *core, ut64 addr);
|
||||
|
|
|
|||
|
|
@ -3363,6 +3363,7 @@ RZ_API void rz_core_visual_title(RzCore *core, int color) {
|
|||
} else if (follow < 0) {
|
||||
rz_core_seek(core, curpc + follow, true);
|
||||
}
|
||||
rz_core_debug_sync_bits(core);
|
||||
oldpc = curpc;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -461,6 +461,11 @@ RZ_API int rz_debug_stop(RzDebug *dbg) {
|
|||
RZ_API bool rz_debug_set_arch(RzDebug *dbg, const char *arch, int bits) {
|
||||
if (arch && dbg && dbg->cur) {
|
||||
switch (bits) {
|
||||
case 16:
|
||||
if (dbg->cur->bits & RZ_SYS_BITS_16) {
|
||||
dbg->bits = RZ_SYS_BITS_16;
|
||||
}
|
||||
break;
|
||||
case 27:
|
||||
if (dbg->cur->bits == 27) {
|
||||
dbg->bits = 27;
|
||||
|
|
@ -798,6 +803,9 @@ RZ_API int rz_debug_step_soft(RzDebug *dbg) {
|
|||
return false;
|
||||
}
|
||||
|
||||
const bool has_lr_reg = rz_reg_get_name(dbg->reg, RZ_REG_NAME_LR);
|
||||
const bool arch_ret_is_pop = !strcmp(dbg->arch, "arm") && dbg->bits <= RZ_SYS_BITS_32;
|
||||
|
||||
pc = rz_debug_reg_get(dbg, dbg->reg->name[RZ_REG_NAME_PC]);
|
||||
sp = rz_debug_reg_get(dbg, dbg->reg->name[RZ_REG_NAME_SP]);
|
||||
|
||||
|
|
@ -815,8 +823,15 @@ RZ_API int rz_debug_step_soft(RzDebug *dbg) {
|
|||
}
|
||||
switch (op.type) {
|
||||
case RZ_ANALYSIS_OP_TYPE_RET:
|
||||
dbg->iob.read_at(dbg->iob.io, sp, (ut8 *)&sp_top, 8);
|
||||
next[0] = (dbg->bits == RZ_SYS_BITS_32) ? sp_top.r32[0] : sp_top.r64;
|
||||
if (arch_ret_is_pop && op.stackop == RZ_ANALYSIS_STACK_INC) {
|
||||
dbg->iob.read_at(dbg->iob.io, sp - op.stackptr - 4, (ut8 *)&sp_top, 4);
|
||||
next[0] = sp_top.r32[0];
|
||||
} else if (has_lr_reg) {
|
||||
next[0] = rz_debug_reg_get(dbg, dbg->reg->name[RZ_REG_NAME_LR]);
|
||||
} else {
|
||||
dbg->iob.read_at(dbg->iob.io, sp, (ut8 *)&sp_top, 8);
|
||||
next[0] = (dbg->bits <= RZ_SYS_BITS_32) ? sp_top.r32[0] : sp_top.r64;
|
||||
}
|
||||
br = 1;
|
||||
break;
|
||||
case RZ_ANALYSIS_OP_TYPE_CJMP:
|
||||
|
|
@ -842,7 +857,7 @@ RZ_API int rz_debug_step_soft(RzDebug *dbg) {
|
|||
if (!dbg->iob.read_at(dbg->iob.io, r, (ut8 *)&memval, 8)) {
|
||||
next[0] = op.addr + op.size;
|
||||
} else {
|
||||
next[0] = (dbg->bits == RZ_SYS_BITS_32) ? memval.r32[0] : memval.r64;
|
||||
next[0] = (dbg->bits <= RZ_SYS_BITS_32) ? memval.r32[0] : memval.r64;
|
||||
}
|
||||
br = 1;
|
||||
break;
|
||||
|
|
@ -857,7 +872,7 @@ RZ_API int rz_debug_step_soft(RzDebug *dbg) {
|
|||
if (!dbg->iob.read_at(dbg->iob.io, r * op.scale + op.disp, (ut8 *)&memval, 8)) {
|
||||
next[0] = op.addr + op.size;
|
||||
} else {
|
||||
next[0] = (dbg->bits == RZ_SYS_BITS_32) ? memval.r32[0] : memval.r64;
|
||||
next[0] = (dbg->bits <= RZ_SYS_BITS_32) ? memval.r32[0] : memval.r64;
|
||||
}
|
||||
br = 1;
|
||||
break;
|
||||
|
|
@ -867,7 +882,11 @@ RZ_API int rz_debug_step_soft(RzDebug *dbg) {
|
|||
break;
|
||||
}
|
||||
|
||||
const int align = rz_analysis_archinfo(dbg->analysis, RZ_ANALYSIS_ARCHINFO_ALIGN);
|
||||
for (i = 0; i < br; i++) {
|
||||
if (align > 1) {
|
||||
next[i] = next[i] - (next[i] % align);
|
||||
}
|
||||
RzBreakpointItem *bpi = rz_bp_add_sw(dbg->bp, next[i], dbg->bpsize, RZ_BP_PROT_EXEC);
|
||||
if (bpi) {
|
||||
bpi->swstep = true;
|
||||
|
|
|
|||
|
|
@ -129,9 +129,10 @@ static int rz_debug_native_step(RzDebug *dbg) {
|
|||
return false;
|
||||
}
|
||||
return true;
|
||||
#else // linux
|
||||
#elif __linux__
|
||||
return linux_step(dbg);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
// return thread id
|
||||
|
|
@ -1305,7 +1306,7 @@ static int rz_debug_native_drx(RzDebug *dbg, int n, ut64 addr, int sz, int rwx,
|
|||
#else
|
||||
eprintf("drx: Unsupported platform\n");
|
||||
#endif
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if __linux__
|
||||
|
|
@ -1434,6 +1435,10 @@ static int rz_debug_native_bp(RzBreakpoint *bp, RzBreakpointItem *b, bool set) {
|
|||
return set
|
||||
? arm64_hwbp_add(dbg, bp, b)
|
||||
: arm64_hwbp_del(dbg, bp, b);
|
||||
#elif __WINDOWS__
|
||||
return set
|
||||
? w32_hwbp_arm_add(dbg, bp, b)
|
||||
: w32_hwbp_arm_del(dbg, bp, b);
|
||||
#elif __arm__ && __linux__
|
||||
return set
|
||||
? arm32_hwbp_add(dbg, bp, b)
|
||||
|
|
@ -1602,7 +1607,11 @@ RzDebugPlugin rz_debug_plugin_native = {
|
|||
#elif __aarch64__ || __arm64__
|
||||
.bits = RZ_SYS_BITS_16 | RZ_SYS_BITS_32 | RZ_SYS_BITS_64,
|
||||
.arch = "arm",
|
||||
#if __WINDOWS__
|
||||
.canstep = 0,
|
||||
#else
|
||||
.canstep = 1,
|
||||
#endif
|
||||
#elif __arm__
|
||||
.bits = RZ_SYS_BITS_16 | RZ_SYS_BITS_32 | RZ_SYS_BITS_64,
|
||||
.arch = "arm",
|
||||
|
|
@ -1656,7 +1665,9 @@ RzDebugPlugin rz_debug_plugin_native = {
|
|||
.modules_get = rz_debug_native_modules_get,
|
||||
.map_protect = rz_debug_native_map_protect,
|
||||
.breakpoint = rz_debug_native_bp,
|
||||
#if __i386__ || __x86_64__
|
||||
.drx = rz_debug_native_drx,
|
||||
#endif
|
||||
.gcore = rz_debug_gcore,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ typedef struct { // Keep in sync with io_windbg.c
|
|||
PDEBUG_ADVANCED3 dbgAdvanced;
|
||||
} DbgEngContext;
|
||||
|
||||
static bool __is_target_kernel(DbgEngContext *idbg) {
|
||||
static bool is_target_kernel(DbgEngContext *idbg) {
|
||||
ULONG Class, Qualifier;
|
||||
if (SUCCEEDED(ITHISCALL(dbgCtrl, GetDebuggeeType, &Class, &Qualifier))) {
|
||||
if (Class == DEBUG_CLASS_KERNEL) {
|
||||
|
|
@ -81,7 +81,7 @@ static int windbg_select(RzDebug *dbg, int pid, int tid) {
|
|||
rz_return_val_if_fail(idbg && idbg->initialized, 0);
|
||||
ULONG process_id = pid;
|
||||
ULONG thread_id = tid;
|
||||
if (!__is_target_kernel(idbg)) {
|
||||
if (!is_target_kernel(idbg)) {
|
||||
ITHISCALL(dbgSysObj, GetProcessIdBySystemId, pid, &process_id);
|
||||
ITHISCALL(dbgSysObj, GetThreadIdBySystemId, tid, &thread_id);
|
||||
}
|
||||
|
|
@ -136,10 +136,10 @@ static int windbg_stop(RzDebug *dbg) {
|
|||
|
||||
static bool do_break = false;
|
||||
|
||||
static void __break(void *user) {
|
||||
static void break_debugger(void *user) {
|
||||
RzDebug *dbg = (RzDebug *)user;
|
||||
DbgEngContext *idbg = dbg->plugin_data;
|
||||
if (__is_target_kernel(idbg)) {
|
||||
if (is_target_kernel(idbg)) {
|
||||
windbg_stop(dbg);
|
||||
}
|
||||
do_break = true;
|
||||
|
|
@ -149,8 +149,8 @@ static int windbg_wait(RzDebug *dbg, int pid) {
|
|||
DbgEngContext *idbg = dbg->plugin_data;
|
||||
rz_return_val_if_fail(idbg && idbg->initialized, 0);
|
||||
ULONG Type, ProcessId, ThreadId;
|
||||
rz_cons_break_push(__break, dbg);
|
||||
const ULONG timeout = __is_target_kernel(idbg) ? INFINITE : TIMEOUT;
|
||||
rz_cons_break_push(break_debugger, dbg);
|
||||
const ULONG timeout = is_target_kernel(idbg) ? INFINITE : TIMEOUT;
|
||||
HRESULT hr;
|
||||
while ((hr = ITHISCALL(dbgCtrl, WaitForEvent, DEBUG_WAIT_DEFAULT, timeout)) == S_FALSE) {
|
||||
if (do_break) {
|
||||
|
|
@ -165,7 +165,7 @@ static int windbg_wait(RzDebug *dbg, int pid) {
|
|||
return RZ_DEBUG_REASON_DEAD;
|
||||
}
|
||||
ITHISCALL(dbgCtrl, GetLastEventInformation, &Type, &ProcessId, &ThreadId, NULL, 0, NULL, NULL, 0, NULL);
|
||||
if (!__is_target_kernel(idbg)) {
|
||||
if (!is_target_kernel(idbg)) {
|
||||
ITHISCALL(dbgSysObj, GetCurrentProcessSystemId, (PULONG)&dbg->pid);
|
||||
ITHISCALL(dbgSysObj, GetCurrentThreadSystemId, (PULONG)&dbg->tid);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
#include <rz_analysis.h>
|
||||
|
||||
#if __WINDOWS__
|
||||
#include "bt/windows-all.c"
|
||||
#endif
|
||||
#include "bt/generic-x86.c"
|
||||
#include "bt/generic-x64.c"
|
||||
#include "bt/fuzzy-all.c"
|
||||
|
|
@ -46,19 +49,28 @@ static RzList *rz_debug_native_frames(RzDebug *dbg, ut64 at) {
|
|||
if (!strcmp(dbg->btalgo, "fuzzy")) {
|
||||
cb = backtrace_fuzzy;
|
||||
} else if (!strcmp(dbg->btalgo, "analysis")) {
|
||||
if (dbg->bits == RZ_SYS_BITS_64) {
|
||||
cb = backtrace_x86_64_analysis;
|
||||
if (!strcmp(dbg->arch, "x86")) {
|
||||
if (dbg->bits == RZ_SYS_BITS_64) {
|
||||
cb = backtrace_x86_64_analysis;
|
||||
} else {
|
||||
cb = backtrace_x86_32_analysis;
|
||||
}
|
||||
} else {
|
||||
cb = backtrace_x86_32_analysis;
|
||||
eprintf("Analysis backtrace not available for current architecture (%s)\n", dbg->arch);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!cb) {
|
||||
#if __WINDOWS__
|
||||
cb = backtrace_windows;
|
||||
#else
|
||||
if (dbg->bits == RZ_SYS_BITS_64) {
|
||||
cb = backtrace_x86_64;
|
||||
} else {
|
||||
cb = backtrace_x86_32;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
RzList *list;
|
||||
|
|
|
|||
120
librz/debug/p/native/bt/windows-all.c
Normal file
120
librz/debug/p/native/bt/windows-all.c
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
// SPDX-FileCopyrightText: 2021 GustavoLCR <gugulcr@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <DbgHelp.h>
|
||||
#include <w32dbg_wrap.h>
|
||||
|
||||
#define DEF_PROC(proc) proc##_t *w32_##proc
|
||||
#define GET_PROC(proc) \
|
||||
w32_##proc = (proc##_t *)GetProcAddress(dbghelp, #proc); \
|
||||
if (!w32_##proc) { \
|
||||
return false; \
|
||||
}
|
||||
|
||||
typedef BOOL __stdcall SymInitialize_t(
|
||||
_In_ HANDLE hProcess,
|
||||
_In_opt_ PCSTR UserSearchPath,
|
||||
_In_ BOOL fInvadeProcess);
|
||||
|
||||
typedef BOOL __stdcall SymCleanup_t(
|
||||
_In_ HANDLE hProcess);
|
||||
|
||||
typedef PVOID __stdcall SymFunctionTableAccess64_t(
|
||||
_In_ HANDLE hProcess,
|
||||
_In_ DWORD64 AddrBase);
|
||||
|
||||
typedef DWORD64 __stdcall SymGetModuleBase64_t(
|
||||
_In_ HANDLE hProcess,
|
||||
_In_ DWORD64 qwAddr);
|
||||
|
||||
typedef BOOL __stdcall StackWalk64_t(
|
||||
_In_ DWORD MachineType,
|
||||
_In_ HANDLE hProcess,
|
||||
_In_ HANDLE hThread,
|
||||
_Inout_ LPSTACKFRAME64 StackFrame,
|
||||
_Inout_ PVOID ContextRecord,
|
||||
_In_opt_ PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
|
||||
_In_opt_ PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
|
||||
_In_opt_ PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
|
||||
_In_opt_ PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress);
|
||||
|
||||
DEF_PROC(SymInitialize);
|
||||
DEF_PROC(SymCleanup);
|
||||
DEF_PROC(SymFunctionTableAccess64);
|
||||
DEF_PROC(SymGetModuleBase64);
|
||||
DEF_PROC(StackWalk64);
|
||||
|
||||
static inline bool initialize_sym_api(void) {
|
||||
static bool initialized = false;
|
||||
if (initialized) {
|
||||
return true;
|
||||
}
|
||||
HMODULE dbghelp = LoadLibrary(TEXT("DbgHelp"));
|
||||
if (!dbghelp) {
|
||||
return false;
|
||||
}
|
||||
GET_PROC(SymInitialize);
|
||||
GET_PROC(SymCleanup);
|
||||
GET_PROC(SymFunctionTableAccess64);
|
||||
GET_PROC(SymGetModuleBase64);
|
||||
GET_PROC(StackWalk64);
|
||||
initialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static RzList *backtrace_windows(RzDebug *dbg, ut64 at) {
|
||||
initialize_sym_api();
|
||||
static RzThreadLock *lock = NULL;
|
||||
if (!lock) {
|
||||
lock = rz_th_lock_new(false);
|
||||
if (!lock) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
W32DbgWInst *wrap = dbg->plugin_data;
|
||||
#if __arm64__
|
||||
DWORD machine_type = IMAGE_FILE_MACHINE_ARM64;
|
||||
#elif __arm__
|
||||
DWORD machine_type = IMAGE_FILE_MACHINE_ARMNT;
|
||||
#elif __x86_64__
|
||||
DWORD machine_type = IMAGE_FILE_MACHINE_AMD64;
|
||||
#else
|
||||
DWORD machine_type = IMAGE_FILE_MACHINE_I386;
|
||||
#endif
|
||||
STACKFRAME64 stack = { 0 };
|
||||
stack.AddrFrame.Mode = AddrModeFlat;
|
||||
stack.AddrFrame.Offset = rz_reg_getv(dbg->reg, rz_reg_get_name(dbg->reg, RZ_REG_NAME_BP));
|
||||
stack.AddrStack.Mode = AddrModeFlat;
|
||||
stack.AddrStack.Offset = rz_reg_getv(dbg->reg, rz_reg_get_name(dbg->reg, RZ_REG_NAME_SP));
|
||||
stack.AddrPC.Mode = AddrModeFlat;
|
||||
stack.AddrPC.Offset = rz_reg_getv(dbg->reg, rz_reg_get_name(dbg->reg, RZ_REG_NAME_PC));
|
||||
|
||||
RzList *list = rz_list_newf(free);
|
||||
if (!list) {
|
||||
return NULL;
|
||||
}
|
||||
CONTEXT *ctx = (CONTEXT *)rz_reg_arena_peek(dbg->reg);
|
||||
rz_th_lock_enter(lock);
|
||||
w32_SymInitialize(wrap->pi.hProcess, NULL, TRUE);
|
||||
while (w32_StackWalk64(machine_type, wrap->pi.hProcess, wrap->pi.hThread, &stack, ctx, NULL, w32_SymFunctionTableAccess64, w32_SymGetModuleBase64, NULL)) {
|
||||
RzDebugFrame *frame = RZ_NEW0(RzDebugFrame);
|
||||
if (!frame) {
|
||||
break;
|
||||
}
|
||||
frame->addr = stack.AddrPC.Offset;
|
||||
frame->bp = stack.AddrFrame.Offset;
|
||||
frame->sp = stack.AddrStack.Offset;
|
||||
frame->size = frame->bp - frame->sp;
|
||||
if (!rz_list_append(list, frame)) {
|
||||
free(frame);
|
||||
break;
|
||||
}
|
||||
}
|
||||
w32_SymCleanup(wrap->pi.hProcess);
|
||||
rz_th_lock_leave(lock);
|
||||
free(ctx);
|
||||
return list;
|
||||
}
|
||||
|
||||
#undef DEF_PROC
|
||||
#undef GET_PROC
|
||||
|
|
@ -6,6 +6,7 @@ return strdup(
|
|||
"=PC pc\n"
|
||||
"=BP x29\n"
|
||||
"=SP sp\n"
|
||||
"=LR x30\n"
|
||||
"=SN x8\n"
|
||||
"=A0 x0\n"
|
||||
"=A1 x1\n"
|
||||
|
|
|
|||
|
|
@ -6,17 +6,21 @@
|
|||
|
||||
static char *rz_debug_native_reg_profile(RzDebug *dbg) {
|
||||
#if __WINDOWS__
|
||||
/*_______
|
||||
/*_______
|
||||
| | |
|
||||
|___|___|
|
||||
| | |
|
||||
|___|___|
|
||||
*/
|
||||
if (dbg->bits & RZ_SYS_BITS_64) {
|
||||
#if defined(__arm64__)
|
||||
#include "reg/windows-arm64.h"
|
||||
#elif defined(__arm__)
|
||||
#include "reg/windows-arm.h"
|
||||
#elif defined(__x86_64__)
|
||||
#include "reg/windows-x64.h"
|
||||
} else {
|
||||
#elif defined(__i386__)
|
||||
#include "reg/windows-x86.h"
|
||||
}
|
||||
#endif
|
||||
#elif (__OpenBSD__ || __NetBSD__)
|
||||
/* __.--..__
|
||||
\-/-/-/ _ __ _.--' _.--'
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ return strdup(
|
|||
"=PC pc\n"
|
||||
"=SP sp\n"
|
||||
"=BP fp\n"
|
||||
"=LR lr\n"
|
||||
"=A0 r0\n"
|
||||
"=A1 r1\n"
|
||||
"=A2 r2\n"
|
||||
|
|
@ -25,7 +26,7 @@ return strdup(
|
|||
"gpr r9 .32 40 0\n"
|
||||
"gpr r10 .32 44 0\n"
|
||||
"gpr r11 .32 48 0\n"
|
||||
"gpr r12 .32 52 0\n"
|
||||
"gpr ip .32 52 0\n"
|
||||
"gpr sp .32 56 0\n"
|
||||
"gpr lr .32 60 0\n"
|
||||
"gpr pc .32 64 0\n"
|
||||
|
|
@ -34,40 +35,44 @@ return strdup(
|
|||
"flg cf .1 68.29 0 carry\n"
|
||||
"flg zf .1 68.30 0 zero\n"
|
||||
"flg nf .1 68.31 0 sign\n"
|
||||
"gpr fpsr .32 72 0\n"
|
||||
"fpu q0 .128 76 0\n"
|
||||
"fpu q1 .128 92 0\n"
|
||||
"fpu q2 .128 108 0\n"
|
||||
"fpu q3 .128 124 0\n"
|
||||
"fpu q4 .128 140 0\n"
|
||||
"fpu q5 .128 156 0\n"
|
||||
"fpu q6 .128 172 0\n"
|
||||
"fpu q7 .128 188 0\n"
|
||||
"fpu q8 .128 204 0\n"
|
||||
"fpu q9 .128 220 0\n"
|
||||
"fpu q10 .128 236 0\n"
|
||||
"fpu q11 .128 252 0\n"
|
||||
"fpu q12 .128 268 0\n"
|
||||
"fpu q13 .128 284 0\n"
|
||||
"fpu q14 .128 300 0\n"
|
||||
"fpu q15 .128 316 0\n"
|
||||
"drx bcr0 .32 332 0\n"
|
||||
"drx bcr1 .32 336 0\n"
|
||||
"drx bcr2 .32 340 0\n"
|
||||
"drx bcr3 .32 344 0\n"
|
||||
"drx bcr4 .32 348 0\n"
|
||||
"drx bcr5 .32 352 0\n"
|
||||
"drx bcr6 .32 356 0\n"
|
||||
"drx bcr7 .32 360 0\n"
|
||||
"drx bvr0 .32 364 0\n"
|
||||
"drx bvr1 .32 368 0\n"
|
||||
"drx bvr2 .32 372 0\n"
|
||||
"drx bvr3 .32 376 0\n"
|
||||
"drx bvr4 .32 380 0\n"
|
||||
"drx bvr5 .32 384 0\n"
|
||||
"drx bvr6 .32 388 0\n"
|
||||
"drx bvr7 .32 392 0\n"
|
||||
"drx wcr0 .32 396 0\n"
|
||||
"drx wcr1 .32 400 0\n"
|
||||
"drx wvr0 .32 404 0\n"
|
||||
"drx wvr1 .32 408 0\n");
|
||||
"flg fpscr .32 72 0\n"
|
||||
"flg fvf .1 72.28 0 overflow\n"
|
||||
"flg fcf .1 72.29 0 carry\n"
|
||||
"flg fzf .1 72.30 0 zero\n"
|
||||
"flg fnf .1 72.31 0 sign\n"
|
||||
"fpu q0 .128 80 0\n"
|
||||
"fpu q1 .128 96 0\n"
|
||||
"fpu q2 .128 112 0\n"
|
||||
"fpu q3 .128 128 0\n"
|
||||
"fpu q4 .128 144 0\n"
|
||||
"fpu q5 .128 160 0\n"
|
||||
"fpu q6 .128 176 0\n"
|
||||
"fpu q7 .128 192 0\n"
|
||||
"fpu q8 .128 208 0\n"
|
||||
"fpu q9 .128 224 0\n"
|
||||
"fpu q10 .128 240 0\n"
|
||||
"fpu q11 .128 256 0\n"
|
||||
"fpu q12 .128 272 0\n"
|
||||
"fpu q13 .128 288 0\n"
|
||||
"fpu q14 .128 304 0\n"
|
||||
"fpu q15 .128 320 0\n"
|
||||
"drx bcr0 .32 336 0\n"
|
||||
"drx bcr1 .32 340 0\n"
|
||||
"drx bcr2 .32 344 0\n"
|
||||
"drx bcr3 .32 348 0\n"
|
||||
"drx bcr4 .32 352 0\n"
|
||||
"drx bcr5 .32 356 0\n"
|
||||
"drx bcr6 .32 360 0\n"
|
||||
"drx bcr7 .32 364 0\n"
|
||||
"drx bvr0 .32 368 0\n"
|
||||
"drx bvr1 .32 372 0\n"
|
||||
"drx bvr2 .32 376 0\n"
|
||||
"drx bvr3 .32 380 0\n"
|
||||
"drx bvr4 .32 384 0\n"
|
||||
"drx bvr5 .32 388 0\n"
|
||||
"drx bvr6 .32 392 0\n"
|
||||
"drx bvr7 .32 396 0\n"
|
||||
"drx wcr0 .32 400 0\n"
|
||||
"drx wcr1 .32 404 0\n"
|
||||
"drx wvr0 .32 408 0\n"
|
||||
"drx wvr1 .32 412 0\n");
|
||||
|
|
|
|||
|
|
@ -1,108 +1,233 @@
|
|||
// SPDX-FileCopyrightText: 2020 GustavoLCR <gugulcr@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
return strdup(
|
||||
"=PC pc\n"
|
||||
"=SP sp\n"
|
||||
"=BP fp\n"
|
||||
"=A0 x0\n"
|
||||
"=A1 x1\n"
|
||||
"=A2 x2\n"
|
||||
"=A3 x3\n"
|
||||
"=ZF zf\n"
|
||||
"=SF nf\n"
|
||||
"=OF vf\n"
|
||||
"=CF cf\n"
|
||||
"=SN x16\n"
|
||||
"flg cpsr .32 4 0 _____tfiae_____________j__qvczn\n"
|
||||
"flg vf .1 4.28 0 overflow\n"
|
||||
"flg cf .1 4.29 0 carry\n"
|
||||
"flg zf .1 4.30 0 zero\n"
|
||||
"flg nf .1 4.31 0 sign\n"
|
||||
"gpr x0 .64 8 0\n"
|
||||
"gpr x1 .64 16 0\n"
|
||||
"gpr x2 .64 24 0\n"
|
||||
"gpr x3 .64 32 0\n"
|
||||
"gpr x4 .64 40 0\n"
|
||||
"gpr x5 .64 48 0\n"
|
||||
"gpr x6 .64 56 0\n"
|
||||
"gpr x7 .64 64 0\n"
|
||||
"gpr x8 .64 72 0\n"
|
||||
"gpr x9 .64 80 0\n"
|
||||
"gpr x10 .64 88 0\n"
|
||||
"gpr x11 .64 96 0\n"
|
||||
"gpr x12 .64 104 0\n"
|
||||
"gpr x13 .64 112 0\n"
|
||||
"gpr x14 .64 120 0\n"
|
||||
"gpr x15 .64 128 0\n"
|
||||
"gpr x16 .64 136 0\n"
|
||||
"gpr x17 .64 144 0\n"
|
||||
"gpr x18 .64 152 0\n"
|
||||
"gpr x19 .64 160 0\n"
|
||||
"gpr x20 .64 168 0\n"
|
||||
"gpr x21 .64 176 0\n"
|
||||
"gpr x22 .64 184 0\n"
|
||||
"gpr x23 .64 192 0\n"
|
||||
"gpr x24 .64 200 0\n"
|
||||
"gpr x25 .64 208 0\n"
|
||||
"gpr x26 .64 216 0\n"
|
||||
"gpr x27 .64 224 0\n"
|
||||
"gpr x28 .64 232 0\n"
|
||||
"gpr fp .64 240 0\n"
|
||||
"gpr lr .64 248 0\n"
|
||||
"gpr sp .64 256 0\n"
|
||||
"gpr pc .64 264 0\n"
|
||||
"fpu v0 .128 272 0\n"
|
||||
"fpu v1 .128 288 0\n"
|
||||
"fpu v2 .128 304 0\n"
|
||||
"fpu v3 .128 320 0\n"
|
||||
"fpu v4 .128 336 0\n"
|
||||
"fpu v5 .128 352 0\n"
|
||||
"fpu v6 .128 368 0\n"
|
||||
"fpu v7 .128 384 0\n"
|
||||
"fpu v8 .128 400 0\n"
|
||||
"fpu v9 .128 416 0\n"
|
||||
"fpu v10 .128 432 0\n"
|
||||
"fpu v11 .128 448 0\n"
|
||||
"fpu v12 .128 464 0\n"
|
||||
"fpu v13 .128 480 0\n"
|
||||
"fpu v14 .128 496 0\n"
|
||||
"fpu v15 .128 512 0\n"
|
||||
"fpu v16 .128 528 0\n"
|
||||
"fpu v17 .128 544 0\n"
|
||||
"fpu v18 .128 560 0\n"
|
||||
"fpu v19 .128 576 0\n"
|
||||
"fpu v20 .128 592 0\n"
|
||||
"fpu v21 .128 608 0\n"
|
||||
"fpu v22 .128 624 0\n"
|
||||
"fpu v23 .128 640 0\n"
|
||||
"fpu v24 .128 656 0\n"
|
||||
"fpu v25 .128 672 0\n"
|
||||
"fpu v26 .128 688 0\n"
|
||||
"fpu v27 .128 704 0\n"
|
||||
"fpu v28 .128 720 0\n"
|
||||
"fpu v29 .128 736 0\n"
|
||||
"fpu v30 .128 752 0\n"
|
||||
"fpu v31 .128 768 0\n"
|
||||
"gpr fpcr .32 784 0\n"
|
||||
"gpr fpsr .32 788 0\n"
|
||||
"drx bcr0 .32 792 0\n"
|
||||
"drx bcr1 .32 796 0\n"
|
||||
"drx bcr2 .32 800 0\n"
|
||||
"drx bcr3 .32 804 0\n"
|
||||
"drx bcr4 .32 808 0\n"
|
||||
"drx bcr5 .32 812 0\n"
|
||||
"drx bcr6 .32 816 0\n"
|
||||
"drx bcr7 .32 820 0\n"
|
||||
"drx bvr0 .64 824 0\n"
|
||||
"drx bvr1 .64 832 0\n"
|
||||
"drx bvr2 .64 840 0\n"
|
||||
"drx bvr3 .64 848 0\n"
|
||||
"drx bvr4 .64 856 0\n"
|
||||
"drx bvr5 .64 864 0\n"
|
||||
"drx bvr6 .64 872 0\n"
|
||||
"drx bvr7 .64 880 0\n"
|
||||
"drx wcr0 .32 888 0\n"
|
||||
"drx wcr1 .32 892 0\n"
|
||||
"drx wvr0 .64 896 0\n"
|
||||
"drx wvr1 .64 904 0\n");
|
||||
if (dbg->bits == RZ_SYS_BITS_64) {
|
||||
return strdup(
|
||||
"=PC pc\n"
|
||||
"=SP sp\n"
|
||||
"=BP fp\n"
|
||||
"=LR lr\n"
|
||||
"=A0 x0\n"
|
||||
"=A1 x1\n"
|
||||
"=A2 x2\n"
|
||||
"=A3 x3\n"
|
||||
"=ZF zf\n"
|
||||
"=SF nf\n"
|
||||
"=OF vf\n"
|
||||
"=CF cf\n"
|
||||
"=SN x16\n"
|
||||
"flg cpsr .32 4 0 _____tfiae_____________j__qvczn\n"
|
||||
"flg vf .1 4.28 0 overflow\n"
|
||||
"flg cf .1 4.29 0 carry\n"
|
||||
"flg zf .1 4.30 0 zero\n"
|
||||
"flg nf .1 4.31 0 sign\n"
|
||||
"gpr x0 .64 8 0\n"
|
||||
"gpr x1 .64 16 0\n"
|
||||
"gpr x2 .64 24 0\n"
|
||||
"gpr x3 .64 32 0\n"
|
||||
"gpr x4 .64 40 0\n"
|
||||
"gpr x5 .64 48 0\n"
|
||||
"gpr x6 .64 56 0\n"
|
||||
"gpr x7 .64 64 0\n"
|
||||
"gpr x8 .64 72 0\n"
|
||||
"gpr x9 .64 80 0\n"
|
||||
"gpr x10 .64 88 0\n"
|
||||
"gpr x11 .64 96 0\n"
|
||||
"gpr x12 .64 104 0\n"
|
||||
"gpr x13 .64 112 0\n"
|
||||
"gpr x14 .64 120 0\n"
|
||||
"gpr x15 .64 128 0\n"
|
||||
"gpr x16 .64 136 0\n"
|
||||
"gpr x17 .64 144 0\n"
|
||||
"gpr x18 .64 152 0\n"
|
||||
"gpr x19 .64 160 0\n"
|
||||
"gpr x20 .64 168 0\n"
|
||||
"gpr x21 .64 176 0\n"
|
||||
"gpr x22 .64 184 0\n"
|
||||
"gpr x23 .64 192 0\n"
|
||||
"gpr x24 .64 200 0\n"
|
||||
"gpr x25 .64 208 0\n"
|
||||
"gpr x26 .64 216 0\n"
|
||||
"gpr x27 .64 224 0\n"
|
||||
"gpr x28 .64 232 0\n"
|
||||
"gpr w0 .32 8 0\n"
|
||||
"gpr w1 .32 16 0\n"
|
||||
"gpr w2 .32 24 0\n"
|
||||
"gpr w3 .32 32 0\n"
|
||||
"gpr w4 .32 40 0\n"
|
||||
"gpr w5 .32 48 0\n"
|
||||
"gpr w6 .32 56 0\n"
|
||||
"gpr w7 .32 64 0\n"
|
||||
"gpr w8 .32 72 0\n"
|
||||
"gpr w9 .32 80 0\n"
|
||||
"gpr w10 .32 88 0\n"
|
||||
"gpr w11 .32 96 0\n"
|
||||
"gpr w12 .32 104 0\n"
|
||||
"gpr w13 .32 112 0\n"
|
||||
"gpr w14 .32 120 0\n"
|
||||
"gpr w15 .32 128 0\n"
|
||||
"gpr w16 .32 136 0\n"
|
||||
"gpr w17 .32 144 0\n"
|
||||
"gpr w18 .32 152 0\n"
|
||||
"gpr w19 .32 160 0\n"
|
||||
"gpr w20 .32 168 0\n"
|
||||
"gpr w21 .32 176 0\n"
|
||||
"gpr w22 .32 184 0\n"
|
||||
"gpr w23 .32 192 0\n"
|
||||
"gpr w24 .32 200 0\n"
|
||||
"gpr w25 .32 208 0\n"
|
||||
"gpr w26 .32 216 0\n"
|
||||
"gpr w27 .32 224 0\n"
|
||||
"gpr w28 .32 232 0\n"
|
||||
"gpr fp .64 240 0\n"
|
||||
"gpr lr .64 248 0\n"
|
||||
"gpr sp .64 256 0\n"
|
||||
"gpr pc .64 264 0\n"
|
||||
"fpu v0 .128 272 0\n"
|
||||
"fpu v1 .128 288 0\n"
|
||||
"fpu v2 .128 304 0\n"
|
||||
"fpu v3 .128 320 0\n"
|
||||
"fpu v4 .128 336 0\n"
|
||||
"fpu v5 .128 352 0\n"
|
||||
"fpu v6 .128 368 0\n"
|
||||
"fpu v7 .128 384 0\n"
|
||||
"fpu v8 .128 400 0\n"
|
||||
"fpu v9 .128 416 0\n"
|
||||
"fpu v10 .128 432 0\n"
|
||||
"fpu v11 .128 448 0\n"
|
||||
"fpu v12 .128 464 0\n"
|
||||
"fpu v13 .128 480 0\n"
|
||||
"fpu v14 .128 496 0\n"
|
||||
"fpu v15 .128 512 0\n"
|
||||
"fpu v16 .128 528 0\n"
|
||||
"fpu v17 .128 544 0\n"
|
||||
"fpu v18 .128 560 0\n"
|
||||
"fpu v19 .128 576 0\n"
|
||||
"fpu v20 .128 592 0\n"
|
||||
"fpu v21 .128 608 0\n"
|
||||
"fpu v22 .128 624 0\n"
|
||||
"fpu v23 .128 640 0\n"
|
||||
"fpu v24 .128 656 0\n"
|
||||
"fpu v25 .128 672 0\n"
|
||||
"fpu v26 .128 688 0\n"
|
||||
"fpu v27 .128 704 0\n"
|
||||
"fpu v28 .128 720 0\n"
|
||||
"fpu v29 .128 736 0\n"
|
||||
"fpu v30 .128 752 0\n"
|
||||
"fpu v31 .128 768 0\n"
|
||||
"flg fpcr .32 784 0\n"
|
||||
"flg fpsr .32 788 0\n"
|
||||
"flg fvf .1 788.28 0 overflow\n"
|
||||
"flg fcf .1 788.29 0 carry\n"
|
||||
"flg fzf .1 788.30 0 zero\n"
|
||||
"flg fnf .1 788.31 0 sign\n"
|
||||
"drx bcr0 .32 792 0\n"
|
||||
"drx bcr1 .32 796 0\n"
|
||||
"drx bcr2 .32 800 0\n"
|
||||
"drx bcr3 .32 804 0\n"
|
||||
"drx bcr4 .32 808 0\n"
|
||||
"drx bcr5 .32 812 0\n"
|
||||
"drx bcr6 .32 816 0\n"
|
||||
"drx bcr7 .32 820 0\n"
|
||||
"drx bvr0 .64 824 0\n"
|
||||
"drx bvr1 .64 832 0\n"
|
||||
"drx bvr2 .64 840 0\n"
|
||||
"drx bvr3 .64 848 0\n"
|
||||
"drx bvr4 .64 856 0\n"
|
||||
"drx bvr5 .64 864 0\n"
|
||||
"drx bvr6 .64 872 0\n"
|
||||
"drx bvr7 .64 880 0\n"
|
||||
"drx wcr0 .32 888 0\n"
|
||||
"drx wcr1 .32 892 0\n"
|
||||
"drx wvr0 .64 896 0\n"
|
||||
"drx wvr1 .64 904 0\n");
|
||||
} else {
|
||||
return strdup(
|
||||
"=PC pc\n"
|
||||
"=SP sp\n"
|
||||
"=BP fp\n"
|
||||
"=LR lr\n"
|
||||
"=A0 r0\n"
|
||||
"=A1 r1\n"
|
||||
"=A2 r2\n"
|
||||
"=A3 r3\n"
|
||||
"=ZF zf\n"
|
||||
"=SF nf\n"
|
||||
"=OF vf\n"
|
||||
"=CF cf\n"
|
||||
"flg cpsr .32 4 0 _____tfiae_____________j__qvczn\n"
|
||||
"flg vf .1 4.28 0 overflow\n"
|
||||
"flg cf .1 4.29 0 carry\n"
|
||||
"flg zf .1 4.30 0 zero\n"
|
||||
"flg nf .1 4.31 0 sign\n"
|
||||
"gpr r0 .32 8 0\n"
|
||||
"gpr r1 .32 16 0\n"
|
||||
"gpr r2 .32 24 0\n"
|
||||
"gpr r3 .32 32 0\n"
|
||||
"gpr r4 .32 40 0\n"
|
||||
"gpr r5 .32 48 0\n"
|
||||
"gpr r6 .32 56 0\n"
|
||||
"gpr r7 .32 64 0\n"
|
||||
"gpr r8 .32 72 0\n"
|
||||
"gpr r9 .32 80 0\n"
|
||||
"gpr r10 .32 88 0\n"
|
||||
"gpr fp .32 96 0\n"
|
||||
"gpr ip .32 104 0\n"
|
||||
"gpr sp .32 112 0\n"
|
||||
"gpr lr .32 120 0\n"
|
||||
"gpr pc .64 264 0\n"
|
||||
"fpu v0 .128 272 0\n"
|
||||
"fpu v1 .128 288 0\n"
|
||||
"fpu v2 .128 304 0\n"
|
||||
"fpu v3 .128 320 0\n"
|
||||
"fpu v4 .128 336 0\n"
|
||||
"fpu v5 .128 352 0\n"
|
||||
"fpu v6 .128 368 0\n"
|
||||
"fpu v7 .128 384 0\n"
|
||||
"fpu v8 .128 400 0\n"
|
||||
"fpu v9 .128 416 0\n"
|
||||
"fpu v10 .128 432 0\n"
|
||||
"fpu v11 .128 448 0\n"
|
||||
"fpu v12 .128 464 0\n"
|
||||
"fpu v13 .128 480 0\n"
|
||||
"fpu v14 .128 496 0\n"
|
||||
"fpu v15 .128 512 0\n"
|
||||
"fpu v16 .128 528 0\n"
|
||||
"fpu v17 .128 544 0\n"
|
||||
"fpu v18 .128 560 0\n"
|
||||
"fpu v19 .128 576 0\n"
|
||||
"fpu v20 .128 592 0\n"
|
||||
"fpu v21 .128 608 0\n"
|
||||
"fpu v22 .128 624 0\n"
|
||||
"fpu v23 .128 640 0\n"
|
||||
"fpu v24 .128 656 0\n"
|
||||
"fpu v25 .128 672 0\n"
|
||||
"fpu v26 .128 688 0\n"
|
||||
"fpu v27 .128 704 0\n"
|
||||
"fpu v28 .128 720 0\n"
|
||||
"fpu v29 .128 736 0\n"
|
||||
"fpu v30 .128 752 0\n"
|
||||
"fpu v31 .128 768 0\n"
|
||||
"gpr fpcr .32 784 0\n"
|
||||
"gpr fpsr .32 788 0\n"
|
||||
"drx bcr0 .32 792 0\n"
|
||||
"drx bcr1 .32 796 0\n"
|
||||
"drx bcr2 .32 800 0\n"
|
||||
"drx bcr3 .32 804 0\n"
|
||||
"drx bcr4 .32 808 0\n"
|
||||
"drx bcr5 .32 812 0\n"
|
||||
"drx bcr6 .32 816 0\n"
|
||||
"drx bcr7 .32 820 0\n"
|
||||
"drx bvr0 .64 824 0\n"
|
||||
"drx bvr1 .64 832 0\n"
|
||||
"drx bvr2 .64 840 0\n"
|
||||
"drx bvr3 .64 848 0\n"
|
||||
"drx bvr4 .64 856 0\n"
|
||||
"drx bvr5 .64 864 0\n"
|
||||
"drx bvr6 .64 872 0\n"
|
||||
"drx bvr7 .64 880 0\n"
|
||||
"drx wcr0 .32 888 0\n"
|
||||
"drx wcr1 .32 892 0\n"
|
||||
"drx wvr0 .64 896 0\n"
|
||||
"drx wvr1 .64 904 0\n");
|
||||
}
|
||||
|
|
@ -183,38 +183,26 @@ static PTHREAD_ITEM add_thread(RzDebug *dbg, DWORD pid, DWORD tid, HANDLE hThrea
|
|||
return pthread;
|
||||
}
|
||||
|
||||
static int suspend_thread(HANDLE th, int bits) {
|
||||
static inline int suspend_thread(HANDLE th) {
|
||||
int ret;
|
||||
//if (bits == RZ_SYS_BITS_32) {
|
||||
if ((ret = SuspendThread(th)) == -1) {
|
||||
rz_sys_perror("SuspendThread");
|
||||
}
|
||||
/*} else {
|
||||
if ((ret = Wow64SuspendThread (th)) == -1) {
|
||||
rz_sys_perror ("Wow64SuspendThread");
|
||||
}
|
||||
}*/
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int resume_thread(HANDLE th, int bits) {
|
||||
static int resume_thread(HANDLE th) {
|
||||
int ret;
|
||||
//if (bits == RZ_SYS_BITS_32) {
|
||||
if ((ret = ResumeThread(th)) == -1) {
|
||||
rz_sys_perror("ResumeThread");
|
||||
}
|
||||
/*} else {
|
||||
if ((ret = ResumeThread (th)) == -1) {
|
||||
rz_sys_perror ("Wow64ResumeThread");
|
||||
}
|
||||
}*/
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void continue_thread(HANDLE th, int bits) {
|
||||
static inline void continue_thread(HANDLE th) {
|
||||
int ret;
|
||||
do {
|
||||
ret = resume_thread(th, bits);
|
||||
ret = resume_thread(th);
|
||||
} while (ret > 0);
|
||||
}
|
||||
|
||||
|
|
@ -244,7 +232,7 @@ static bool is_process_alive(HANDLE ph) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static int set_thread_context(HANDLE th, const ut8 *buf, int size, int bits) {
|
||||
static int set_thread_context(HANDLE th, const ut8 *buf, int size) {
|
||||
bool ret;
|
||||
CONTEXT ctx = { 0 };
|
||||
size = RZ_MIN(size, sizeof(ctx));
|
||||
|
|
@ -255,11 +243,11 @@ static int set_thread_context(HANDLE th, const ut8 *buf, int size, int bits) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int get_thread_context(HANDLE th, ut8 *buf, int size, int bits) {
|
||||
static int get_thread_context(HANDLE th, ut8 *buf, int size, DWORD context_flags) {
|
||||
int ret = 0;
|
||||
CONTEXT ctx = { 0 };
|
||||
// TODO: support various types?
|
||||
ctx.ContextFlags = CONTEXT_ALL;
|
||||
ctx.ContextFlags = context_flags;
|
||||
if (GetThreadContext(th, &ctx)) {
|
||||
if (size > sizeof(ctx)) {
|
||||
size = sizeof(ctx);
|
||||
|
|
@ -274,6 +262,21 @@ static int get_thread_context(HANDLE th, ut8 *buf, int size, int bits) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
#if __i386__ || __x86_64__
|
||||
|
||||
int w32_step(RzDebug *dbg) {
|
||||
/* set TRAP flag */
|
||||
CONTEXT ctx;
|
||||
if (!w32_reg_read(dbg, RZ_REG_TYPE_GPR, (ut8 *)&ctx, sizeof(ctx))) {
|
||||
return false;
|
||||
}
|
||||
ctx.EFlags |= 0x100;
|
||||
if (!w32_reg_write(dbg, RZ_REG_TYPE_GPR, (ut8 *)&ctx, sizeof(ctx))) {
|
||||
return false;
|
||||
}
|
||||
return w32_continue(dbg, dbg->pid, dbg->tid, dbg->reason.signum);
|
||||
}
|
||||
|
||||
static int get_avx(HANDLE th, ut128 xmm[16], ut128 ymm[16]) {
|
||||
int nregs = 0, index = 0;
|
||||
DWORD ctxsize = 0;
|
||||
|
|
@ -416,6 +419,160 @@ static void print_fpu_context(HANDLE th, CONTEXT *ctx) {
|
|||
}
|
||||
}
|
||||
|
||||
static void transfer_drx(RzDebug *dbg, const ut8 *buf) {
|
||||
CONTEXT cur_ctx;
|
||||
if (w32_reg_read(dbg, RZ_REG_TYPE_ANY, (ut8 *)&cur_ctx, sizeof(CONTEXT))) {
|
||||
CONTEXT *new_ctx = (CONTEXT *)buf;
|
||||
size_t drx_size = offsetof(CONTEXT, Dr7) - offsetof(CONTEXT, Dr0) + sizeof(new_ctx->Dr7);
|
||||
memcpy(&cur_ctx.Dr0, &new_ctx->Dr0, drx_size);
|
||||
*new_ctx = cur_ctx;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void transfer_drx(RzDebug *dbg, const ut8 *buf) {
|
||||
// Do nothing (not supported)
|
||||
}
|
||||
|
||||
static void print_fpu_context(HANDLE th, CONTEXT *buf) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
int w32_step(RzDebug *dbg) {
|
||||
// Do nothing (not supported)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void get_arm_hwbp_values(ut64 address, ut32 *control, ut64 *value) {
|
||||
const ut32 type = 0b0100 << 20; // match
|
||||
const ut32 bas = 0xF << 5; // match a64 and a32
|
||||
const ut32 priv = 1 << 2;
|
||||
const ut32 enable = 1;
|
||||
*control = type | bas | priv | enable;
|
||||
*value = address;
|
||||
}
|
||||
|
||||
static inline void get_arm64_hwwp_values(ut64 address, int size, int rw, ut32 *control, ut64 *value) {
|
||||
const unsigned int offset = address % 8;
|
||||
const ut32 byte_mask = ((1 << size) - 1) << offset;
|
||||
const ut32 priv = 1 << 2;
|
||||
const ut32 enable = 1;
|
||||
ut32 load_store = 0;
|
||||
switch (rw) {
|
||||
case RZ_BP_PROT_READ:
|
||||
load_store = 1;
|
||||
break;
|
||||
case RZ_BP_PROT_WRITE:
|
||||
load_store = 2;
|
||||
break;
|
||||
case RZ_BP_PROT_ACCESS:
|
||||
load_store = 3;
|
||||
break;
|
||||
}
|
||||
*control = byte_mask << 5 | load_store << 3 | priv | enable;
|
||||
*value = address - offset;
|
||||
}
|
||||
|
||||
static inline bool is_watchpoint(RzBreakpointItem *b) {
|
||||
return b->perm & (RZ_BP_PROT_ACCESS | RZ_BP_PROT_READ | RZ_BP_PROT_WRITE);
|
||||
}
|
||||
|
||||
static inline bool is_breakpoint(RzBreakpointItem *b) {
|
||||
return b->perm & RZ_BP_PROT_EXEC;
|
||||
}
|
||||
|
||||
int w32_hwbp_arm_add(RzDebug *dbg, RzBreakpoint *bp, RzBreakpointItem *b) {
|
||||
rz_return_val_if_fail(dbg && bp && b, 0);
|
||||
W32DbgWInst *wrap = dbg->plugin_data;
|
||||
CONTEXT ctx;
|
||||
const bool alive = is_thread_alive(dbg, wrap->pi.dwThreadId);
|
||||
if (alive && suspend_thread(wrap->pi.hThread) == -1) {
|
||||
return 0;
|
||||
}
|
||||
get_thread_context(wrap->pi.hThread, (ut8 *)&ctx, sizeof(CONTEXT), CONTEXT_DEBUG_REGISTERS);
|
||||
ut32 control;
|
||||
ut64 value;
|
||||
int i;
|
||||
if (is_watchpoint(b)) {
|
||||
get_arm64_hwwp_values(b->addr, b->size, b->perm, &control, &value);
|
||||
for (i = 0; i < ARM64_MAX_WATCHPOINTS; i++) {
|
||||
if (!ctx.Wvr[i] || ctx.Wvr[i] == value) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < ARM64_MAX_WATCHPOINTS) {
|
||||
ctx.Wcr[i] = control;
|
||||
ctx.Wvr[i] = value;
|
||||
} else {
|
||||
eprintf("Too many hardware watchpoints\n");
|
||||
}
|
||||
}
|
||||
if (is_breakpoint(b)) {
|
||||
get_arm_hwbp_values(b->addr, &control, &value);
|
||||
for (i = 0; i < ARM64_MAX_BREAKPOINTS; i++) {
|
||||
if (!ctx.Bvr[i] || ctx.Bvr[i] == value) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < ARM64_MAX_BREAKPOINTS) {
|
||||
ctx.Bcr[i] = control;
|
||||
ctx.Bvr[i] = value;
|
||||
} else {
|
||||
eprintf("Too many hardware breakpoints\n");
|
||||
}
|
||||
}
|
||||
set_thread_context(wrap->pi.hThread, (ut8 *)&ctx, sizeof(CONTEXT));
|
||||
if (alive && resume_thread(wrap->pi.hThread) == -1) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w32_hwbp_arm_del(RzDebug *dbg, RzBreakpoint *bp, RzBreakpointItem *b) {
|
||||
W32DbgWInst *wrap = dbg->plugin_data;
|
||||
CONTEXT ctx;
|
||||
const bool alive = is_thread_alive(dbg, wrap->pi.dwThreadId);
|
||||
if (alive && suspend_thread(wrap->pi.hThread) == -1) {
|
||||
return 0;
|
||||
}
|
||||
get_thread_context(wrap->pi.hThread, (ut8 *)&ctx, sizeof(CONTEXT), CONTEXT_DEBUG_REGISTERS);
|
||||
ut32 control;
|
||||
ut64 value;
|
||||
int i;
|
||||
if (is_watchpoint(b)) {
|
||||
get_arm64_hwwp_values(b->addr, b->size, b->perm, &control, &value);
|
||||
for (i = 0; i < ARM64_MAX_WATCHPOINTS; i++) {
|
||||
if (ctx.Wcr[i] == control && ctx.Wvr[i] == value) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < ARM64_MAX_WATCHPOINTS) {
|
||||
ctx.Wcr[i] = 0;
|
||||
ctx.Wvr[i] = 0;
|
||||
}
|
||||
}
|
||||
if (is_breakpoint(b)) {
|
||||
get_arm_hwbp_values(b->addr, &control, &value);
|
||||
for (i = 0; i < ARM64_MAX_BREAKPOINTS; i++) {
|
||||
if (ctx.Bvr[i] == value) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < ARM64_MAX_BREAKPOINTS) {
|
||||
ctx.Bcr[i] = 0;
|
||||
ctx.Bvr[i] = 0;
|
||||
}
|
||||
}
|
||||
set_thread_context(wrap->pi.hThread, (ut8 *)&ctx, sizeof(CONTEXT));
|
||||
if (alive && resume_thread(wrap->pi.hThread, dbg->bits) == -1) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static HANDLE get_thread_handle_from_tid(RzDebug *dbg, int tid) {
|
||||
rz_return_val_if_fail(dbg, NULL);
|
||||
W32DbgWInst *wrap = dbg->plugin_data;
|
||||
|
|
@ -443,30 +600,20 @@ int w32_reg_read(RzDebug *dbg, int type, ut8 *buf, int size) {
|
|||
return 0;
|
||||
}
|
||||
// Always suspend
|
||||
if (alive && suspend_thread(th, dbg->bits) == -1) {
|
||||
if (alive && suspend_thread(th) == -1) {
|
||||
return 0;
|
||||
}
|
||||
size = get_thread_context(th, buf, size, dbg->bits);
|
||||
size = get_thread_context(th, buf, size, CONTEXT_ALL);
|
||||
if (showfpu) {
|
||||
print_fpu_context(th, (CONTEXT *)buf);
|
||||
}
|
||||
// Always resume
|
||||
if (alive && resume_thread(th, dbg->bits) == -1) {
|
||||
if (alive && resume_thread(th) == -1) {
|
||||
size = 0;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
static void transfer_drx(RzDebug *dbg, const ut8 *buf) {
|
||||
CONTEXT cur_ctx;
|
||||
if (w32_reg_read(dbg, RZ_REG_TYPE_ANY, (ut8 *)&cur_ctx, sizeof(CONTEXT))) {
|
||||
CONTEXT *new_ctx = (CONTEXT *)buf;
|
||||
size_t drx_size = offsetof(CONTEXT, Dr7) - offsetof(CONTEXT, Dr0) + sizeof(new_ctx->Dr7);
|
||||
memcpy(&cur_ctx.Dr0, &new_ctx->Dr0, drx_size);
|
||||
*new_ctx = cur_ctx;
|
||||
}
|
||||
}
|
||||
|
||||
int w32_reg_write(RzDebug *dbg, int type, const ut8 *buf, int size) {
|
||||
bool alive = is_thread_alive(dbg, dbg->tid);
|
||||
if (!alive) {
|
||||
|
|
@ -477,15 +624,15 @@ int w32_reg_write(RzDebug *dbg, int type, const ut8 *buf, int size) {
|
|||
return 0;
|
||||
}
|
||||
// Always suspend
|
||||
if (suspend_thread(th, dbg->bits) == -1) {
|
||||
if (suspend_thread(th) == -1) {
|
||||
return false;
|
||||
}
|
||||
if (type == RZ_REG_TYPE_DRX) {
|
||||
transfer_drx(dbg, buf);
|
||||
}
|
||||
bool ret = set_thread_context(th, buf, size, dbg->bits);
|
||||
bool ret = set_thread_context(th, buf, size);
|
||||
// Always resume
|
||||
if (resume_thread(th, dbg->bits) == -1) {
|
||||
if (resume_thread(th) == -1) {
|
||||
ret = false;
|
||||
}
|
||||
return ret;
|
||||
|
|
@ -529,7 +676,7 @@ int w32_detach(RzDebug *dbg, int pid) {
|
|||
PTHREAD_ITEM th;
|
||||
rz_list_foreach (dbg->threads, it, th) {
|
||||
if (th->bSuspended && !th->bFinished) {
|
||||
resume_thread(th->hThread, dbg->bits);
|
||||
resume_thread(th->hThread);
|
||||
}
|
||||
}
|
||||
rz_list_purge(dbg->threads);
|
||||
|
|
@ -778,7 +925,7 @@ int w32_select(RzDebug *dbg, int pid, int tid) {
|
|||
// Suspend all other threads
|
||||
rz_list_foreach (dbg->threads, it, th) {
|
||||
if (!th->bFinished && !th->bSuspended && th->tid != selected) {
|
||||
suspend_thread(th->hThread, dbg->bits);
|
||||
suspend_thread(th->hThread);
|
||||
th->bSuspended = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1022,7 +1169,6 @@ int w32_dbg_wait(RzDebug *dbg, int pid) {
|
|||
case UNLOAD_DLL_DEBUG_EVENT: {
|
||||
PLIB_ITEM lib = (PLIB_ITEM)find_library(de.u.UnloadDll.lpBaseOfDll);
|
||||
if (lib) {
|
||||
CloseHandle(lib->hFile);
|
||||
remove_library(lib);
|
||||
}
|
||||
ret = RZ_DEBUG_REASON_EXIT_LIB;
|
||||
|
|
@ -1073,6 +1219,11 @@ int w32_dbg_wait(RzDebug *dbg, int pid) {
|
|||
next_event = 0;
|
||||
break;
|
||||
default:
|
||||
if (rz_bp_get_at(dbg->bp, (size_t)de.u.Exception.ExceptionRecord.ExceptionAddress)) {
|
||||
ret = RZ_DEBUG_REASON_BREAKPOINT;
|
||||
next_event = 0;
|
||||
break;
|
||||
}
|
||||
print_exception_event(&de);
|
||||
if (is_exception_fatal(de.u.Exception.ExceptionRecord.ExceptionCode)) {
|
||||
next_event = 0;
|
||||
|
|
@ -1093,7 +1244,7 @@ int w32_dbg_wait(RzDebug *dbg, int pid) {
|
|||
eprintf("(%d) unknown event: %lu\n", pid, de.dwDebugEventCode);
|
||||
ret = -1;
|
||||
}
|
||||
goto end;
|
||||
next_event = 0;
|
||||
}
|
||||
} while (next_event);
|
||||
|
||||
|
|
@ -1105,7 +1256,23 @@ int w32_dbg_wait(RzDebug *dbg, int pid) {
|
|||
rz_warn_if_reached();
|
||||
}
|
||||
}
|
||||
|
||||
#if __arm__ || __arm64__
|
||||
if (ret != RZ_DEBUG_REASON_EXIT_TID) {
|
||||
CONTEXT ctx;
|
||||
suspend_thread(wrap->pi.hThread);
|
||||
get_thread_context(wrap->pi.hThread, (ut8 *)&ctx, sizeof(ctx), CONTEXT_CONTROL);
|
||||
resume_thread(wrap->pi.hThread);
|
||||
if (ctx.Cpsr & 0x20) {
|
||||
dbg->bits = RZ_SYS_BITS_16;
|
||||
} else {
|
||||
#if __arm__
|
||||
dbg->bits = RZ_SYS_BITS_32;
|
||||
#else
|
||||
dbg->bits = RZ_SYS_BITS_64;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
end:
|
||||
if (ret == RZ_DEBUG_REASON_DEAD) {
|
||||
w32_detach(dbg, dbg->pid);
|
||||
|
|
@ -1116,20 +1283,6 @@ end:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int w32_step(RzDebug *dbg) {
|
||||
/* set TRAP flag */
|
||||
CONTEXT ctx;
|
||||
if (!w32_reg_read(dbg, RZ_REG_TYPE_GPR, (ut8 *)&ctx, sizeof(ctx))) {
|
||||
return false;
|
||||
}
|
||||
ctx.EFlags |= 0x100;
|
||||
if (!w32_reg_write(dbg, RZ_REG_TYPE_GPR, (ut8 *)&ctx, sizeof(ctx))) {
|
||||
return false;
|
||||
}
|
||||
return w32_continue(dbg, dbg->pid, dbg->tid, dbg->reason.signum);
|
||||
// (void)rz_debug_handle_signals (dbg);
|
||||
}
|
||||
|
||||
int w32_continue(RzDebug *dbg, int pid, int tid, int sig) {
|
||||
if (tid != dbg->tid) {
|
||||
dbg->tid = w32_select(dbg, pid, tid);
|
||||
|
|
@ -1146,7 +1299,7 @@ int w32_continue(RzDebug *dbg, int pid, int tid, int sig) {
|
|||
|
||||
PTHREAD_ITEM th = find_thread(dbg, tid);
|
||||
if (th && th->hThread != INVALID_HANDLE_VALUE && th->bSuspended) {
|
||||
continue_thread(th->hThread, dbg->bits);
|
||||
continue_thread(th->hThread);
|
||||
th->bSuspended = false;
|
||||
}
|
||||
|
||||
|
|
@ -1222,6 +1375,19 @@ int w32_map_protect(RzDebug *dbg, ut64 addr, int size, int perms) {
|
|||
size, io_perms_to_prot(perms), &old);
|
||||
}
|
||||
|
||||
static inline ut64 pc_from_context(CONTEXT *ctx) {
|
||||
#if __x86_64__
|
||||
return ctx->Rip;
|
||||
#elif __arm__ || __arm64__
|
||||
return ctx->Pc;
|
||||
#elif __i386__
|
||||
return ctx->Eip;
|
||||
#else
|
||||
#pragma warning("platform not supported")
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
RzList *w32_thread_list(RzDebug *dbg, int pid, RzList *list) {
|
||||
// pid is not respected for TH32CS_SNAPTHREAD flag
|
||||
HANDLE th = w32_CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
|
||||
|
|
@ -1257,11 +1423,7 @@ RzList *w32_thread_list(RzDebug *dbg, int pid, RzList *list) {
|
|||
dbg->tid = te.th32ThreadID;
|
||||
w32_reg_read(dbg, RZ_REG_TYPE_GPR, (ut8 *)&ctx, sizeof(ctx));
|
||||
// TODO: is needed check context for x32 and x64??
|
||||
#if _WIN64
|
||||
pc = ctx.Rip;
|
||||
#else
|
||||
pc = ctx.Eip;
|
||||
#endif
|
||||
pc = pc_from_context(&ctx);
|
||||
PTHREAD_ITEM pthread = find_thread(dbg, te.th32ThreadID);
|
||||
if (pthread) {
|
||||
if (pthread->bFinished) {
|
||||
|
|
@ -1404,6 +1566,7 @@ static RzDebugPid *build_debug_pid(int pid, int ppid, HANDLE ph, const TCHAR *na
|
|||
}
|
||||
|
||||
RzList *w32_pid_list(RzDebug *dbg, int pid, RzList *list) {
|
||||
W32DbgWInst *wrap = dbg->plugin_data;
|
||||
HANDLE sh = w32_CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, pid);
|
||||
if (sh == INVALID_HANDLE_VALUE) {
|
||||
rz_sys_perror("CreateToolhelp32Snapshot");
|
||||
|
|
@ -1412,7 +1575,6 @@ RzList *w32_pid_list(RzDebug *dbg, int pid, RzList *list) {
|
|||
PROCESSENTRY32 pe;
|
||||
pe.dwSize = sizeof(pe);
|
||||
if (Process32First(sh, &pe)) {
|
||||
W32DbgWInst *wrap = dbg->plugin_data;
|
||||
bool all = pid == 0;
|
||||
do {
|
||||
if (all || pe.th32ProcessID == pid || pe.th32ParentProcessID == pid) {
|
||||
|
|
|
|||
|
|
@ -190,4 +190,10 @@ RzDebugInfo *w32_info(RzDebug *dbg, const char *arg);
|
|||
RzList *w32_pid_list(RzDebug *dbg, int pid, RzList *list);
|
||||
|
||||
RzList *w32_desc_list(int pid);
|
||||
|
||||
#if __arm64__
|
||||
int w32_hwbp_arm_add(RzDebug *dbg, RzBreakpoint *bp, RzBreakpointItem *b);
|
||||
int w32_hwbp_arm_del(RzDebug *dbg, RzBreakpoint *bp, RzBreakpointItem *b);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -247,13 +247,21 @@ static char *msg_types_arr[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
void __free_window(void *ptr) {
|
||||
typedef struct _window {
|
||||
DWORD pid;
|
||||
DWORD tid;
|
||||
HWND h;
|
||||
char *name;
|
||||
ut64 proc;
|
||||
} window;
|
||||
|
||||
void free_window(void *ptr) {
|
||||
window *win = ptr;
|
||||
free(win->name);
|
||||
free(win);
|
||||
}
|
||||
|
||||
static window *__window_from_handle(HANDLE hwnd) {
|
||||
static window *window_from_handle(HANDLE hwnd) {
|
||||
rz_return_val_if_fail(hwnd, NULL);
|
||||
window *win = RZ_NEW0(window);
|
||||
if (!win) {
|
||||
|
|
@ -277,7 +285,7 @@ static window *__window_from_handle(HANDLE hwnd) {
|
|||
return win;
|
||||
}
|
||||
|
||||
static RzTable *__create_window_table(void) {
|
||||
static RzTable *create_window_table(void) {
|
||||
RzTable *tbl = rz_table_new();
|
||||
if (!tbl) {
|
||||
return NULL;
|
||||
|
|
@ -289,7 +297,7 @@ static RzTable *__create_window_table(void) {
|
|||
return tbl;
|
||||
}
|
||||
|
||||
static void __add_window_to_table(RzTable *tbl, window *win) {
|
||||
static void add_window_to_table(RzTable *tbl, window *win) {
|
||||
rz_return_if_fail(tbl && win);
|
||||
char *handle = rz_str_newf("0x%08" PFMT64x "", (ut64)win->h);
|
||||
char *pid = rz_str_newf("%lu", win->pid);
|
||||
|
|
@ -301,18 +309,20 @@ static void __add_window_to_table(RzTable *tbl, window *win) {
|
|||
}
|
||||
|
||||
RZ_API void rz_w32_identify_window(void) {
|
||||
while (!rz_cons_yesno('y', "Move cursor to the window to be identified. Ready?"))
|
||||
while (!rz_cons_yesno('y', "Move cursor to the window to be identified. Ready? (Y/n)"))
|
||||
;
|
||||
POINT p;
|
||||
GetCursorPos(&p);
|
||||
HANDLE hwnd = WindowFromPoint(p);
|
||||
if (!GetCursorPos(&p)) {
|
||||
rz_sys_perror("GetCursorPos");
|
||||
}
|
||||
HWND hwnd = WindowFromPoint(p);
|
||||
window *win = NULL;
|
||||
if (hwnd) {
|
||||
if (rz_cons_yesno('y', "Try to get the child?")) {
|
||||
HANDLE child = ChildWindowFromPoint(hwnd, p);
|
||||
if (rz_cons_yesno('y', "Try to get the child? (Y/n)")) {
|
||||
HWND child = ChildWindowFromPoint(hwnd, p);
|
||||
hwnd = child ? child : hwnd;
|
||||
}
|
||||
win = __window_from_handle(hwnd);
|
||||
win = window_from_handle(hwnd);
|
||||
} else {
|
||||
eprintf("No window found\n");
|
||||
return;
|
||||
|
|
@ -321,22 +331,22 @@ RZ_API void rz_w32_identify_window(void) {
|
|||
eprintf("Error trying to get information from 0x%08" PFMT64x "\n", (ut64)hwnd);
|
||||
return;
|
||||
}
|
||||
RzTable *tbl = __create_window_table();
|
||||
RzTable *tbl = create_window_table();
|
||||
if (!tbl) {
|
||||
return;
|
||||
}
|
||||
__add_window_to_table(tbl, win);
|
||||
add_window_to_table(tbl, win);
|
||||
char *tbl_str = rz_table_tofancystring(tbl);
|
||||
rz_cons_print(tbl_str);
|
||||
free(tbl_str);
|
||||
rz_table_free(tbl);
|
||||
}
|
||||
|
||||
static BOOL CALLBACK __enum_childs(
|
||||
static BOOL CALLBACK enum_childs(
|
||||
_In_ HWND hwnd,
|
||||
_In_ LPARAM lParam) {
|
||||
RzList *windows = (RzList *)lParam;
|
||||
window *win = __window_from_handle(hwnd);
|
||||
window *win = window_from_handle(hwnd);
|
||||
if (!win) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -344,16 +354,16 @@ static BOOL CALLBACK __enum_childs(
|
|||
return true;
|
||||
}
|
||||
|
||||
static RzList *__get_windows(RzDebug *dbg) {
|
||||
RzList *windows = rz_list_newf((RzListFree)__free_window);
|
||||
static RzList *get_windows(RzDebug *dbg) {
|
||||
RzList *windows = rz_list_newf((RzListFree)free_window);
|
||||
HWND hCurWnd = NULL;
|
||||
do {
|
||||
hCurWnd = FindWindowEx(NULL, hCurWnd, NULL, NULL);
|
||||
DWORD dwProcessID = 0;
|
||||
GetWindowThreadProcessId(hCurWnd, &dwProcessID);
|
||||
if (dbg->pid == dwProcessID) {
|
||||
EnumChildWindows(hCurWnd, __enum_childs, (LPARAM)windows);
|
||||
window *win = __window_from_handle(hCurWnd);
|
||||
EnumChildWindows(hCurWnd, enum_childs, (LPARAM)windows);
|
||||
window *win = window_from_handle(hCurWnd);
|
||||
if (!win) {
|
||||
rz_list_free(windows);
|
||||
return NULL;
|
||||
|
|
@ -364,7 +374,7 @@ static RzList *__get_windows(RzDebug *dbg) {
|
|||
return windows;
|
||||
}
|
||||
|
||||
static ut64 __get_dispatchmessage_offset(RzDebug *dbg) {
|
||||
static ut64 get_dispatchmessage_offset(RzDebug *dbg) {
|
||||
RzList *modlist = rz_debug_modules_list(dbg);
|
||||
RzListIter *it;
|
||||
RzDebugMap *mod;
|
||||
|
|
@ -397,7 +407,7 @@ static ut64 __get_dispatchmessage_offset(RzDebug *dbg) {
|
|||
return offset;
|
||||
}
|
||||
|
||||
static void __init_msg_types(Sdb **msg_types) {
|
||||
static void init_msg_types(Sdb **msg_types) {
|
||||
*msg_types = sdb_new0();
|
||||
int i;
|
||||
char *cur_type;
|
||||
|
|
@ -406,44 +416,44 @@ static void __init_msg_types(Sdb **msg_types) {
|
|||
}
|
||||
}
|
||||
|
||||
static DWORD __get_msg_type(char *name) {
|
||||
static DWORD get_msg_type(char *name) {
|
||||
static Sdb *msg_types = NULL;
|
||||
if (!msg_types) {
|
||||
__init_msg_types(&msg_types);
|
||||
init_msg_types(&msg_types);
|
||||
}
|
||||
ut32 found;
|
||||
const char *type_str = sdb_const_get(msg_types, name, &found);
|
||||
if (found) {
|
||||
int type = rz_num_math(NULL, type_str);
|
||||
int type = rz_num_get(NULL, type_str);
|
||||
return type;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __print_windows(RzDebug *dbg, RzList *windows) {
|
||||
RzTable *tbl = __create_window_table();
|
||||
static void print_windows(RzDebug *dbg, RzList *windows) {
|
||||
RzTable *tbl = create_window_table();
|
||||
if (!tbl) {
|
||||
return;
|
||||
}
|
||||
RzListIter *it;
|
||||
window *win;
|
||||
rz_list_foreach (windows, it, win) {
|
||||
__add_window_to_table(tbl, win);
|
||||
add_window_to_table(tbl, win);
|
||||
}
|
||||
char *t = rz_table_tofancystring(tbl);
|
||||
char *t = rz_table_tostring(tbl);
|
||||
dbg->cb_printf(t);
|
||||
free(t);
|
||||
rz_table_free(tbl);
|
||||
}
|
||||
|
||||
RZ_API void rz_w32_print_windows(RzDebug *dbg) {
|
||||
RzList *windows = __get_windows(dbg);
|
||||
RzList *windows = get_windows(dbg);
|
||||
if (windows) {
|
||||
if (!windows->length) {
|
||||
dbg->cb_printf("No windows for this process.\n");
|
||||
return;
|
||||
}
|
||||
__print_windows(dbg, windows);
|
||||
print_windows(dbg, windows);
|
||||
}
|
||||
rz_list_free(windows);
|
||||
}
|
||||
|
|
@ -453,14 +463,14 @@ RZ_API bool rz_w32_add_winmsg_breakpoint(RzDebug *dbg, const char *msg_name, con
|
|||
char *name = strdup(msg_name);
|
||||
rz_str_trim(name);
|
||||
|
||||
DWORD type = __get_msg_type(name);
|
||||
DWORD type = get_msg_type(name);
|
||||
if (!type) {
|
||||
free(name);
|
||||
return false;
|
||||
}
|
||||
ut64 offset = 0;
|
||||
if (window_id) {
|
||||
RzList *windows = __get_windows(dbg);
|
||||
RzList *windows = get_windows(dbg);
|
||||
if (windows && !windows->length) {
|
||||
dbg->cb_printf("No windows for this process.\n");
|
||||
}
|
||||
|
|
@ -475,30 +485,51 @@ RZ_API bool rz_w32_add_winmsg_breakpoint(RzDebug *dbg, const char *msg_name, con
|
|||
}
|
||||
if (!offset) {
|
||||
dbg->cb_printf("Window not found, try these:\n");
|
||||
__print_windows(dbg, windows);
|
||||
print_windows(dbg, windows);
|
||||
}
|
||||
rz_list_free(windows);
|
||||
} else {
|
||||
offset = __get_dispatchmessage_offset(dbg);
|
||||
offset = get_dispatchmessage_offset(dbg);
|
||||
}
|
||||
if (!offset) {
|
||||
free(name);
|
||||
return false;
|
||||
}
|
||||
rz_debug_bp_add(dbg, offset, 0, 0, 0, NULL, 0);
|
||||
RzBreakpointItem *b = rz_debug_bp_add(dbg, offset, 0, 0, 0, NULL, 0);
|
||||
if (!b) {
|
||||
free(name);
|
||||
return false;
|
||||
}
|
||||
char *cond;
|
||||
if (window_id) {
|
||||
cond = rz_str_newf("?= `ae %lu,edx,-`", type);
|
||||
char *reg;
|
||||
if (!strcmp(dbg->arch, "arm")) {
|
||||
if (dbg->bits == RZ_SYS_BITS_64) {
|
||||
reg = "x1";
|
||||
} else {
|
||||
reg = "r1";
|
||||
}
|
||||
} else {
|
||||
reg = "edx";
|
||||
}
|
||||
b->cond = rz_str_newf("?q `ae %s,%d,-`", reg, type);
|
||||
} else {
|
||||
char *reg;
|
||||
if (dbg->bits == RZ_SYS_BITS_64) {
|
||||
reg = "rcx";
|
||||
if (!strcmp(dbg->arch, "arm")) {
|
||||
if (dbg->bits == RZ_SYS_BITS_64) {
|
||||
reg = "x0";
|
||||
} else {
|
||||
reg = "r0";
|
||||
}
|
||||
} else {
|
||||
reg = "ecx";
|
||||
if (dbg->bits == RZ_SYS_BITS_64) {
|
||||
reg = "rcx";
|
||||
} else {
|
||||
reg = "ecx";
|
||||
}
|
||||
}
|
||||
cond = rz_str_newf("?= `ae %lu,%s,%d,+,[4],-`", type, reg, dbg->bits);
|
||||
b->cond = rz_str_newf("?q `ae %lu,%s,%d,+,[4],-`", type, reg, dbg->bits);
|
||||
}
|
||||
dbg->corebind.cmdf(dbg->corebind.core, "\"dbC %s @ 0x%" PFMT64x "\"", cond, offset);
|
||||
free(name);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,14 +3,6 @@
|
|||
|
||||
#include <rz_types.h>
|
||||
|
||||
typedef struct _window {
|
||||
DWORD pid;
|
||||
DWORD tid;
|
||||
HANDLE h;
|
||||
char *name;
|
||||
ut64 proc;
|
||||
} window;
|
||||
|
||||
RZ_API bool rz_w32_add_winmsg_breakpoint(RzDebug *dbg, const char *msg_name, const char *window_id);
|
||||
RZ_API void rz_w32_identify_window(void);
|
||||
RZ_API void rz_w32_print_windows(RzDebug *dbg);
|
||||
|
|
|
|||
|
|
@ -497,16 +497,26 @@ static inline void *rz_new_copy(int size, void *data) {
|
|||
#endif
|
||||
#else
|
||||
#ifdef _MSC_VER
|
||||
#ifdef _WIN64
|
||||
#if defined(_M_X64) || defined(_M_AMD64)
|
||||
#define RZ_SYS_ARCH "x86"
|
||||
#define RZ_SYS_BITS (RZ_SYS_BITS_32 | RZ_SYS_BITS_64)
|
||||
#define RZ_SYS_ENDIAN 0
|
||||
#define __x86_64__ 1
|
||||
#else
|
||||
#elif defined(_M_IX86)
|
||||
#define RZ_SYS_ARCH "x86"
|
||||
#define RZ_SYS_BITS (RZ_SYS_BITS_32)
|
||||
#define __i386__ 1
|
||||
#define RZ_SYS_ENDIAN 0
|
||||
#define __i386__ 1
|
||||
#elif defined(_M_ARM64)
|
||||
#define RZ_SYS_ARCH "arm"
|
||||
#define RZ_SYS_BITS (RZ_SYS_BITS_32 | RZ_SYS_BITS_64)
|
||||
#define RZ_SYS_ENDIAN 0
|
||||
#define __arm64__ 1
|
||||
#elif defined(_M_ARM)
|
||||
#define RZ_SYS_ARCH "arm"
|
||||
#define RZ_SYS_BITS RZ_SYS_BITS_32
|
||||
#define RZ_SYS_ENDIAN 0
|
||||
#define __arm__ 1
|
||||
#endif
|
||||
#else
|
||||
#define RZ_SYS_ARCH "unknown"
|
||||
|
|
|
|||
13
sys/cross-arm64-windows.txt
Normal file
13
sys/cross-arm64-windows.txt
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# SPDX-FileCopyrightText: 2021 GustavoLCR <gugulcr@gmail.com>
|
||||
# SPDX-License-Identifier: LGPL-3.0-only
|
||||
[binaries]
|
||||
c = 'cl'
|
||||
cpp = 'cl'
|
||||
ar = 'lib'
|
||||
windres = 'rc'
|
||||
|
||||
[host_machine]
|
||||
system = 'windows'
|
||||
cpu_family = 'aarch64'
|
||||
cpu = 'armv8'
|
||||
endian = 'little'
|
||||
Loading…
Reference in a new issue