Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Windows on ARM #1502

Merged
merged 19 commits into from
Nov 24, 2021
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions binrz/rz-test/rz_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 4 additions & 8 deletions librz/core/cconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -3377,7 +3369,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)");
Expand Down
19 changes: 19 additions & 0 deletions librz/core/cdebug.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
1 change: 1 addition & 0 deletions librz/core/cmd/cmd_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down
1 change: 1 addition & 0 deletions librz/core/core_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,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);
Expand Down
1 change: 1 addition & 0 deletions librz/core/tui/visual.c
Original file line number Diff line number Diff line change
Expand Up @@ -3410,6 +3410,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;
}
}
Expand Down
27 changes: 23 additions & 4 deletions librz/debug/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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]);

Expand All @@ -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:
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down
15 changes: 13 additions & 2 deletions librz/debug/p/debug_native.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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__
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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,
};

Expand Down
14 changes: 7 additions & 7 deletions librz/debug/p/debug_windbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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;
Expand All @@ -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) {
Expand All @@ -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 {
Expand Down
18 changes: 15 additions & 3 deletions librz/debug/p/native/bt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand Down
Loading