From 39d5b0f9e567bcec3526c487f5194626fd0b03dd Mon Sep 17 00:00:00 2001 From: pancake Date: Thu, 14 Sep 2023 22:32:24 +0200 Subject: [PATCH] Add RArch.esilCb() and register a new op for x86 ##arch * This callback was previously not used or accessed * Still wip, as the fini is never called --- libr/arch/arch.c | 6 +++++ libr/arch/p/8051/plugin.c | 4 ++-- libr/arch/p/avr/plugin.c | 4 ++-- libr/arch/p/bpf/plugin.c | 4 ++-- libr/arch/p/gb/plugin.c | 4 ++-- libr/arch/p/x86/plugin_cs.c | 46 ++++++++++++++++++++++++++----------- libr/core/cmd_anal.inc.c | 5 +++- libr/esil/esil.c | 4 ++-- libr/include/r_arch.h | 9 ++++---- 9 files changed, 58 insertions(+), 28 deletions(-) diff --git a/libr/arch/arch.c b/libr/arch/arch.c index 2da2d1c97d..237df3274d 100644 --- a/libr/arch/arch.c +++ b/libr/arch/arch.c @@ -296,6 +296,12 @@ R_API int r_arch_info(RArch *a, int query) { return info? info (session, query): -1; } +R_API bool r_arch_esilcb(RArch *a, RArchEsilAction action) { + RArchSession *session = a->session; + RArchPluginEsilCallback esilcb = R_UNWRAP3 (session, plugin, esilcb); + return esilcb? esilcb (session, action): false; +} + R_API bool r_arch_encode(RArch *a, RAnalOp *op, RArchEncodeMask mask) { RArchSession *session = a->session; RArchPluginEncodeCallback encode = R_UNWRAP3 (session, plugin, encode); diff --git a/libr/arch/p/8051/plugin.c b/libr/arch/p/8051/plugin.c index 7a61a06e1d..3a7543dcf3 100644 --- a/libr/arch/p/8051/plugin.c +++ b/libr/arch/p/8051/plugin.c @@ -1102,10 +1102,10 @@ static bool esil_cb(RArchSession *as, RArchEsilAction action) { } switch (action) { - case R_ARCH_ESIL_INIT: + case R_ARCH_ESIL_ACTION_INIT: esil_i8051_init (as, esil); break; - case R_ARCH_ESIL_FINI: + case R_ARCH_ESIL_ACTION_FINI: esil_i8051_fini (as, esil); break; default: diff --git a/libr/arch/p/avr/plugin.c b/libr/arch/p/avr/plugin.c index 1ce797b0cd..2d366226a1 100644 --- a/libr/arch/p/avr/plugin.c +++ b/libr/arch/p/avr/plugin.c @@ -2371,9 +2371,9 @@ static bool esil_cb(RArchSession *as, RArchEsilAction action) { } switch (action) { - case R_ARCH_ESIL_INIT: + case R_ARCH_ESIL_ACTION_INIT: return esil_avr_init (as, esil); - case R_ARCH_ESIL_FINI: + case R_ARCH_ESIL_ACTION_FINI: return esil_avr_fini (as, esil); default: return false; diff --git a/libr/arch/p/bpf/plugin.c b/libr/arch/p/bpf/plugin.c index f6b34533e1..5c9fd61a42 100644 --- a/libr/arch/p/bpf/plugin.c +++ b/libr/arch/p/bpf/plugin.c @@ -1198,10 +1198,10 @@ static bool esilcb(RArchSession *as, RArchEsilAction action) { } const int syscall_number = 0; switch (action) { - case R_ARCH_ESIL_INIT: + case R_ARCH_ESIL_ACTION_INIT: r_esil_set_interrupt (esil, syscall_number, &bpf_int_exit, as); break; - case R_ARCH_ESIL_FINI: + case R_ARCH_ESIL_ACTION_FINI: r_esil_del_interrupt (esil, 0); break; default: diff --git a/libr/arch/p/gb/plugin.c b/libr/arch/p/gb/plugin.c index eb8f6dc96e..562bbfc737 100644 --- a/libr/arch/p/gb/plugin.c +++ b/libr/arch/p/gb/plugin.c @@ -1545,10 +1545,10 @@ static bool esil_cb(RArchSession *as, RArchEsilAction action) { return false; } switch (action) { - case R_ARCH_ESIL_INIT: + case R_ARCH_ESIL_ACTION_INIT: esil_gb_init (esil); break; - case R_ARCH_ESIL_FINI: + case R_ARCH_ESIL_ACTION_FINI: esil_gb_fini (esil); break; default: diff --git a/libr/arch/p/x86/plugin_cs.c b/libr/arch/p/x86/plugin_cs.c index 5a78fa1e5b..9631b0b5a1 100644 --- a/libr/arch/p/x86/plugin_cs.c +++ b/libr/arch/p/x86/plugin_cs.c @@ -7,7 +7,6 @@ #include #define r_anal_value_new() R_NEW0 (RAnalValue) -#define ARCH_HAVE_ESILCB 0 #define ARCH_HAVE_READ 1 #if 0 @@ -4433,21 +4432,47 @@ static char *mnemonics(RArchSession *as, int id, bool json) { CapstonePluginData *cpd = as->data; return r_arch_cs_mnemonics (as, cpd->cs_handle, id, json); } +#include -// esilcb -#if ARCH_HAVE_ESILCB -static int esil_x86_cs_init(REsil *esil) { - // not implemented - if (!esil) { +static bool tls_begin(REsil *esil) { + // R_LOG_DEBUG ("tls:begin"); + RCoreBind *coreb = &esil->anal->coreb; + coreb->cmdf (coreb->core, "omb fs"); + return true; +} + +static bool tls_end(REsil *esil) { + // R_LOG_DEBUG ("tls:end"); + RCoreBind *coreb = &esil->anal->coreb; + coreb->cmdf (coreb->core, "omb default"); + return true; +} + +static bool esilcb(RArchSession *as, RArchEsilAction action) { + // R_LOG_DEBUG ("x86.cs.esil.action %d", action); + RBin *bin = as->arch->binb.bin; + if (!bin) { return false; } + RIO *io = bin->iob.io; + RCore *core = io->coreb.core; + RAnal *anal = core->anal; + REsil *esil = anal->esil; + // not implemented + if (!esil) { + R_LOG_ERROR ("Failed to find an esil instance"); + return false; + } + r_esil_set_op (esil, "TLS_BEGIN", tls_begin, + 0, 0, R_ESIL_OP_TYPE_CUSTOM); + r_esil_set_op (esil, "TLS_END", tls_end, + 0, 0, R_ESIL_OP_TYPE_CUSTOM); // XXX. this depends on kernel // r_esil_set_interrupt (esil, 0x80, x86_int_0x80); /* disable by default */ // r_esil_set_interrupt (esil, 0x80, NULL); // this is stupid, don't do this return true; } -#endif const RArchPlugin r_arch_plugin_x86_cs = { .meta = { @@ -4463,12 +4488,7 @@ const RArchPlugin r_arch_plugin_x86_cs = { .fini = fini, .info = archinfo, .regs = &get_reg_profile, - // .esilcb = esilcb, -#if 0 - .esil_init = esil_x86_cs_init, - .esil_fini = esil_x86_cs_fini, -// .esil_intr = esil_x86_cs_intr, -#endif + .esilcb = esilcb, .mnemonics = mnemonics, }; diff --git a/libr/core/cmd_anal.inc.c b/libr/core/cmd_anal.inc.c index 5590aaa5b5..c44cd1f70a 100644 --- a/libr/core/cmd_anal.inc.c +++ b/libr/core/cmd_anal.inc.c @@ -2236,7 +2236,10 @@ static inline REsil *esil_new_setup(RCore *core) { esil->cmd = r_core_esil_cmd; const char *et = r_config_get (core->config, "cmd.esil.trap"); esil->cmd_trap = R_STR_ISNOTEMPTY (et)? strdup (et): NULL; - + } + // run the esilcb from arch + if (core->anal->arch) { + r_arch_esilcb (core->anal->arch, R_ARCH_ESIL_ACTION_INIT); } return esil; } diff --git a/libr/esil/esil.c b/libr/esil/esil.c index 9c26b7f854..a8fa6dd4ab 100644 --- a/libr/esil/esil.c +++ b/libr/esil/esil.c @@ -181,7 +181,7 @@ R_API void r_esil_free(REsil *esil) { if (as) { RArchPluginEsilCallback esil_cb = R_UNWRAP3 (as, plugin, esilcb); if (esil_cb) { - if (!esil_cb (as, R_ARCH_ESIL_FINI)) { + if (!esil_cb (as, R_ARCH_ESIL_ACTION_FINI)) { R_LOG_DEBUG ("Failed to properly cleanup esil for arch plugin"); } } @@ -4016,7 +4016,7 @@ R_API bool r_esil_setup(REsil *esil, RAnal *anal, bool romem, bool stats, bool n anal->arch->esil = esil; RArchPluginEsilCallback esil_cb = R_UNWRAP3 (as, plugin, esilcb); if (esil_cb) { - return esil_cb (as, R_ARCH_ESIL_INIT); + return esil_cb (as, R_ARCH_ESIL_ACTION_INIT); } } return true; diff --git a/libr/include/r_arch.h b/libr/include/r_arch.h index 3d164e196b..f0e36a688d 100644 --- a/libr/include/r_arch.h +++ b/libr/include/r_arch.h @@ -139,11 +139,11 @@ typedef struct r_arch_session_t { } RArchSession; typedef enum { - R_ARCH_ESIL_INIT, - R_ARCH_ESIL_MAPS, + R_ARCH_ESIL_ACTION_INIT, + R_ARCH_ESIL_ACTION_MAPS, // R_ARCH_ESIL_EVAL, - R_ARCH_ESIL_RESET, - R_ARCH_ESIL_FINI, + R_ARCH_ESIL_ACTION_RESET, + R_ARCH_ESIL_ACTION_FINI, } RArchEsilAction; typedef ut32 RArchDecodeMask; @@ -198,6 +198,7 @@ R_API bool r_arch_unload_decoder(RArch *arch, const char *dname); R_API int r_arch_info(RArch *arch, int query); R_API bool r_arch_decode(RArch *a, RAnalOp *op, RArchDecodeMask mask); R_API bool r_arch_encode(RArch *a, RAnalOp *op, RArchEncodeMask mask); +R_API bool r_arch_esilcb(RArch *a, RArchEsilAction action); //R_API bool r_arch_esil_init(RArch *arch, const char *dname, REsil *esil); //R_API void r_arch_esil_fini(RArch *arch, const char *dname, REsil *esil);