Move ESIL into its own namespace (#6199)
* Move ESIL into its own namespace * Remove RzAnalysisEsilInterState from RzAnalysis * More cleanup to split cil.c from ESIL code * Rename RzAnalysisRzilTrace to RzAnalysisILTrace * Fix various null-derefs. * Remove rz_analysis_get/set_esil_inter_state * Fix use after free and leaks
This commit is contained in:
parent
1fe7507c0f
commit
1a57d18cc4
32 changed files with 1824 additions and 1904 deletions
|
|
@ -113,12 +113,6 @@ RZ_API RzAnalysis *rz_analysis_new(RZ_NULLABLE const char *sdb_types_path) {
|
|||
free(analysis);
|
||||
return NULL;
|
||||
}
|
||||
analysis->esilinterstate = RZ_NEW0(RzAnalysisEsilInterState);
|
||||
if (!analysis->esilinterstate) {
|
||||
free(analysis->sdb_types_path);
|
||||
free(analysis);
|
||||
return NULL;
|
||||
}
|
||||
analysis->bb_tree = NULL;
|
||||
analysis->ht_addr_fun = ht_up_new(NULL, NULL);
|
||||
analysis->ht_name_fun = ht_sp_new(HT_STR_DUP, NULL, NULL);
|
||||
|
|
@ -222,7 +216,6 @@ RZ_API void rz_analysis_free(RZ_NULLABLE RzAnalysis *a) {
|
|||
rz_type_db_free(a->typedb);
|
||||
sdb_free(a->sdb);
|
||||
rz_analysis_esil_free(a->esil);
|
||||
free(a->esilinterstate);
|
||||
free(a->last_disasm_reg);
|
||||
rz_list_free(a->imports);
|
||||
rz_str_constpool_fini(&a->constpool);
|
||||
|
|
@ -645,16 +638,6 @@ RZ_API RZ_BORROW bool rz_analysis_get_recursive_noreturn(RZ_NONNULL RzAnalysis *
|
|||
return analysis->recursive_noreturn;
|
||||
}
|
||||
|
||||
RZ_DEPRECATE RZ_API RZ_BORROW RzAnalysisEsilInterState *rz_analysis_get_esil_inter_state(RZ_NONNULL RzAnalysis *analysis) {
|
||||
rz_return_val_if_fail(analysis, NULL);
|
||||
return analysis->esilinterstate;
|
||||
}
|
||||
|
||||
RZ_DEPRECATE RZ_API void rz_analysis_set_esil_inter_state(RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzAnalysisEsilInterState *esilinterstate) {
|
||||
rz_return_if_fail(analysis);
|
||||
analysis->esilinterstate = esilinterstate;
|
||||
}
|
||||
|
||||
RZ_DEPRECATE RZ_API void rz_analysis_set_core(RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE void *core) {
|
||||
rz_return_if_fail(analysis);
|
||||
analysis->core = core;
|
||||
|
|
@ -665,16 +648,6 @@ RZ_DEPRECATE RZ_API void rz_analysis_set_event(RZ_NONNULL RzAnalysis *analysis,
|
|||
analysis->ev = ev;
|
||||
}
|
||||
|
||||
RZ_DEPRECATE RZ_API RZ_BORROW RzAnalysisEsil *rz_analysis_get_esil(RZ_NONNULL RzAnalysis *analysis) {
|
||||
rz_return_val_if_fail(analysis, NULL);
|
||||
return analysis->esil;
|
||||
}
|
||||
|
||||
RZ_DEPRECATE RZ_API void rz_analysis_set_esil(RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzAnalysisEsil *esil) {
|
||||
rz_return_if_fail(analysis);
|
||||
analysis->esil = esil;
|
||||
}
|
||||
|
||||
RZ_DEPRECATE RZ_API const char *rz_analysis_get_arch(RZ_NONNULL const RzAnalysis *analysis) {
|
||||
rz_return_val_if_fail(analysis, RZ_SYS_ARCH);
|
||||
return analysis->cur ? analysis->cur->name : RZ_SYS_ARCH;
|
||||
|
|
@ -1272,3 +1245,13 @@ RZ_API void rz_analysis_remove_import(RzAnalysis *analysis, const char *imp) {
|
|||
RZ_API void rz_analysis_purge_imports(RzAnalysis *analysis) {
|
||||
rz_list_purge(analysis->imports);
|
||||
}
|
||||
|
||||
RZ_DEPRECATE RZ_API RZ_BORROW RzAnalysisEsil *rz_analysis_get_esil(RZ_NONNULL RzAnalysis *analysis) {
|
||||
rz_return_val_if_fail(analysis, NULL);
|
||||
return analysis->esil;
|
||||
}
|
||||
|
||||
RZ_DEPRECATE RZ_API void rz_analysis_set_esil(RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzAnalysisEsil *esil) {
|
||||
rz_return_if_fail(analysis);
|
||||
analysis->esil = esil;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@ struct rz_analysis_t {
|
|||
int maxreflines; // asm.lines.maxref
|
||||
ut32 pcalign; // asm.pcalign
|
||||
RzAnalysisEsil *esil;
|
||||
RzAnalysisEsilInterState *esilinterstate;
|
||||
RzAnalysisILVM *il_vm; ///< user-faced VM, NEVER use this for any analysis passes!
|
||||
RzAnalysisPlugin *cur;
|
||||
RzInterval limit; // analysis.from, analysis.to
|
||||
|
|
|
|||
|
|
@ -2,10 +2,9 @@
|
|||
// SPDX-FileCopyrightText: 2014-2021 condret <condr3t@protonmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_esil/rz_esil.h>
|
||||
#include "analysis_private.h"
|
||||
#include <rz_types.h>
|
||||
#include <rz_util.h>
|
||||
#include <rz_bind.h>
|
||||
#define EANALYSIS(e) ((RzAnalysis *)(esil->panalysis))
|
||||
|
||||
#define FLG(x) RZ_ANALYSIS_ESIL_FLAG_##x
|
||||
#define cpuflag(x, y) \
|
||||
|
|
@ -51,7 +50,7 @@ static bool isnum(RzAnalysisEsil *esil, const char *str, ut64 *num) {
|
|||
}
|
||||
|
||||
static bool ispackedreg(RzAnalysisEsil *esil, const char *str) {
|
||||
RzRegItem *ri = rz_reg_get(esil->analysis->reg, str, -1);
|
||||
RzRegItem *ri = rz_reg_get(EANALYSIS(esil)->reg, str, -1);
|
||||
return ri ? ri->packed_size > 0 : false;
|
||||
}
|
||||
|
||||
|
|
@ -100,6 +99,7 @@ RZ_API RzAnalysisEsil *rz_analysis_esil_new(int stacksize, int iotrap, unsigned
|
|||
rz_analysis_esil_interrupts_init(esil);
|
||||
esil->addrmask = genmask(addrsize - 1);
|
||||
rz_strbuf_init(&esil->current_opstr);
|
||||
esil->esilinterstate = RZ_NEW0(RzAnalysisEsilInterState);
|
||||
return esil;
|
||||
}
|
||||
|
||||
|
|
@ -132,14 +132,6 @@ static bool rz_analysis_esil_fire_trap(RzAnalysisEsil *esil, int trap_type, int
|
|||
return true;
|
||||
}
|
||||
}
|
||||
if (esil->analysis) {
|
||||
RzAnalysisPlugin *ap = esil->analysis->cur;
|
||||
if (ap && ap->esil_trap) {
|
||||
if (ap->esil_trap(esil, trap_type, trap_code)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -155,8 +147,8 @@ RZ_API void rz_analysis_esil_free(RzAnalysisEsil *esil) {
|
|||
if (!esil) {
|
||||
return;
|
||||
}
|
||||
if (esil->analysis && esil == esil->analysis->esil) {
|
||||
esil->analysis->esil = NULL;
|
||||
if (EANALYSIS(esil) && esil == EANALYSIS(esil)->esil) {
|
||||
EANALYSIS(esil)->esil = NULL;
|
||||
}
|
||||
ht_sp_free(esil->ops);
|
||||
esil->ops = NULL;
|
||||
|
|
@ -166,8 +158,8 @@ RZ_API void rz_analysis_esil_free(RzAnalysisEsil *esil) {
|
|||
esil->stats = NULL;
|
||||
rz_analysis_esil_stack_free(esil);
|
||||
free(esil->stack);
|
||||
if (esil->analysis && esil->analysis->cur && esil->analysis->cur->esil_fini) {
|
||||
esil->analysis->cur->esil_fini(esil);
|
||||
if (EANALYSIS(esil) && EANALYSIS(esil)->cur && EANALYSIS(esil)->cur->esil_fini) {
|
||||
EANALYSIS(esil)->cur->esil_fini(esil);
|
||||
}
|
||||
rz_strbuf_fini(&esil->current_opstr);
|
||||
rz_analysis_esil_trace_free(esil->trace);
|
||||
|
|
@ -179,17 +171,18 @@ RZ_API void rz_analysis_esil_free(RzAnalysisEsil *esil) {
|
|||
free(esil->cmd_step);
|
||||
free(esil->cmd_step_out);
|
||||
free(esil->cmd_ioer);
|
||||
free(esil->esilinterstate);
|
||||
free(esil);
|
||||
}
|
||||
|
||||
static ut8 esil_internal_sizeof_reg(RzAnalysisEsil *esil, const char *r) {
|
||||
rz_return_val_if_fail(esil && esil->analysis && esil->analysis->reg && r, 0);
|
||||
RzRegItem *ri = rz_reg_get(esil->analysis->reg, r, -1);
|
||||
rz_return_val_if_fail(esil && EANALYSIS(esil) && EANALYSIS(esil)->reg && r, 0);
|
||||
RzRegItem *ri = rz_reg_get(EANALYSIS(esil)->reg, r, -1);
|
||||
return ri ? ri->size : 0;
|
||||
}
|
||||
|
||||
static int internal_esil_mem_read(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len) {
|
||||
rz_return_val_if_fail(esil && esil->analysis && esil->analysis->iob.io, 0);
|
||||
rz_return_val_if_fail(esil && EANALYSIS(esil) && EANALYSIS(esil)->iob.io, 0);
|
||||
|
||||
addr &= esil->addrmask;
|
||||
if (esil->cmd_mdev && esil->mdev_range) {
|
||||
|
|
@ -200,10 +193,10 @@ static int internal_esil_mem_read(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int
|
|||
}
|
||||
}
|
||||
// TODO: Check if error return from read_at.(on previous version of r2 this call always return len)
|
||||
(void)esil->analysis->iob.read_at(esil->analysis->iob.io, addr, buf, len);
|
||||
(void)EANALYSIS(esil)->iob.read_at(EANALYSIS(esil)->iob.io, addr, buf, len);
|
||||
// check if request address is mapped , if don't fire trap and esil ioer callback
|
||||
// now with siol, read_at return true/false can't be used to check error vs len
|
||||
if (!esil->analysis->iob.is_valid_offset(esil->analysis->iob.io, addr, false)) {
|
||||
if (!EANALYSIS(esil)->iob.is_valid_offset(EANALYSIS(esil)->iob.io, addr, false)) {
|
||||
if (esil->iotrap) {
|
||||
esil->trap = RZ_ANALYSIS_TRAP_READ_ERR;
|
||||
esil->trap_code = addr;
|
||||
|
|
@ -216,14 +209,14 @@ static int internal_esil_mem_read(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int
|
|||
}
|
||||
|
||||
static int internal_esil_mem_read_no_null(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len) {
|
||||
rz_return_val_if_fail(esil && esil->analysis && esil->analysis->iob.io, 0);
|
||||
rz_return_val_if_fail(esil && EANALYSIS(esil) && EANALYSIS(esil)->iob.io, 0);
|
||||
|
||||
addr &= esil->addrmask;
|
||||
// TODO: Check if error return from read_at.(on previous version of r2 this call always return len)
|
||||
(void)esil->analysis->iob.read_at(esil->analysis->iob.io, addr, buf, len);
|
||||
(void)EANALYSIS(esil)->iob.read_at(EANALYSIS(esil)->iob.io, addr, buf, len);
|
||||
// check if request address is mapped , if don't fire trap and esil ioer callback
|
||||
// now with siol, read_at return true/false can't be used to check error vs len
|
||||
if (!esil->analysis->iob.is_valid_offset(esil->analysis->iob.io, addr, false)) {
|
||||
if (!EANALYSIS(esil)->iob.is_valid_offset(EANALYSIS(esil)->iob.io, addr, false)) {
|
||||
if (esil->iotrap) {
|
||||
esil->trap = RZ_ANALYSIS_TRAP_READ_ERR;
|
||||
esil->trap_code = addr;
|
||||
|
|
@ -253,7 +246,7 @@ RZ_API int rz_analysis_esil_mem_read(RzAnalysisEsil *esil, ut64 addr, ut8 *buf,
|
|||
|
||||
static int internal_esil_mem_write(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len) {
|
||||
int ret = 0;
|
||||
if (!esil || !esil->analysis || !esil->analysis->iob.io || esil->nowrite) {
|
||||
if (!esil || !EANALYSIS(esil) || !EANALYSIS(esil)->iob.io || esil->nowrite) {
|
||||
return 0;
|
||||
}
|
||||
addr &= esil->addrmask;
|
||||
|
|
@ -264,12 +257,12 @@ static int internal_esil_mem_write(RzAnalysisEsil *esil, ut64 addr, const ut8 *b
|
|||
}
|
||||
}
|
||||
}
|
||||
if (esil->analysis->iob.write_at(esil->analysis->iob.io, addr, buf, len)) {
|
||||
if (EANALYSIS(esil)->iob.write_at(EANALYSIS(esil)->iob.io, addr, buf, len)) {
|
||||
ret = len;
|
||||
}
|
||||
// check if request address is mapped , if don't fire trap and esil ioer callback
|
||||
// now with siol, write_at return true/false can't be used to check error vs len
|
||||
if (!esil->analysis->iob.is_valid_offset(esil->analysis->iob.io, addr, false)) {
|
||||
if (!EANALYSIS(esil)->iob.is_valid_offset(EANALYSIS(esil)->iob.io, addr, false)) {
|
||||
if (esil->iotrap) {
|
||||
esil->trap = RZ_ANALYSIS_TRAP_WRITE_ERR;
|
||||
esil->trap_code = addr;
|
||||
|
|
@ -283,19 +276,19 @@ static int internal_esil_mem_write(RzAnalysisEsil *esil, ut64 addr, const ut8 *b
|
|||
|
||||
static int internal_esil_mem_write_no_null(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len) {
|
||||
int ret = 0;
|
||||
if (!esil || !esil->analysis || !esil->analysis->iob.io || !addr) {
|
||||
if (!esil || !EANALYSIS(esil) || !EANALYSIS(esil)->iob.io || !addr) {
|
||||
return 0;
|
||||
}
|
||||
if (esil->nowrite) {
|
||||
return 0;
|
||||
}
|
||||
addr &= esil->addrmask;
|
||||
if (esil->analysis->iob.write_at(esil->analysis->iob.io, addr, buf, len)) {
|
||||
if (EANALYSIS(esil)->iob.write_at(EANALYSIS(esil)->iob.io, addr, buf, len)) {
|
||||
ret = len;
|
||||
}
|
||||
// check if request address is mapped , if don't fire trap and esil ioer callback
|
||||
// now with siol, write_at return true/false can't be used to check error vs len
|
||||
if (!esil->analysis->iob.is_valid_offset(esil->analysis->iob.io, addr, false)) {
|
||||
if (!EANALYSIS(esil)->iob.is_valid_offset(EANALYSIS(esil)->iob.io, addr, false)) {
|
||||
if (esil->iotrap) {
|
||||
esil->trap = RZ_ANALYSIS_TRAP_WRITE_ERR;
|
||||
esil->trap_code = addr;
|
||||
|
|
@ -318,13 +311,13 @@ RZ_API int rz_analysis_esil_mem_write(RzAnalysisEsil *esil, ut64 addr, const ut8
|
|||
}
|
||||
|
||||
static int internal_esil_reg_read(RzAnalysisEsil *esil, const char *regname, ut64 *num, int *size) {
|
||||
RzRegItem *reg = rz_reg_get(esil->analysis->reg, regname, -1);
|
||||
RzRegItem *reg = rz_reg_get(EANALYSIS(esil)->reg, regname, -1);
|
||||
if (reg) {
|
||||
if (size) {
|
||||
*size = reg->size;
|
||||
}
|
||||
if (num) {
|
||||
*num = rz_reg_get_value(esil->analysis->reg, reg);
|
||||
*num = rz_reg_get_value(EANALYSIS(esil)->reg, reg);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -332,10 +325,10 @@ static int internal_esil_reg_read(RzAnalysisEsil *esil, const char *regname, ut6
|
|||
}
|
||||
|
||||
static int internal_esil_reg_write(RzAnalysisEsil *esil, const char *regname, ut64 num) {
|
||||
if (esil && esil->analysis) {
|
||||
RzRegItem *reg = rz_reg_get(esil->analysis->reg, regname, -1);
|
||||
if (esil && EANALYSIS(esil)) {
|
||||
RzRegItem *reg = rz_reg_get(EANALYSIS(esil)->reg, regname, -1);
|
||||
if (reg) {
|
||||
rz_reg_set_value(esil->analysis->reg, reg, num);
|
||||
rz_reg_set_value(EANALYSIS(esil)->reg, reg, num);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -343,12 +336,12 @@ static int internal_esil_reg_write(RzAnalysisEsil *esil, const char *regname, ut
|
|||
}
|
||||
|
||||
static int internal_esil_reg_write_no_null(RzAnalysisEsil *esil, const char *regname, ut64 num) {
|
||||
rz_return_val_if_fail(esil && esil->analysis && esil->analysis->reg, false);
|
||||
rz_return_val_if_fail(esil && EANALYSIS(esil) && EANALYSIS(esil)->reg, false);
|
||||
|
||||
RzRegItem *reg = rz_reg_get(esil->analysis->reg, regname, -1);
|
||||
const char *pc = rz_reg_get_name(esil->analysis->reg, RZ_REG_NAME_PC);
|
||||
const char *sp = rz_reg_get_name(esil->analysis->reg, RZ_REG_NAME_SP);
|
||||
const char *bp = rz_reg_get_name(esil->analysis->reg, RZ_REG_NAME_BP);
|
||||
RzRegItem *reg = rz_reg_get(EANALYSIS(esil)->reg, regname, -1);
|
||||
const char *pc = rz_reg_get_name(EANALYSIS(esil)->reg, RZ_REG_NAME_PC);
|
||||
const char *sp = rz_reg_get_name(EANALYSIS(esil)->reg, RZ_REG_NAME_SP);
|
||||
const char *bp = rz_reg_get_name(EANALYSIS(esil)->reg, RZ_REG_NAME_BP);
|
||||
|
||||
if (!pc) {
|
||||
RZ_LOG_WARN("RzReg profile does not contain PC register\n");
|
||||
|
|
@ -363,7 +356,7 @@ static int internal_esil_reg_write_no_null(RzAnalysisEsil *esil, const char *reg
|
|||
return false;
|
||||
}
|
||||
if (reg && reg->name && ((strcmp(reg->name, pc) && strcmp(reg->name, sp) && strcmp(reg->name, bp)) || num)) { // I trust k-maps
|
||||
rz_reg_set_value(esil->analysis->reg, reg, num);
|
||||
rz_reg_set_value(EANALYSIS(esil)->reg, reg, num);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -410,7 +403,7 @@ RZ_API int rz_analysis_esil_get_parm_type(RzAnalysisEsil *esil, const char *str)
|
|||
}
|
||||
return RZ_ANALYSIS_ESIL_PARM_NUM;
|
||||
not_a_number:
|
||||
if (rz_reg_get(esil->analysis->reg, str, -1)) {
|
||||
if (rz_reg_get(EANALYSIS(esil)->reg, str, -1)) {
|
||||
return RZ_ANALYSIS_ESIL_PARM_REG;
|
||||
}
|
||||
return RZ_ANALYSIS_ESIL_PARM_INVALID;
|
||||
|
|
@ -428,7 +421,7 @@ RZ_API int rz_analysis_esil_get_parm_size(RzAnalysisEsil *esil, const char *str,
|
|||
case RZ_ANALYSIS_ESIL_PARM_NUM:
|
||||
*num = rz_num_get(NULL, str);
|
||||
if (size) {
|
||||
*size = esil->analysis->bits;
|
||||
*size = EANALYSIS(esil)->bits;
|
||||
}
|
||||
return true;
|
||||
case RZ_ANALYSIS_ESIL_PARM_REG:
|
||||
|
|
@ -479,7 +472,7 @@ RZ_API int rz_analysis_esil_reg_read(RzAnalysisEsil *esil, const char *regname,
|
|||
}
|
||||
*num = 0LL;
|
||||
if (size) {
|
||||
*size = esil->analysis->bits;
|
||||
*size = EANALYSIS(esil)->bits;
|
||||
}
|
||||
if (esil->cb.hook_reg_read) {
|
||||
ret = esil->cb.hook_reg_read(esil, regname, num, size);
|
||||
|
|
@ -688,8 +681,8 @@ static bool esil_js(RzAnalysisEsil *esil) {
|
|||
|
||||
// TODO: this should be deprecated because it is not accurate
|
||||
static bool esil_rs(RzAnalysisEsil *esil) {
|
||||
rz_return_val_if_fail(esil && esil->analysis, false);
|
||||
return rz_analysis_esil_pushnum(esil, esil->analysis->bits >> 3);
|
||||
rz_return_val_if_fail(esil && EANALYSIS(esil), false);
|
||||
return rz_analysis_esil_pushnum(esil, EANALYSIS(esil)->bits >> 3);
|
||||
}
|
||||
|
||||
// TODO: this should be deprecated because plugins should know their current address
|
||||
|
|
@ -699,7 +692,7 @@ static bool esil_address(RzAnalysisEsil *esil) {
|
|||
}
|
||||
|
||||
static bool esil_weak_eq(RzAnalysisEsil *esil) {
|
||||
rz_return_val_if_fail(esil && esil->analysis, false);
|
||||
rz_return_val_if_fail(esil && EANALYSIS(esil), false);
|
||||
char *dst = rz_analysis_esil_pop(esil);
|
||||
char *src = rz_analysis_esil_pop(esil);
|
||||
|
||||
|
|
@ -881,8 +874,8 @@ static bool esil_trap(RzAnalysisEsil *esil) {
|
|||
static bool esil_bits(RzAnalysisEsil *esil) {
|
||||
ut64 s;
|
||||
if (popRN(esil, &s)) {
|
||||
if (esil->analysis && esil->analysis->coreb.setab) {
|
||||
esil->analysis->coreb.setab(esil->analysis->coreb.core, NULL, s);
|
||||
if (EANALYSIS(esil) && EANALYSIS(esil)->coreb.setab) {
|
||||
EANALYSIS(esil)->coreb.setab(EANALYSIS(esil)->coreb.core, NULL, s);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -909,9 +902,9 @@ static bool esil_cmp(RzAnalysisEsil *esil) {
|
|||
esil->old = num;
|
||||
esil->cur = num - num2;
|
||||
ret = true;
|
||||
if (rz_reg_get(esil->analysis->reg, dst, -1)) {
|
||||
if (rz_reg_get(EANALYSIS(esil)->reg, dst, -1)) {
|
||||
esil->lastsz = esil_internal_sizeof_reg(esil, dst);
|
||||
} else if (rz_reg_get(esil->analysis->reg, src, -1)) {
|
||||
} else if (rz_reg_get(EANALYSIS(esil)->reg, src, -1)) {
|
||||
esil->lastsz = esil_internal_sizeof_reg(esil, src);
|
||||
} else {
|
||||
// default size is set to 64 as internally operands are ut64
|
||||
|
|
@ -1702,9 +1695,9 @@ static bool esil_poke_n(RzAnalysisEsil *esil, int bits) {
|
|||
if (bits == 128) {
|
||||
src2 = rz_analysis_esil_pop(esil);
|
||||
if (src2 && rz_analysis_esil_get_parm(esil, src2, &num2)) {
|
||||
rz_write_ble(b, num, esil->analysis->big_endian, 64);
|
||||
rz_write_ble(b, num, EANALYSIS(esil)->big_endian, 64);
|
||||
rz_analysis_esil_mem_write(esil, addr, b, bytes);
|
||||
rz_write_ble(b, num2, esil->analysis->big_endian, 64);
|
||||
rz_write_ble(b, num2, EANALYSIS(esil)->big_endian, 64);
|
||||
rz_analysis_esil_mem_write(esil, addr + 8, b, bytes);
|
||||
ret = true;
|
||||
goto out;
|
||||
|
|
@ -1718,12 +1711,12 @@ static bool esil_poke_n(RzAnalysisEsil *esil, int bits) {
|
|||
esil->cb.hook_mem_read = NULL;
|
||||
rz_analysis_esil_mem_read(esil, addr, b, bytes);
|
||||
esil->cb.hook_mem_read = oldhook;
|
||||
n = rz_read_ble64(b, esil->analysis->big_endian);
|
||||
n = rz_read_ble64(b, EANALYSIS(esil)->big_endian);
|
||||
esil->old = n;
|
||||
esil->cur = num;
|
||||
esil->lastsz = bits;
|
||||
num = num & bitmask;
|
||||
rz_write_ble(b, num, esil->analysis->big_endian, bits);
|
||||
rz_write_ble(b, num, EANALYSIS(esil)->big_endian, bits);
|
||||
rz_analysis_esil_mem_write(esil, addr, b, bytes);
|
||||
ret = true;
|
||||
}
|
||||
|
|
@ -1760,7 +1753,7 @@ static bool esil_poke16(RzAnalysisEsil *esil) {
|
|||
}
|
||||
|
||||
static bool esil_poke(RzAnalysisEsil *esil) {
|
||||
return esil_poke_n(esil, esil->analysis->bits);
|
||||
return esil_poke_n(esil, EANALYSIS(esil)->bits);
|
||||
}
|
||||
|
||||
static bool esil_poke_some(RzAnalysisEsil *esil) {
|
||||
|
|
@ -1788,7 +1781,7 @@ static bool esil_poke_some(RzAnalysisEsil *esil) {
|
|||
}
|
||||
rz_analysis_esil_get_parm_size(esil, foo, &tmp, ®size);
|
||||
isregornum(esil, foo, &num64);
|
||||
rz_write_ble(b, num64, esil->analysis->big_endian, regsize);
|
||||
rz_write_ble(b, num64, EANALYSIS(esil)->big_endian, regsize);
|
||||
const int size_bytes = regsize / 8;
|
||||
const ut32 written = rz_analysis_esil_mem_write(esil, ptr, b, size_bytes);
|
||||
if (written != size_bytes) {
|
||||
|
|
@ -1826,8 +1819,8 @@ static bool esil_peek_n(RzAnalysisEsil *esil, int bits) {
|
|||
if (bits == 128) {
|
||||
ut8 a[sizeof(ut64) * 2] = { 0 };
|
||||
rz_analysis_esil_mem_read(esil, addr, a, bytes);
|
||||
ut64 b = rz_read_ble(a, esil->analysis->big_endian, bits);
|
||||
ut64 c = rz_read_ble(a + 8, esil->analysis->big_endian, bits);
|
||||
ut64 b = rz_read_ble(a, EANALYSIS(esil)->big_endian, bits);
|
||||
ut64 c = rz_read_ble(a + 8, EANALYSIS(esil)->big_endian, bits);
|
||||
rz_strf(res, "0x%" PFMT64x, b);
|
||||
rz_analysis_esil_push(esil, res);
|
||||
rz_strf(res, "0x%" PFMT64x, c);
|
||||
|
|
@ -1838,7 +1831,7 @@ static bool esil_peek_n(RzAnalysisEsil *esil, int bits) {
|
|||
ut64 bitmask = genmask(bits - 1);
|
||||
ut8 a[sizeof(ut64)] = { 0 };
|
||||
rz_analysis_esil_mem_read(esil, addr, a, bytes);
|
||||
ut64 b = rz_read_ble(a, esil->analysis->big_endian, bits);
|
||||
ut64 b = rz_read_ble(a, EANALYSIS(esil)->big_endian, bits);
|
||||
rz_strf(res, "0x%" PFMT64x, b & bitmask);
|
||||
rz_analysis_esil_push(esil, res);
|
||||
esil->lastsz = bits;
|
||||
|
|
@ -1878,7 +1871,7 @@ static bool esil_stack(RzAnalysisEsil *esil) {
|
|||
}
|
||||
|
||||
static bool esil_peek(RzAnalysisEsil *esil) {
|
||||
return esil_peek_n(esil, esil->analysis->bits);
|
||||
return esil_peek_n(esil, EANALYSIS(esil)->bits);
|
||||
};
|
||||
|
||||
static bool esil_peek_some(RzAnalysisEsil *esil) {
|
||||
|
|
@ -1905,7 +1898,7 @@ static bool esil_peek_some(RzAnalysisEsil *esil) {
|
|||
}
|
||||
const ut32 read = rz_analysis_esil_mem_read(esil, ptr, a, 4);
|
||||
if (read == 4) { // this is highly questionabla
|
||||
num32 = rz_read_ble32(a, esil->analysis->big_endian);
|
||||
num32 = rz_read_ble32(a, EANALYSIS(esil)->big_endian);
|
||||
rz_analysis_esil_reg_write(esil, foo, num32);
|
||||
} else {
|
||||
ESIL_LOG("Cannot peek from 0x%08" PFMT64x "\n", ptr);
|
||||
|
|
@ -1966,7 +1959,7 @@ static bool esil_mem_oreq8(RzAnalysisEsil *esil) {
|
|||
return esil_mem_oreq_n(esil, 64);
|
||||
}
|
||||
static bool esil_mem_oreq(RzAnalysisEsil *esil) {
|
||||
return esil_mem_oreq_n(esil, esil->analysis->bits);
|
||||
return esil_mem_oreq_n(esil, EANALYSIS(esil)->bits);
|
||||
}
|
||||
|
||||
/* XOREQ */
|
||||
|
|
@ -2012,7 +2005,7 @@ static bool esil_mem_xoreq8(RzAnalysisEsil *esil) {
|
|||
return esil_mem_xoreq_n(esil, 64);
|
||||
}
|
||||
static bool esil_mem_xoreq(RzAnalysisEsil *esil) {
|
||||
return esil_mem_xoreq_n(esil, esil->analysis->bits);
|
||||
return esil_mem_xoreq_n(esil, EANALYSIS(esil)->bits);
|
||||
}
|
||||
|
||||
/* ANDEQ */
|
||||
|
|
@ -2058,7 +2051,7 @@ static bool esil_mem_andeq8(RzAnalysisEsil *esil) {
|
|||
return esil_mem_andeq_n(esil, 64);
|
||||
}
|
||||
static bool esil_mem_andeq(RzAnalysisEsil *esil) {
|
||||
return esil_mem_andeq_n(esil, esil->analysis->bits);
|
||||
return esil_mem_andeq_n(esil, EANALYSIS(esil)->bits);
|
||||
}
|
||||
|
||||
/* ADDEQ */
|
||||
|
|
@ -2104,7 +2097,7 @@ static bool esil_mem_addeq8(RzAnalysisEsil *esil) {
|
|||
return esil_mem_addeq_n(esil, 64);
|
||||
}
|
||||
static bool esil_mem_addeq(RzAnalysisEsil *esil) {
|
||||
return esil_mem_addeq_n(esil, esil->analysis->bits);
|
||||
return esil_mem_addeq_n(esil, EANALYSIS(esil)->bits);
|
||||
}
|
||||
|
||||
/* SUBEQ */
|
||||
|
|
@ -2150,7 +2143,7 @@ static bool esil_mem_subeq8(RzAnalysisEsil *esil) {
|
|||
return esil_mem_subeq_n(esil, 64);
|
||||
}
|
||||
static bool esil_mem_subeq(RzAnalysisEsil *esil) {
|
||||
return esil_mem_subeq_n(esil, esil->analysis->bits);
|
||||
return esil_mem_subeq_n(esil, EANALYSIS(esil)->bits);
|
||||
}
|
||||
|
||||
/* MODEQ */
|
||||
|
|
@ -2203,7 +2196,7 @@ static bool esil_mem_modeq8(RzAnalysisEsil *esil) {
|
|||
return esil_mem_modeq_n(esil, 64);
|
||||
}
|
||||
static bool esil_mem_modeq(RzAnalysisEsil *esil) {
|
||||
return esil_mem_modeq_n(esil, esil->analysis->bits);
|
||||
return esil_mem_modeq_n(esil, EANALYSIS(esil)->bits);
|
||||
}
|
||||
|
||||
/* DIVEQ */
|
||||
|
|
@ -2255,7 +2248,7 @@ static bool esil_mem_diveq8(RzAnalysisEsil *esil) {
|
|||
return esil_mem_diveq_n(esil, 64);
|
||||
}
|
||||
static bool esil_mem_diveq(RzAnalysisEsil *esil) {
|
||||
return esil_mem_diveq_n(esil, esil->analysis->bits);
|
||||
return esil_mem_diveq_n(esil, EANALYSIS(esil)->bits);
|
||||
}
|
||||
|
||||
/* MULEQ */
|
||||
|
|
@ -2302,7 +2295,7 @@ static bool esil_mem_muleq8(RzAnalysisEsil *esil) {
|
|||
}
|
||||
|
||||
static bool esil_mem_muleq(RzAnalysisEsil *esil) {
|
||||
switch (esil->analysis->bits) {
|
||||
switch (EANALYSIS(esil)->bits) {
|
||||
case 64: return esil_mem_muleq8(esil);
|
||||
case 32: return esil_mem_muleq4(esil);
|
||||
case 16: return esil_mem_muleq2(esil);
|
||||
|
|
@ -2355,7 +2348,7 @@ static bool esil_mem_inceq8(RzAnalysisEsil *esil) {
|
|||
return esil_mem_inceq_n(esil, 64);
|
||||
}
|
||||
static bool esil_mem_inceq(RzAnalysisEsil *esil) {
|
||||
return esil_mem_inceq_n(esil, esil->analysis->bits);
|
||||
return esil_mem_inceq_n(esil, EANALYSIS(esil)->bits);
|
||||
}
|
||||
|
||||
/* DECEQ */
|
||||
|
|
@ -2399,7 +2392,7 @@ static bool esil_mem_deceq8(RzAnalysisEsil *esil) {
|
|||
return esil_mem_deceq_n(esil, 64);
|
||||
}
|
||||
static bool esil_mem_deceq(RzAnalysisEsil *esil) {
|
||||
return esil_mem_deceq_n(esil, esil->analysis->bits);
|
||||
return esil_mem_deceq_n(esil, EANALYSIS(esil)->bits);
|
||||
}
|
||||
|
||||
/* LSLEQ */
|
||||
|
|
@ -2453,7 +2446,7 @@ static bool esil_mem_lsleq8(RzAnalysisEsil *esil) {
|
|||
return esil_mem_lsleq_n(esil, 64);
|
||||
}
|
||||
static bool esil_mem_lsleq(RzAnalysisEsil *esil) {
|
||||
return esil_mem_lsleq_n(esil, esil->analysis->bits);
|
||||
return esil_mem_lsleq_n(esil, EANALYSIS(esil)->bits);
|
||||
}
|
||||
|
||||
/* LSREQ */
|
||||
|
|
@ -2499,7 +2492,7 @@ static bool esil_mem_lsreq8(RzAnalysisEsil *esil) {
|
|||
return esil_mem_lsreq_n(esil, 64);
|
||||
}
|
||||
static bool esil_mem_lsreq(RzAnalysisEsil *esil) {
|
||||
return esil_mem_lsreq_n(esil, esil->analysis->bits);
|
||||
return esil_mem_lsreq_n(esil, EANALYSIS(esil)->bits);
|
||||
}
|
||||
|
||||
/* get value of register or memory reference and push the value */
|
||||
|
|
@ -2582,9 +2575,9 @@ static bool esil_smaller(RzAnalysisEsil *esil) { // 'dst < src' => 'src,dst,<'
|
|||
esil->old = num;
|
||||
esil->cur = num - num2;
|
||||
ret = true;
|
||||
if (rz_reg_get(esil->analysis->reg, dst, -1)) {
|
||||
if (rz_reg_get(EANALYSIS(esil)->reg, dst, -1)) {
|
||||
esil->lastsz = esil_internal_sizeof_reg(esil, dst);
|
||||
} else if (rz_reg_get(esil->analysis->reg, src, -1)) {
|
||||
} else if (rz_reg_get(EANALYSIS(esil)->reg, src, -1)) {
|
||||
esil->lastsz = esil_internal_sizeof_reg(esil, src);
|
||||
} else {
|
||||
// default size is set to 64 as internally operands are ut64
|
||||
|
|
@ -2608,9 +2601,9 @@ static bool esil_bigger(RzAnalysisEsil *esil) { // 'dst > src' => 'src,dst,>'
|
|||
esil->old = num;
|
||||
esil->cur = num - num2;
|
||||
ret = true;
|
||||
if (rz_reg_get(esil->analysis->reg, dst, -1)) {
|
||||
if (rz_reg_get(EANALYSIS(esil)->reg, dst, -1)) {
|
||||
esil->lastsz = esil_internal_sizeof_reg(esil, dst);
|
||||
} else if (rz_reg_get(esil->analysis->reg, src, -1)) {
|
||||
} else if (rz_reg_get(EANALYSIS(esil)->reg, src, -1)) {
|
||||
esil->lastsz = esil_internal_sizeof_reg(esil, src);
|
||||
} else {
|
||||
// default size is set to 64 as internally operands are ut64
|
||||
|
|
@ -2634,9 +2627,9 @@ static bool esil_smaller_equal(RzAnalysisEsil *esil) { // 'dst <= src' => 'src,d
|
|||
esil->old = num;
|
||||
esil->cur = num - num2;
|
||||
ret = true;
|
||||
if (rz_reg_get(esil->analysis->reg, dst, -1)) {
|
||||
if (rz_reg_get(EANALYSIS(esil)->reg, dst, -1)) {
|
||||
esil->lastsz = esil_internal_sizeof_reg(esil, dst);
|
||||
} else if (rz_reg_get(esil->analysis->reg, src, -1)) {
|
||||
} else if (rz_reg_get(EANALYSIS(esil)->reg, src, -1)) {
|
||||
esil->lastsz = esil_internal_sizeof_reg(esil, src);
|
||||
} else {
|
||||
// default size is set to 64 as internally operands are ut64
|
||||
|
|
@ -2660,9 +2653,9 @@ static bool esil_bigger_equal(RzAnalysisEsil *esil) { // 'dst >= src' => 'src,ds
|
|||
esil->old = num;
|
||||
esil->cur = num - num2;
|
||||
ret = true;
|
||||
if (rz_reg_get(esil->analysis->reg, dst, -1)) {
|
||||
if (rz_reg_get(EANALYSIS(esil)->reg, dst, -1)) {
|
||||
esil->lastsz = esil_internal_sizeof_reg(esil, dst);
|
||||
} else if (rz_reg_get(esil->analysis->reg, src, -1)) {
|
||||
} else if (rz_reg_get(EANALYSIS(esil)->reg, src, -1)) {
|
||||
esil->lastsz = esil_internal_sizeof_reg(esil, src);
|
||||
} else {
|
||||
// default size is set to 64 as internally operands are ut64
|
||||
|
|
@ -2889,8 +2882,8 @@ repeat:
|
|||
wordi = 0;
|
||||
while (*str) {
|
||||
if (str == hashbang) {
|
||||
if (esil->analysis && esil->analysis->coreb.setab) {
|
||||
esil->analysis->coreb.cmd(esil->analysis->coreb.core, str + 2);
|
||||
if (EANALYSIS(esil) && EANALYSIS(esil)->coreb.setab) {
|
||||
EANALYSIS(esil)->coreb.cmd(EANALYSIS(esil)->coreb.core, str + 2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -3158,11 +3151,11 @@ static void rz_analysis_esil_setup_ops(RzAnalysisEsil *esil) {
|
|||
}
|
||||
|
||||
/* register callbacks using this analysis module. */
|
||||
RZ_API bool rz_analysis_esil_setup(RzAnalysisEsil *esil, RzAnalysis *analysis, int romem, int stats, int nonull, RzCore *core) {
|
||||
RZ_API bool rz_analysis_esil_setup(RzAnalysisEsil *esil, void /*RzAnalysis*/ *panalysis, int romem, int stats, int nonull, void /*RzCore*/ *pcore) {
|
||||
rz_return_val_if_fail(esil, false);
|
||||
// esil->debug = 0;
|
||||
esil->core = core;
|
||||
esil->analysis = analysis;
|
||||
|
||||
esil->pcore = pcore;
|
||||
esil->panalysis = panalysis;
|
||||
esil->parse_goto_count = RZ_ANALYSIS_ESIL_GOTO_LIMIT;
|
||||
esil->trap = 0;
|
||||
esil->trap_code = 0;
|
||||
|
|
@ -3187,7 +3180,9 @@ RZ_API bool rz_analysis_esil_setup(RzAnalysisEsil *esil, RzAnalysis *analysis, i
|
|||
rz_analysis_esil_stats(esil, stats);
|
||||
rz_analysis_esil_setup_ops(esil);
|
||||
|
||||
return (analysis->cur && analysis->cur->esil_init)
|
||||
? analysis->cur->esil_init(esil)
|
||||
: true;
|
||||
RzAnalysis *analysis = panalysis;
|
||||
if (analysis->cur && analysis->cur->esil_init) {
|
||||
return analysis->cur->esil_init(esil);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
// SPDX-FileCopyrightText: 2018 condret <condr3t@protonmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_esil/rz_esil.h>
|
||||
#include "analysis_private.h"
|
||||
#include <rz_util.h>
|
||||
#include <rz_lib.h>
|
||||
|
||||
static void interrupt_free(RzAnalysisEsilInterrupt *i) {
|
||||
rz_analysis_esil_interrupt_free(i->esil, i);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
// SPDX-FileCopyrightText: 2018 condret <condr3t@protonmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_esil/rz_esil.h>
|
||||
#include "analysis_private.h"
|
||||
#include <rz_util.h>
|
||||
#include <rz_lib.h>
|
||||
|
||||
RZ_API void rz_analysis_esil_sources_init(RzAnalysisEsil *esil) {
|
||||
if (esil && !esil->sources) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-FileCopyrightText: 2014 pancake <pancake@nopcode.org>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_esil/rz_esil.h>
|
||||
#include "analysis_private.h"
|
||||
|
||||
static int hook_flag_read(RzAnalysisEsil *esil, const char *flag, ut64 *num) {
|
||||
|
|
|
|||
|
|
@ -2,13 +2,12 @@
|
|||
// SPDX-FileCopyrightText: 2015-2020 rkx1209 <rkx1209dev@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_esil/rz_esil.h>
|
||||
#include "analysis_private.h"
|
||||
|
||||
#define CMP_REG_CHANGE(x, y) ((x) - ((RzAnalysisEsilRegChange *)(y))->idx)
|
||||
#define CMP_MEM_CHANGE(x, y) ((x) - ((RzAnalysisEsilMemChange *)(y))->idx)
|
||||
|
||||
#define ESILISTATE esil->analysis->esilinterstate
|
||||
|
||||
// IL trace wrapper of esil
|
||||
static inline bool esil_add_mem_trace(RzAnalysisEsilTrace *etrace, RzILTraceMemOp *mem) {
|
||||
RzILTraceInstruction *instr_trace = rz_analysis_esil_get_instruction_trace(etrace, etrace->idx);
|
||||
|
|
@ -22,6 +21,7 @@ static inline bool esil_add_reg_trace(RzAnalysisEsilTrace *etrace, RzILTraceRegO
|
|||
|
||||
RZ_API RzAnalysisEsilTrace *rz_analysis_esil_trace_new(RzAnalysisEsil *esil) {
|
||||
rz_return_val_if_fail(esil && esil->stack_addr && esil->stack_size, NULL);
|
||||
RzAnalysis *analysis = esil->panalysis;
|
||||
size_t i;
|
||||
RzAnalysisEsilTrace *trace = RZ_NEW0(RzAnalysisEsilTrace);
|
||||
if (!trace) {
|
||||
|
|
@ -50,11 +50,10 @@ RZ_API RzAnalysisEsilTrace *rz_analysis_esil_trace_new(RzAnalysisEsil *esil) {
|
|||
RZ_LOG_ERROR("esil: Cannot allocate stack for trace\n");
|
||||
goto error;
|
||||
}
|
||||
esil->analysis->iob.read_at(esil->analysis->iob.io, trace->stack_addr,
|
||||
trace->stack_data, trace->stack_size);
|
||||
analysis->iob.read_at(analysis->iob.io, trace->stack_addr, trace->stack_data, trace->stack_size);
|
||||
// Save initial registers arenas
|
||||
for (i = 0; i < RZ_REG_TYPE_LAST; i++) {
|
||||
RzRegArena *a = esil->analysis->reg->regset[i].arena;
|
||||
RzRegArena *a = analysis->reg->regset[i].arena;
|
||||
RzRegArena *b = rz_reg_arena_new(a->size);
|
||||
if (!b) {
|
||||
RZ_LOG_ERROR("esil: Cannot allocate register arena for trace\n");
|
||||
|
|
@ -122,23 +121,24 @@ static int trace_hook_reg_read(RzAnalysisEsil *esil, const char *name, ut64 *res
|
|||
// RZ_LOG_WARN("Register not found in profile\n");
|
||||
return 0;
|
||||
}
|
||||
if (ESILISTATE->callbacks.hook_reg_read) {
|
||||
if (esil->esilinterstate->callbacks.hook_reg_read) {
|
||||
RzAnalysisEsilCallbacks cbs = esil->cb;
|
||||
esil->cb = ESILISTATE->callbacks;
|
||||
ret = ESILISTATE->callbacks.hook_reg_read(esil, name, res, size);
|
||||
esil->cb = esil->esilinterstate->callbacks;
|
||||
ret = esil->esilinterstate->callbacks.hook_reg_read(esil, name, res, size);
|
||||
esil->cb = cbs;
|
||||
}
|
||||
if (!ret && esil->cb.reg_read) {
|
||||
ret = esil->cb.reg_read(esil, name, res, size);
|
||||
}
|
||||
if (ret) {
|
||||
RzAnalysis *analysis = esil->panalysis;
|
||||
// Trace reg read behavior
|
||||
RzILTraceRegOp *reg_read = RZ_NEW0(RzILTraceRegOp);
|
||||
if (!reg_read) {
|
||||
RZ_LOG_ERROR("failed to init reg read trace\n");
|
||||
return 0;
|
||||
}
|
||||
reg_read->reg_name = rz_str_constpool_get(&esil->analysis->constpool, name);
|
||||
reg_read->reg_name = rz_str_constpool_get(&analysis->constpool, name);
|
||||
reg_read->behavior = RZ_IL_TRACE_OP_READ;
|
||||
reg_read->value = *res;
|
||||
if (!esil_add_reg_trace(esil->trace, reg_read)) {
|
||||
|
|
@ -150,6 +150,7 @@ static int trace_hook_reg_read(RzAnalysisEsil *esil, const char *name, ut64 *res
|
|||
|
||||
static int trace_hook_reg_write(RzAnalysisEsil *esil, const char *name, ut64 *val) {
|
||||
int ret = 0;
|
||||
RzAnalysis *analysis = esil->panalysis;
|
||||
|
||||
// add reg write to trace
|
||||
RzILTraceRegOp *reg_write = RZ_NEW0(RzILTraceRegOp);
|
||||
|
|
@ -157,19 +158,19 @@ static int trace_hook_reg_write(RzAnalysisEsil *esil, const char *name, ut64 *va
|
|||
RZ_LOG_ERROR("failed to init reg write\n");
|
||||
return ret;
|
||||
}
|
||||
reg_write->reg_name = rz_str_constpool_get(&esil->analysis->constpool, name);
|
||||
reg_write->reg_name = rz_str_constpool_get(&analysis->constpool, name);
|
||||
reg_write->behavior = RZ_IL_TRACE_OP_WRITE;
|
||||
reg_write->value = *val;
|
||||
if (!esil_add_reg_trace(esil->trace, reg_write)) {
|
||||
RZ_FREE(reg_write);
|
||||
}
|
||||
|
||||
RzRegItem *ri = rz_reg_get(esil->analysis->reg, name, -1);
|
||||
RzRegItem *ri = rz_reg_get(analysis->reg, name, -1);
|
||||
add_reg_change(esil->trace, esil->trace->idx + 1, ri, *val);
|
||||
if (ESILISTATE->callbacks.hook_reg_write) {
|
||||
if (esil->esilinterstate->callbacks.hook_reg_write) {
|
||||
RzAnalysisEsilCallbacks cbs = esil->cb;
|
||||
esil->cb = ESILISTATE->callbacks;
|
||||
ret = ESILISTATE->callbacks.hook_reg_write(esil, name, val);
|
||||
esil->cb = esil->esilinterstate->callbacks;
|
||||
ret = esil->esilinterstate->callbacks.hook_reg_write(esil, name, val);
|
||||
esil->cb = cbs;
|
||||
}
|
||||
return ret;
|
||||
|
|
@ -202,10 +203,10 @@ static int trace_hook_mem_read(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int le
|
|||
RZ_FREE(mem_read);
|
||||
}
|
||||
|
||||
if (ESILISTATE->callbacks.hook_mem_read) {
|
||||
if (esil->esilinterstate->callbacks.hook_mem_read) {
|
||||
RzAnalysisEsilCallbacks cbs = esil->cb;
|
||||
esil->cb = ESILISTATE->callbacks;
|
||||
ret = ESILISTATE->callbacks.hook_mem_read(esil, addr, buf, len);
|
||||
esil->cb = esil->esilinterstate->callbacks;
|
||||
ret = esil->esilinterstate->callbacks.hook_mem_read(esil, addr, buf, len);
|
||||
esil->cb = cbs;
|
||||
}
|
||||
return ret;
|
||||
|
|
@ -240,10 +241,10 @@ static int trace_hook_mem_write(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf,
|
|||
add_mem_change(esil->trace, esil->trace->idx + 1, addr + i, buf[i]);
|
||||
}
|
||||
|
||||
if (ESILISTATE->callbacks.hook_mem_write) {
|
||||
if (esil->esilinterstate->callbacks.hook_mem_write) {
|
||||
RzAnalysisEsilCallbacks cbs = esil->cb;
|
||||
esil->cb = ESILISTATE->callbacks;
|
||||
ret = ESILISTATE->callbacks.hook_mem_write(esil, addr, buf, len);
|
||||
esil->cb = esil->esilinterstate->callbacks;
|
||||
ret = esil->esilinterstate->callbacks.hook_mem_write(esil, addr, buf, len);
|
||||
esil->cb = cbs;
|
||||
}
|
||||
return ret;
|
||||
|
|
@ -255,7 +256,7 @@ static int trace_hook_mem_write(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf,
|
|||
* \param idx int, index of instruction
|
||||
* \return RzILTraceInstruction *, instruction trace at index
|
||||
*/
|
||||
RZ_API RZ_BORROW RzILTraceInstruction *rz_analysis_esil_get_instruction_trace(RZ_NONNULL RzAnalysisEsilTrace *etrace, int idx) {
|
||||
RZ_API RZ_BORROW void /*RzILTraceInstruction*/ *rz_analysis_esil_get_instruction_trace(RZ_NONNULL RzAnalysisEsilTrace *etrace, int idx) {
|
||||
rz_return_val_if_fail(etrace, NULL);
|
||||
if (idx < 0 || idx >= rz_pvector_len(etrace->instructions)) {
|
||||
return NULL;
|
||||
|
|
@ -263,10 +264,9 @@ RZ_API RZ_BORROW RzILTraceInstruction *rz_analysis_esil_get_instruction_trace(RZ
|
|||
return rz_pvector_at(etrace->instructions, idx);
|
||||
}
|
||||
|
||||
RZ_API void rz_analysis_esil_trace_op(RzAnalysisEsil *esil, RZ_NONNULL RzAnalysisOp *op) {
|
||||
rz_return_if_fail(esil && op);
|
||||
const char *expr = rz_strbuf_get(&op->esil);
|
||||
if (RZ_STR_ISEMPTY(expr)) {
|
||||
RZ_API void rz_analysis_esil_trace_op(RzAnalysisEsil *esil, ut64 pc, RZ_NULLABLE const char *esil_expr) {
|
||||
rz_return_if_fail(esil);
|
||||
if (RZ_STR_ISEMPTY(esil_expr)) {
|
||||
// do nothing
|
||||
return;
|
||||
}
|
||||
|
|
@ -283,17 +283,18 @@ RZ_API void rz_analysis_esil_trace_op(RzAnalysisEsil *esil, RZ_NONNULL RzAnalysi
|
|||
}
|
||||
/* save old callbacks */
|
||||
int esil_verbose = esil->verbose;
|
||||
if (ESILISTATE->callbacks_set) {
|
||||
if (esil->esilinterstate->callbacks_set) {
|
||||
RZ_LOG_ERROR("esil: Cannot call recursively\n");
|
||||
}
|
||||
ESILISTATE->callbacks = esil->cb;
|
||||
ESILISTATE->callbacks_set = true;
|
||||
esil->esilinterstate->callbacks = esil->cb;
|
||||
esil->esilinterstate->callbacks_set = true;
|
||||
|
||||
RzILTraceInstruction *instruction = rz_analysis_il_trace_instruction_new(op->addr);
|
||||
RzILTraceInstruction *instruction = rz_analysis_il_trace_instruction_new(pc);
|
||||
rz_pvector_push(esil->trace->instructions, instruction);
|
||||
|
||||
RzRegItem *pc_ri = rz_reg_get(esil->analysis->reg, "PC", -1);
|
||||
add_reg_change(esil->trace, esil->trace->idx, pc_ri, op->addr);
|
||||
RzAnalysis *analysis = esil->panalysis;
|
||||
RzRegItem *pc_ri = rz_reg_get(analysis->reg, "PC", -1);
|
||||
add_reg_change(esil->trace, esil->trace->idx, pc_ri, pc);
|
||||
/* set hooks */
|
||||
esil->verbose = 0;
|
||||
esil->cb.hook_reg_read = trace_hook_reg_read;
|
||||
|
|
@ -302,11 +303,11 @@ RZ_API void rz_analysis_esil_trace_op(RzAnalysisEsil *esil, RZ_NONNULL RzAnalysi
|
|||
esil->cb.hook_mem_write = trace_hook_mem_write;
|
||||
|
||||
/* evaluate esil expression */
|
||||
rz_analysis_esil_parse(esil, expr);
|
||||
rz_analysis_esil_parse(esil, esil_expr);
|
||||
rz_analysis_esil_stack_free(esil);
|
||||
/* restore hooks */
|
||||
esil->cb = ESILISTATE->callbacks;
|
||||
ESILISTATE->callbacks_set = false;
|
||||
esil->cb = esil->esilinterstate->callbacks;
|
||||
esil->esilinterstate->callbacks_set = false;
|
||||
esil->verbose = esil_verbose;
|
||||
/* increment idx */
|
||||
esil->trace->idx++;
|
||||
|
|
@ -320,8 +321,9 @@ static bool restore_memory_cb(void *user, const ut64 key, const void *value) {
|
|||
|
||||
rz_vector_upper_bound(vmem, esil->trace->idx, index, CMP_MEM_CHANGE);
|
||||
if (index > 0 && index <= vmem->len) {
|
||||
RzAnalysis *analysis = esil->panalysis;
|
||||
RzAnalysisEsilMemChange *c = rz_vector_index_ptr(vmem, index - 1);
|
||||
esil->analysis->iob.write_at(esil->analysis->iob.io, key, &c->data, 1);
|
||||
analysis->iob.write_at(analysis->iob.io, key, &c->data, 1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -332,8 +334,9 @@ static bool restore_register(RzAnalysisEsil *esil, RzRegItem *ri, int idx) {
|
|||
if (vreg) {
|
||||
rz_vector_upper_bound(vreg, idx, index, CMP_REG_CHANGE);
|
||||
if (index > 0 && index <= vreg->len) {
|
||||
RzAnalysis *analysis = esil->panalysis;
|
||||
RzAnalysisEsilRegChange *c = rz_vector_index_ptr(vreg, index - 1);
|
||||
rz_reg_set_value(esil->analysis->reg, ri, c->data);
|
||||
rz_reg_set_value(analysis->reg, ri, c->data);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
@ -342,26 +345,27 @@ static bool restore_register(RzAnalysisEsil *esil, RzRegItem *ri, int idx) {
|
|||
RZ_API void rz_analysis_esil_trace_restore(RzAnalysisEsil *esil, int idx) {
|
||||
rz_return_if_fail(esil);
|
||||
size_t i;
|
||||
RzAnalysis *analysis = esil->panalysis;
|
||||
RzAnalysisEsilTrace *trace = esil->trace;
|
||||
// Restore initial state when going backward
|
||||
if (idx < esil->trace->idx) {
|
||||
// Restore initial registers value
|
||||
for (i = 0; i < RZ_REG_TYPE_LAST; i++) {
|
||||
RzRegArena *a = esil->analysis->reg->regset[i].arena;
|
||||
RzRegArena *a = analysis->reg->regset[i].arena;
|
||||
RzRegArena *b = trace->arena[i];
|
||||
if (a && b) {
|
||||
memcpy(a->bytes, b->bytes, a->size);
|
||||
}
|
||||
}
|
||||
// Restore initial stack memory
|
||||
esil->analysis->iob.write_at(esil->analysis->iob.io, trace->stack_addr,
|
||||
analysis->iob.write_at(analysis->iob.io, trace->stack_addr,
|
||||
trace->stack_data, trace->stack_size);
|
||||
}
|
||||
// Apply latest changes to registers and memory
|
||||
esil->trace->idx = idx;
|
||||
RzListIter *iter;
|
||||
RzRegItem *ri;
|
||||
rz_list_foreach (esil->analysis->reg->allregs, iter, ri) {
|
||||
rz_list_foreach (analysis->reg->allregs, iter, ri) {
|
||||
restore_register(esil, ri, idx);
|
||||
}
|
||||
ht_up_foreach(trace->memory, restore_memory_cb, esil);
|
||||
|
|
|
|||
|
|
@ -17,10 +17,10 @@
|
|||
* \param rzil RZ_IL instance
|
||||
* \return pointer to RzilTrace
|
||||
*/
|
||||
RZ_API RzAnalysisRzilTrace *rz_analysis_rzil_trace_new(RzAnalysis *analysis, RZ_NONNULL RzAnalysisILVM *rzil) {
|
||||
RZ_API RzAnalysisILTrace *rz_analysis_il_trace_new(RzAnalysis *analysis, RZ_NONNULL RzAnalysisILVM *rzil) {
|
||||
rz_return_val_if_fail(rzil, NULL);
|
||||
size_t i;
|
||||
RzAnalysisEsilTrace *trace = RZ_NEW0(RzAnalysisEsilTrace);
|
||||
RzAnalysisILTrace *trace = RZ_NEW0(RzAnalysisILTrace);
|
||||
if (!trace) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -59,7 +59,7 @@ RZ_API RzAnalysisRzilTrace *rz_analysis_rzil_trace_new(RzAnalysis *analysis, RZ_
|
|||
}
|
||||
return trace;
|
||||
error:
|
||||
rz_analysis_esil_trace_free(trace);
|
||||
rz_analysis_il_trace_free(trace);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ error:
|
|||
* Free an IL trace
|
||||
* \param trace trace to be free
|
||||
*/
|
||||
RZ_API void rz_analysis_rzil_trace_free(RzAnalysisEsilTrace *trace) {
|
||||
RZ_API void rz_analysis_il_trace_free(RzAnalysisILTrace *trace) {
|
||||
size_t i;
|
||||
if (!trace) {
|
||||
return;
|
||||
|
|
@ -90,6 +90,6 @@ RZ_API void rz_analysis_rzil_trace_free(RzAnalysisEsilTrace *trace) {
|
|||
* \param rzil IL instance
|
||||
* \param op RzAnalysisRzilOp, a general IL op structure (Designed for switching between different implementations of IL op struct)
|
||||
*/
|
||||
RZ_API void rz_analysis_rzil_trace_op(RzAnalysis *analysis, RZ_NONNULL RzAnalysisILVM *rzil, RZ_NONNULL RzAnalysisLiftedILOp op) {
|
||||
RZ_API void rz_analysis_il_trace_op(RzAnalysis *analysis, RZ_NONNULL RzAnalysisILVM *rzil, RZ_NONNULL RzAnalysisLiftedILOp op) {
|
||||
// TODO : rewrite this file when migrate to new op structure
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1405,9 +1405,10 @@ static OPCODE_DESC *avr_op_analyze(RzAnalysis *analysis, RzAnalysisOp *op, ut64
|
|||
}
|
||||
|
||||
static bool avr_custom_des(RzAnalysisEsil *esil) {
|
||||
if (!esil || !esil->analysis || !esil->analysis->reg) {
|
||||
if (!esil) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ut64 arg;
|
||||
if (!__esil_pop_argument(esil, &arg)) {
|
||||
return false;
|
||||
|
|
@ -1487,9 +1488,10 @@ static bool avr_custom_spm_page_erase(RzAnalysisEsil *esil) {
|
|||
ut64 addr, page_size_bits, i;
|
||||
|
||||
// sanity check
|
||||
if (!esil || !esil->analysis || !esil->analysis->reg) {
|
||||
if (!esil || !esil->panalysis) {
|
||||
return false;
|
||||
}
|
||||
RzAnalysis *analysis = esil->panalysis;
|
||||
|
||||
// get target address
|
||||
if (!__esil_pop_argument(esil, &addr)) {
|
||||
|
|
@ -1497,7 +1499,7 @@ static bool avr_custom_spm_page_erase(RzAnalysisEsil *esil) {
|
|||
}
|
||||
|
||||
// get details about current MCU and fix input address
|
||||
cpu = get_cpu_model(esil->analysis->cpu);
|
||||
cpu = get_cpu_model(analysis->cpu);
|
||||
page_size_bits = const_get_value(const_by_name(cpu, CPU_CONST_PARAM, "page_size"));
|
||||
|
||||
// align base address to page_size_bits
|
||||
|
|
@ -1521,9 +1523,10 @@ static bool avr_custom_spm_page_fill(RzAnalysisEsil *esil) {
|
|||
ut8 r0, r1;
|
||||
|
||||
// sanity check
|
||||
if (!esil || !esil->analysis || !esil->analysis->reg) {
|
||||
if (!esil || !esil->panalysis) {
|
||||
return false;
|
||||
}
|
||||
RzAnalysis *analysis = esil->panalysis;
|
||||
|
||||
// get target address, r0, r1
|
||||
if (!__esil_pop_argument(esil, &addr)) {
|
||||
|
|
@ -1541,7 +1544,7 @@ static bool avr_custom_spm_page_fill(RzAnalysisEsil *esil) {
|
|||
r1 = i;
|
||||
|
||||
// get details about current MCU and fix input address
|
||||
cpu = get_cpu_model(esil->analysis->cpu);
|
||||
cpu = get_cpu_model(analysis->cpu);
|
||||
page_size_bits = const_get_value(const_by_name(cpu, CPU_CONST_PARAM, "page_size"));
|
||||
|
||||
// align and crop base address
|
||||
|
|
@ -1562,9 +1565,10 @@ static bool avr_custom_spm_page_write(RzAnalysisEsil *esil) {
|
|||
ut64 addr, page_size_bits, tmp_page;
|
||||
|
||||
// sanity check
|
||||
if (!esil || !esil->analysis || !esil->analysis->reg) {
|
||||
if (!esil || !esil->panalysis) {
|
||||
return false;
|
||||
}
|
||||
RzAnalysis *analysis = esil->panalysis;
|
||||
|
||||
// get target address
|
||||
if (!__esil_pop_argument(esil, &addr)) {
|
||||
|
|
@ -1573,7 +1577,7 @@ static bool avr_custom_spm_page_write(RzAnalysisEsil *esil) {
|
|||
|
||||
// get details about current MCU and fix input address and base address
|
||||
// of the internal temporary page
|
||||
cpu = get_cpu_model(esil->analysis->cpu);
|
||||
cpu = get_cpu_model(analysis->cpu);
|
||||
page_size_bits = const_get_value(const_by_name(cpu, CPU_CONST_PARAM, "page_size"));
|
||||
rz_analysis_esil_reg_read(esil, "_page", &tmp_page, NULL);
|
||||
|
||||
|
|
@ -1595,12 +1599,13 @@ static bool avr_custom_spm_page_write(RzAnalysisEsil *esil) {
|
|||
static int esil_avr_hook_reg_write(RzAnalysisEsil *esil, const char *name, ut64 *val) {
|
||||
CPU_MODEL *cpu;
|
||||
|
||||
if (!esil || !esil->analysis) {
|
||||
if (!esil || !esil->panalysis) {
|
||||
return 0;
|
||||
}
|
||||
RzAnalysis *analysis = esil->panalysis;
|
||||
|
||||
// select cpu info
|
||||
cpu = get_cpu_model(esil->analysis->cpu);
|
||||
cpu = get_cpu_model(analysis->cpu);
|
||||
|
||||
// crop registers and force certain values
|
||||
if (!strcmp(name, "pc")) {
|
||||
|
|
@ -1618,7 +1623,8 @@ static int esil_avr_hook_reg_write(RzAnalysisEsil *esil, const char *name, ut64
|
|||
return 0;
|
||||
}
|
||||
|
||||
RZ_IPI int rz_avr_esil_init(RzAnalysisEsil *esil) {
|
||||
RZ_IPI bool rz_avr_esil_init(void *pesil) {
|
||||
RzAnalysisEsil *esil = pesil;
|
||||
if (!esil) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1631,10 +1637,6 @@ RZ_IPI int rz_avr_esil_init(RzAnalysisEsil *esil) {
|
|||
return true;
|
||||
}
|
||||
|
||||
RZ_IPI int rz_avr_esil_fini(RzAnalysisEsil *esil) {
|
||||
return true;
|
||||
}
|
||||
|
||||
RZ_IPI void rz_avr_esil_opcode(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len) {
|
||||
// select cpu info
|
||||
CPU_MODEL *cpu = get_cpu_model(analysis->cpu);
|
||||
|
|
|
|||
|
|
@ -5,8 +5,7 @@
|
|||
#define RZ_AVR_ESIL_H
|
||||
#include "analysis_private.h"
|
||||
|
||||
RZ_IPI int rz_avr_esil_init(RzAnalysisEsil *esil);
|
||||
RZ_IPI int rz_avr_esil_fini(RzAnalysisEsil *esil);
|
||||
RZ_IPI bool rz_avr_esil_init(void *pesil);
|
||||
RZ_IPI void rz_avr_esil_opcode(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len);
|
||||
|
||||
#endif /* RZ_AVR_ESIL_H */
|
||||
|
|
@ -1844,22 +1844,20 @@ static char *_6502_get_reg_profile(RzAnalysis *analysis) {
|
|||
return rz_str_dup(p);
|
||||
}
|
||||
|
||||
static int _6502_esil_init(RzAnalysisEsil *esil) {
|
||||
if (esil->analysis && esil->analysis->reg) { // initial values
|
||||
rz_reg_set_value(esil->analysis->reg, rz_reg_get(esil->analysis->reg, "pc", -1), 0x0000);
|
||||
rz_reg_set_value(esil->analysis->reg, rz_reg_get(esil->analysis->reg, "sp", -1), 0xff);
|
||||
rz_reg_set_value(esil->analysis->reg, rz_reg_get(esil->analysis->reg, "a", -1), 0x00);
|
||||
rz_reg_set_value(esil->analysis->reg, rz_reg_get(esil->analysis->reg, "x", -1), 0x00);
|
||||
rz_reg_set_value(esil->analysis->reg, rz_reg_get(esil->analysis->reg, "y", -1), 0x00);
|
||||
rz_reg_set_value(esil->analysis->reg, rz_reg_get(esil->analysis->reg, "flags", -1), 0x00);
|
||||
static bool _6502_esil_init(void *pesil) {
|
||||
RzAnalysisEsil *esil = pesil;
|
||||
RzAnalysis *analysis = esil->panalysis;
|
||||
if (analysis && analysis->reg) { // initial values
|
||||
rz_reg_set_value(analysis->reg, rz_reg_get(analysis->reg, "pc", -1), 0x0000);
|
||||
rz_reg_set_value(analysis->reg, rz_reg_get(analysis->reg, "sp", -1), 0xff);
|
||||
rz_reg_set_value(analysis->reg, rz_reg_get(analysis->reg, "a", -1), 0x00);
|
||||
rz_reg_set_value(analysis->reg, rz_reg_get(analysis->reg, "x", -1), 0x00);
|
||||
rz_reg_set_value(analysis->reg, rz_reg_get(analysis->reg, "y", -1), 0x00);
|
||||
rz_reg_set_value(analysis->reg, rz_reg_get(analysis->reg, "flags", -1), 0x00);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int _6502_esil_fini(RzAnalysisEsil *esil) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int _6502_address_bits(RzAnalysis *analysis, int bits) {
|
||||
return 16;
|
||||
}
|
||||
|
|
@ -1904,7 +1902,6 @@ RzAnalysisPlugin rz_analysis_plugin_6502 = {
|
|||
.get_reg_profile = &_6502_get_reg_profile,
|
||||
.esil = true,
|
||||
.esil_init = _6502_esil_init,
|
||||
.esil_fini = _6502_esil_fini,
|
||||
.il_config = _6502_il_config,
|
||||
.archinfo = _6502_archinfo,
|
||||
};
|
||||
|
|
@ -912,80 +912,11 @@ static void analyze_op_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// custom reg read/write temporarily disabled - see r2 issue #9242
|
||||
static int i8051_hook_reg_read(RzAnalysisEsil *, const char *, ut64 *, int *);
|
||||
|
||||
static int i8051_reg_compare(const void *name, const void *reg) {
|
||||
return strcmp ((const char*)name, ((RI8051Reg*)reg)->name);
|
||||
}
|
||||
|
||||
static RI8051Reg *i8051_reg_find(const char *name) {
|
||||
return (RI8051Reg *) bsearch (
|
||||
name, registers,
|
||||
sizeof (registers) / sizeof (registers[0]),
|
||||
sizeof (registers[0]),
|
||||
i8051_reg_compare);
|
||||
}
|
||||
|
||||
static int i8051_reg_get_offset(RzAnalysisEsil *esil, RI8051Reg *ri) {
|
||||
ut8 offset = ri->offset;
|
||||
if (ri->banked) {
|
||||
ut64 psw = 0LL;
|
||||
i8051_hook_reg_read (esil, "psw", &psw, NULL);
|
||||
offset += psw & 0x18;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
// dkreuter: It would be nice if we could attach hooks to RzRegItems directly.
|
||||
// That way we could avoid doing a string lookup on register names
|
||||
// as rz_reg_get already does this. Also, the analysis esil callbacks
|
||||
// approach interferes with rz_reg_arena_swap.
|
||||
|
||||
static int i8051_hook_reg_read(RzAnalysisEsil *esil, const char *name, ut64 *res, int *size) {
|
||||
int ret = 0;
|
||||
ut64 val = 0LL;
|
||||
RI8051Reg *ri;
|
||||
RzAnalysisEsilCallbacks cbs = esil->cb;
|
||||
|
||||
if ((ri = i8051_reg_find (name))) {
|
||||
ut8 offset = i8051_reg_get_offset(esil, ri);
|
||||
ret = rz_analysis_esil_mem_read (esil, IRAM_BASE + offset, (ut8*)res, ri->num_bytes);
|
||||
}
|
||||
esil->cb = ocbs;
|
||||
if (!ret && ocbs.hook_reg_read) {
|
||||
ret = ocbs.hook_reg_read (esil, name, res, NULL);
|
||||
}
|
||||
if (!ret && ocbs.reg_read) {
|
||||
ret = ocbs.reg_read (esil, name, &val, NULL);
|
||||
}
|
||||
esil->cb = cbs;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int i8051_hook_reg_write(RzAnalysisEsil *esil, const char *name, ut64 *val) {
|
||||
int ret = 0;
|
||||
RI8051Reg *ri;
|
||||
RzAnalysisEsilCallbacks cbs = esil->cb;
|
||||
if ((ri = i8051_reg_find (name))) {
|
||||
ut8 offset = i8051_reg_get_offset(esil, ri);
|
||||
ret = rz_analysis_esil_mem_write (esil, IRAM_BASE + offset, (ut8*)val, ri->num_bytes);
|
||||
}
|
||||
esil->cb = ocbs;
|
||||
if (!ret && ocbs.hook_reg_write) {
|
||||
ret = ocbs.hook_reg_write (esil, name, val);
|
||||
}
|
||||
esil->cb = cbs;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int esil_i8051_init(RzAnalysisEsil *esil) {
|
||||
static bool esil_i8051_init(void *pesil) {
|
||||
RzAnalysisEsil *esil = pesil;
|
||||
RzAnalysis *analysis = esil->panalysis;
|
||||
// reset emulation control registers based on cpu
|
||||
set_cpu_model(esil->analysis, true);
|
||||
set_cpu_model(analysis, true);
|
||||
|
||||
if (esil->cb.user) {
|
||||
return true;
|
||||
|
|
@ -1005,7 +936,8 @@ static int esil_i8051_init(RzAnalysisEsil *esil) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static int esil_i8051_fini(RzAnalysisEsil *esil) {
|
||||
static bool esil_i8051_fini(void *pesil) {
|
||||
RzAnalysisEsil *esil = pesil;
|
||||
RZ_FREE(esil->cb.user);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -490,7 +490,6 @@ RzAnalysisPlugin rz_analysis_plugin_avr = {
|
|||
.op = &avr_op,
|
||||
.get_reg_profile = &get_reg_profile,
|
||||
.esil_init = rz_avr_esil_init,
|
||||
.esil_fini = rz_avr_esil_fini,
|
||||
.il_config = rz_avr_il_config,
|
||||
.analysis_mask = analysis_mask_avr,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1131,7 +1131,7 @@ static inline void gb_analysis_cb_srl(RzAnalysisOpMask mask, RzReg *reg, RzAnaly
|
|||
}
|
||||
|
||||
static bool gb_custom_daa(RzAnalysisEsil *esil) {
|
||||
if (!esil || !esil->analysis || !esil->analysis->reg) {
|
||||
if (!esil) {
|
||||
return false;
|
||||
}
|
||||
char *v = rz_analysis_esil_pop(esil);
|
||||
|
|
@ -2005,22 +2005,25 @@ static char *gb_get_reg_profile(RzAnalysis *analysis) {
|
|||
return rz_str_dup(p);
|
||||
}
|
||||
|
||||
static int gb_esil_init(RzAnalysisEsil *esil) {
|
||||
static bool gb_esil_init(void *pesil) {
|
||||
RzAnalysisEsil *esil = pesil;
|
||||
RzAnalysis *analysis = esil->panalysis;
|
||||
GBUser *user = RZ_NEW0(GBUser);
|
||||
|
||||
rz_analysis_esil_set_op(esil, "daa", gb_custom_daa, 1, 1, RZ_ANALYSIS_ESIL_OP_TYPE_MATH | RZ_ANALYSIS_ESIL_OP_TYPE_CUSTOM);
|
||||
if (user) {
|
||||
if (esil->analysis) {
|
||||
esil->analysis->iob.read_at(esil->analysis->iob.io, 0x147, &user->mbc_id, 1);
|
||||
esil->analysis->iob.read_at(esil->analysis->iob.io, 0x148, &user->romsz_id, 1);
|
||||
esil->analysis->iob.read_at(esil->analysis->iob.io, 0x149, &user->ramsz_id, 1);
|
||||
if (esil->analysis->reg) { // initial values
|
||||
rz_reg_set_value(esil->analysis->reg, rz_reg_get(esil->analysis->reg, "mpc", -1), 0x100);
|
||||
rz_reg_set_value(esil->analysis->reg, rz_reg_get(esil->analysis->reg, "sp", -1), 0xfffe);
|
||||
rz_reg_set_value(esil->analysis->reg, rz_reg_get(esil->analysis->reg, "af", -1), 0x01b0);
|
||||
rz_reg_set_value(esil->analysis->reg, rz_reg_get(esil->analysis->reg, "bc", -1), 0x0013);
|
||||
rz_reg_set_value(esil->analysis->reg, rz_reg_get(esil->analysis->reg, "de", -1), 0x00d8);
|
||||
rz_reg_set_value(esil->analysis->reg, rz_reg_get(esil->analysis->reg, "hl", -1), 0x014d);
|
||||
rz_reg_set_value(esil->analysis->reg, rz_reg_get(esil->analysis->reg, "ime", -1), true);
|
||||
if (analysis) {
|
||||
analysis->iob.read_at(analysis->iob.io, 0x147, &user->mbc_id, 1);
|
||||
analysis->iob.read_at(analysis->iob.io, 0x148, &user->romsz_id, 1);
|
||||
analysis->iob.read_at(analysis->iob.io, 0x149, &user->ramsz_id, 1);
|
||||
if (analysis->reg) { // initial values
|
||||
rz_reg_set_value(analysis->reg, rz_reg_get(analysis->reg, "mpc", -1), 0x100);
|
||||
rz_reg_set_value(analysis->reg, rz_reg_get(analysis->reg, "sp", -1), 0xfffe);
|
||||
rz_reg_set_value(analysis->reg, rz_reg_get(analysis->reg, "af", -1), 0x01b0);
|
||||
rz_reg_set_value(analysis->reg, rz_reg_get(analysis->reg, "bc", -1), 0x0013);
|
||||
rz_reg_set_value(analysis->reg, rz_reg_get(analysis->reg, "de", -1), 0x00d8);
|
||||
rz_reg_set_value(analysis->reg, rz_reg_get(analysis->reg, "hl", -1), 0x014d);
|
||||
rz_reg_set_value(analysis->reg, rz_reg_get(analysis->reg, "ime", -1), true);
|
||||
}
|
||||
}
|
||||
esil->cb.user = user;
|
||||
|
|
@ -2028,7 +2031,8 @@ static int gb_esil_init(RzAnalysisEsil *esil) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static int gb_esil_fini(RzAnalysisEsil *esil) {
|
||||
static bool gb_esil_fini(void *pesil) {
|
||||
RzAnalysisEsil *esil = pesil;
|
||||
RZ_FREE(esil->cb.user);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3797,21 +3797,6 @@ static RzList /*<RzSearchKeyword *>*/ *analysis_preludes(RzAnalysis *analysis) {
|
|||
return l;
|
||||
}
|
||||
|
||||
static int esil_x86_zydis_init(RzAnalysisEsil *esil) {
|
||||
if (!esil) {
|
||||
return false;
|
||||
}
|
||||
// XXX. this depends on kernel
|
||||
// rz_analysis_esil_set_interrupt (esil, 0x80, x86_int_0x80);
|
||||
/* disable by default */
|
||||
// rz_analysis_esil_set_interrupt (esil, 0x80, NULL,addr); // this is stupid, don't do this
|
||||
return true;
|
||||
}
|
||||
|
||||
static int esil_x86_zydis_fini(RzAnalysisEsil *esil) {
|
||||
return true;
|
||||
}
|
||||
|
||||
RzAnalysisPlugin rz_analysis_plugin_x86_zydis = {
|
||||
.name = "x86",
|
||||
.desc = "Zydis X86 analysis",
|
||||
|
|
@ -3825,8 +3810,6 @@ RzAnalysisPlugin rz_analysis_plugin_x86_zydis = {
|
|||
.get_reg_profile = &get_reg_profile,
|
||||
.init = x86_init,
|
||||
.fini = x86_fini,
|
||||
.esil_init = esil_x86_zydis_init,
|
||||
.esil_fini = esil_x86_zydis_fini,
|
||||
.il_config = rz_x86_il_config
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#include <rz_core.h>
|
||||
#define LOOP_MAX 10
|
||||
|
||||
static bool analysis_emul_init(RzCore *core, RzConfigHold *hc, RzDebugTrace **dt, RzAnalysisEsilTrace **et, RzAnalysisRzilTrace **rt) {
|
||||
static bool analysis_emul_init(RzCore *core, RzConfigHold *hc, RzDebugTrace **dt, RzAnalysisEsilTrace **et, RzAnalysisILTrace **rt) {
|
||||
RzReg *rreg = rz_analysis_get_reg(core->analysis);
|
||||
RzAnalysisEsil *esil = rz_analysis_get_esil(core->analysis);
|
||||
if (!esil) {
|
||||
|
|
@ -37,7 +37,7 @@ static bool analysis_emul_init(RzCore *core, RzConfigHold *hc, RzDebugTrace **dt
|
|||
return (core->dbg->trace && esil->trace);
|
||||
}
|
||||
|
||||
static void analysis_emul_restore(RzCore *core, RzConfigHold *hc, RzDebugTrace *dt, RzAnalysisEsilTrace *et, RzAnalysisRzilTrace *rt) {
|
||||
static void analysis_emul_restore(RzCore *core, RzConfigHold *hc, RzDebugTrace *dt, RzAnalysisEsilTrace *et, RzAnalysisILTrace *rt) {
|
||||
RzAnalysisEsil *esil = rz_analysis_get_esil(core->analysis);
|
||||
rz_config_hold_restore(hc);
|
||||
rz_config_hold_free(hc);
|
||||
|
|
@ -847,7 +847,7 @@ RZ_API void rz_core_analysis_type_match(RzCore *core, RzAnalysisFunction *fcn, H
|
|||
}
|
||||
RzDebugTrace *dt = NULL;
|
||||
RzAnalysisEsilTrace *et = NULL;
|
||||
RzAnalysisRzilTrace *rt = NULL;
|
||||
RzAnalysisILTrace *rt = NULL;
|
||||
if (!analysis_emul_init(core, hc, &dt, &et, &rt) || !fcn) {
|
||||
analysis_emul_restore(core, hc, dt, et, rt);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1549,7 +1549,7 @@ static bool cb_iopcachewrite(void *user, void *data) {
|
|||
|
||||
RZ_API bool rz_core_esil_cmd(RzAnalysisEsil *esil, const char *cmd, ut64 a1, ut64 a2) {
|
||||
if (cmd && *cmd) {
|
||||
RzCore *core = esil->core;
|
||||
RzCore *core = (RzCore *)esil->pcore;
|
||||
rz_core_cmdf(core, "%s %" PFMT64d " %" PFMT64d, cmd, a1, a2);
|
||||
return core->num->value;
|
||||
}
|
||||
|
|
|
|||
1241
librz/core/cesil.c
1241
librz/core/cesil.c
File diff suppressed because it is too large
Load diff
1238
librz/core/cil.c
1238
librz/core/cil.c
File diff suppressed because it is too large
Load diff
|
|
@ -699,10 +699,11 @@ static void aea_stats_init(AeaStats *stats) {
|
|||
}
|
||||
|
||||
static void aea_stats_fini(AeaStats *stats) {
|
||||
RZ_FREE(stats->regs);
|
||||
RZ_FREE(stats->regread);
|
||||
RZ_FREE(stats->regwrite);
|
||||
RZ_FREE(stats->inputregs);
|
||||
RZ_FREE_CUSTOM(stats->regs, rz_list_free);
|
||||
RZ_FREE_CUSTOM(stats->regread, rz_list_free);
|
||||
RZ_FREE_CUSTOM(stats->regwrite, rz_list_free);
|
||||
RZ_FREE_CUSTOM(stats->regvalues, rz_list_free);
|
||||
RZ_FREE_CUSTOM(stats->inputregs, rz_list_free);
|
||||
}
|
||||
|
||||
static bool contains(RzList /*<char *>*/ *list, const char *name) {
|
||||
|
|
@ -718,14 +719,15 @@ static bool contains(RzList /*<char *>*/ *list, const char *name) {
|
|||
static int mymemwrite(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len) {
|
||||
RzListIter *iter;
|
||||
RzAnalysisEsilMemoryRegion *n;
|
||||
RzAnalysisEsilInterState *estate = rz_analysis_get_esil_inter_state(esil->analysis);
|
||||
RzAnalysisEsilInterState *estate = esil->esilinterstate;
|
||||
RzCore *core = esil->pcore;
|
||||
RzList *memwrites = estate->memwrites;
|
||||
rz_list_foreach (memwrites, iter, n) {
|
||||
if (addr == n->addr) {
|
||||
return len;
|
||||
}
|
||||
}
|
||||
if (!rz_io_is_valid_offset(esil->core->io, addr, 0)) {
|
||||
if (!rz_io_is_valid_offset(core->io, addr, 0)) {
|
||||
return false;
|
||||
}
|
||||
n = RZ_NEW(RzAnalysisEsilMemoryRegion);
|
||||
|
|
@ -740,14 +742,15 @@ static int mymemwrite(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len)
|
|||
static int mymemread(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len) {
|
||||
RzListIter *iter;
|
||||
RzAnalysisEsilMemoryRegion *n;
|
||||
RzAnalysisEsilInterState *estate = rz_analysis_get_esil_inter_state(esil->analysis);
|
||||
RzAnalysisEsilInterState *estate = esil->esilinterstate;
|
||||
RzCore *core = esil->pcore;
|
||||
RzList *memreads = estate->memreads;
|
||||
rz_list_foreach (memreads, iter, n) {
|
||||
if (addr == n->addr) {
|
||||
return len;
|
||||
}
|
||||
}
|
||||
if (!rz_io_is_valid_offset(esil->core->io, addr, 0)) {
|
||||
if (!rz_io_is_valid_offset(core->io, addr, 0)) {
|
||||
return false;
|
||||
}
|
||||
n = RZ_NEW(RzAnalysisEsilMemoryRegion);
|
||||
|
|
@ -847,15 +850,16 @@ static void showmem_json(RzList /*<RzAnalysisEsilMemoryRegion *>*/ *list, PJ *pj
|
|||
}
|
||||
|
||||
static bool cmd_aea(RzCore *core, int mode, ut64 addr, int length) {
|
||||
RzAnalysisEsil *esil;
|
||||
RzAnalysisEsil *esil = NULL;
|
||||
bool ret = false;
|
||||
RzReg *rreg = rz_analysis_get_reg(core->analysis);
|
||||
int ptr, ops, ops_end = 0, len, buf_sz, maxopsize;
|
||||
ut64 addr_end;
|
||||
AeaStats stats;
|
||||
const char *esilstr;
|
||||
int ptr = 0, ops = 0, ops_end = 0, len = 0, buf_sz = 0, maxopsize = 0;
|
||||
ut64 addr_end = 0;
|
||||
AeaStats stats = { 0 };
|
||||
const char *esilstr = NULL;
|
||||
RzAnalysisOp aop = RZ_EMPTY;
|
||||
ut8 *buf;
|
||||
RzList *regnow;
|
||||
ut8 *buf = NULL;
|
||||
RzList *regnow = NULL;
|
||||
PJ *pj = NULL;
|
||||
if (!core) {
|
||||
return false;
|
||||
|
|
@ -887,7 +891,6 @@ static bool cmd_aea(RzCore *core, int mode, ut64 addr, int length) {
|
|||
aea_stats_init(&stats);
|
||||
|
||||
rz_reg_arena_push(rreg);
|
||||
RzAnalysisEsilInterState *estate = rz_analysis_get_esil_inter_state(core->analysis);
|
||||
int stacksize = rz_config_get_i(core->config, "esil.stack.depth");
|
||||
bool iotrap = rz_config_get_i(core->config, "esil.iotrap");
|
||||
int romem = rz_config_get_i(core->config, "esil.romem");
|
||||
|
|
@ -898,6 +901,7 @@ static bool cmd_aea(RzCore *core, int mode, ut64 addr, int length) {
|
|||
rz_analysis_esil_setup(esil, core->analysis, romem, stats1, noNULL, core); // setup io
|
||||
#define hasNext(x) (x & 1) ? (addr < addr_end) : (ops < ops_end)
|
||||
|
||||
RzAnalysisEsilInterState *estate = esil->esilinterstate;
|
||||
estate->memreads = rz_list_new();
|
||||
estate->memwrites = rz_list_new();
|
||||
esil->user = &stats;
|
||||
|
|
@ -925,7 +929,6 @@ static bool cmd_aea(RzCore *core, int mode, ut64 addr, int length) {
|
|||
esil->cb.hook_reg_write = NULL;
|
||||
esil->cb.hook_reg_read = NULL;
|
||||
// esil_fini (core);
|
||||
rz_analysis_esil_free(esil);
|
||||
rz_reg_arena_pop(rreg);
|
||||
regnow = rz_list_newf(free);
|
||||
{
|
||||
|
|
@ -961,7 +964,7 @@ static bool cmd_aea(RzCore *core, int mode, ut64 addr, int length) {
|
|||
} else if ((mode >> 4) & 1) {
|
||||
pj = pj_new();
|
||||
if (!pj) {
|
||||
return false;
|
||||
goto fail;
|
||||
}
|
||||
pj_o(pj);
|
||||
pj_k(pj, "A");
|
||||
|
|
@ -1028,15 +1031,16 @@ static bool cmd_aea(RzCore *core, int mode, ut64 addr, int length) {
|
|||
showmem(estate->memwrites);
|
||||
}
|
||||
}
|
||||
ret = true;
|
||||
|
||||
fail:
|
||||
rz_list_free(estate->memreads);
|
||||
rz_list_free(estate->memwrites);
|
||||
estate->memreads = NULL;
|
||||
estate->memwrites = NULL;
|
||||
aea_stats_fini(&stats);
|
||||
free(buf);
|
||||
RZ_FREE(regnow);
|
||||
return true;
|
||||
rz_list_free(regnow);
|
||||
rz_analysis_esil_free(esil);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// aeC
|
||||
|
|
@ -6355,6 +6359,7 @@ RZ_IPI RzCmdStatus rz_analyze_esil_insn_access_handler(RzCore *core, int argc, c
|
|||
}
|
||||
ut64 newPC = core->offset + op->size;
|
||||
rz_reg_setv(reg, "PC", newPC);
|
||||
rz_analysis_op_free(op);
|
||||
}
|
||||
|
||||
const char cmd_type = argv[2][0];
|
||||
|
|
|
|||
|
|
@ -1921,7 +1921,8 @@ RZ_IPI RzCmdStatus rz_cmd_debug_traces_esil_i_handler(RzCore *core, int argc, co
|
|||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
RzAnalysisEsil *esil = rz_analysis_get_esil(core->analysis);
|
||||
rz_analysis_esil_trace_op(esil, op);
|
||||
const char *eexpr = rz_strbuf_get(&op->esil);
|
||||
rz_analysis_esil_trace_op(esil, op->addr, eexpr);
|
||||
rz_analysis_op_free(op);
|
||||
return RZ_CMD_STATUS_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -561,6 +561,7 @@ static void RzBinSourceLineCacheItem_free(RzBinSourceLineCacheItem *x) {
|
|||
}
|
||||
|
||||
static RzDisasmState *ds_init(RzCore *core) {
|
||||
RzAnalysisEsil *esil = rz_analysis_get_esil(core->analysis);
|
||||
RzDisasmState *ds = RZ_NEW0(RzDisasmState);
|
||||
if (!ds) {
|
||||
return NULL;
|
||||
|
|
@ -669,15 +670,14 @@ static RzDisasmState *ds_init(RzCore *core) {
|
|||
ds->show_emu_ssa = rz_config_get_b(core->config, "emu.ssa");
|
||||
ds->show_emu_stack = rz_config_get_b(core->config, "emu.stack");
|
||||
ds->stackFd = -1;
|
||||
if (ds->show_emu_stack) {
|
||||
if (ds->show_emu_stack && esil) {
|
||||
// TODO: initialize fake stack in here
|
||||
const char *uri = "malloc://32K";
|
||||
ut64 size = rz_num_get(core->num, "32K");
|
||||
RzReg *rreg = rz_analysis_get_reg(core->analysis);
|
||||
RzAnalysisEsilInterState *estate = rz_analysis_get_esil_inter_state(core->analysis);
|
||||
ut64 addr = rz_reg_getv(rreg, "SP") - (size / 2);
|
||||
estate->emustack_min = addr;
|
||||
estate->emustack_max = addr + size;
|
||||
esil->esilinterstate->emustack_min = addr;
|
||||
esil->esilinterstate->emustack_max = addr + size;
|
||||
ds->stackFd = rz_io_fd_open(core->io, uri, RZ_PERM_RW, 0);
|
||||
RzIOMap *map = rz_io_map_add(core->io, ds->stackFd, RZ_PERM_RW, 0LL, addr, size);
|
||||
if (!map) {
|
||||
|
|
@ -4296,7 +4296,7 @@ static int mymemwrite1(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len)
|
|||
}
|
||||
|
||||
static int mymemwrite2(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len) {
|
||||
RzAnalysisEsilInterState *estate = rz_analysis_get_esil_inter_state(esil->analysis);
|
||||
RzAnalysisEsilInterState *estate = esil->esilinterstate;
|
||||
return (addr >= estate->emustack_min && addr < estate->emustack_max);
|
||||
}
|
||||
|
||||
|
|
@ -4332,7 +4332,7 @@ static int myregread(RzAnalysisEsil *esil, const char *name, ut64 *res, int *siz
|
|||
|
||||
static int myregwrite(RzAnalysisEsil *esil, const char *name, ut64 *val) {
|
||||
char str[64], *msg = NULL;
|
||||
RzCore *core = esil->core;
|
||||
RzCore *core = esil->pcore;
|
||||
bool big_endian = core ? rz_asm_is_big_endian_set(core->rasm) : false;
|
||||
RzDisasmState *ds = esil->user;
|
||||
if (!ds) {
|
||||
|
|
|
|||
|
|
@ -49,8 +49,8 @@ RZ_IPI bool rz_core_visual_esil(RzCore *core) {
|
|||
}
|
||||
memcpy(buf, core->block, sizeof(ut64));
|
||||
RzAnalysisEsil *esil = rz_analysis_esil_new(20, 0, addrsize);
|
||||
esil->core = core;
|
||||
esil->analysis = core->analysis;
|
||||
esil->pcore = core;
|
||||
esil->panalysis = core->analysis;
|
||||
rz_analysis_esil_set_pc(esil, core->offset);
|
||||
for (;;) {
|
||||
rz_cons_clear00();
|
||||
|
|
|
|||
|
|
@ -192,7 +192,8 @@ RZ_API void rz_debug_trace_op(RzDebug *dbg, RzAnalysisOp *op) {
|
|||
if (dbg->trace->enabled) {
|
||||
RzAnalysisEsil *esil = rz_analysis_get_esil(dbg->analysis);
|
||||
if (esil) {
|
||||
rz_analysis_esil_trace_op(esil, op);
|
||||
const char *eexpr = rz_strbuf_get(&op->esil);
|
||||
rz_analysis_esil_trace_op(esil, op->addr, eexpr);
|
||||
} else {
|
||||
if (dbg->verbose) {
|
||||
RZ_LOG_WARN("debug: Run aeim to get esil initialized\n");
|
||||
|
|
|
|||
|
|
@ -164,6 +164,11 @@ rz_il_files = [
|
|||
]
|
||||
install_headers(rz_il_files, install_dir: join_paths(rizin_incdir, 'rz_il'))
|
||||
|
||||
rz_esil_files = [
|
||||
'rz_esil/rz_esil.h',
|
||||
]
|
||||
install_headers(rz_esil_files, install_dir: join_paths(rizin_incdir, 'rz_esil'))
|
||||
|
||||
rz_crypto_files = [
|
||||
'rz_crypto/rz_des.h',
|
||||
'rz_crypto/rz_aes.h',
|
||||
|
|
|
|||
|
|
@ -24,8 +24,7 @@
|
|||
#include <rz_il.h>
|
||||
#include <rz_platform.h>
|
||||
#include <rz_cmd.h>
|
||||
|
||||
#define esilprintf(op, fmt, ...) rz_strbuf_setf(&op->esil, fmt, ##__VA_ARGS__)
|
||||
#include <rz_esil/rz_esil.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -396,7 +395,17 @@ typedef struct rz_analysis_callbacks_t {
|
|||
bool (*read_at)(RzAnalysis *analysis, ut64 addr, ut8 *buf, int len);
|
||||
} RzAnalysisCallbacks;
|
||||
|
||||
#define RZ_ANALYSIS_ESIL_GOTO_LIMIT 4096
|
||||
typedef struct rz_analysis_il_trace_t {
|
||||
int idx;
|
||||
int end_idx;
|
||||
HtUP *registers;
|
||||
HtUP *memory;
|
||||
RzRegArena *arena[RZ_REG_TYPE_LAST];
|
||||
ut64 stack_addr;
|
||||
ut64 stack_size;
|
||||
ut8 *stack_data;
|
||||
RzPVector /*<RzILTraceInstruction *>*/ *instructions;
|
||||
} RzAnalysisILTrace;
|
||||
|
||||
typedef struct rz_analysis_options_t {
|
||||
int depth;
|
||||
|
|
@ -960,21 +969,6 @@ typedef struct rz_analysis_cycle_hook_t { // rename ?
|
|||
int cycles;
|
||||
} RzAnalysisCycleHook;
|
||||
|
||||
typedef struct rz_analysis_esil_word_t {
|
||||
int type;
|
||||
const char *str;
|
||||
} RzAnalysisEsilWord;
|
||||
|
||||
// only flags that affect control flow
|
||||
enum {
|
||||
RZ_ANALYSIS_ESIL_FLAG_ZERO = 1,
|
||||
RZ_ANALYSIS_ESIL_FLAG_CARRY = 2,
|
||||
RZ_ANALYSIS_ESIL_FLAG_OVERFLOW = 4,
|
||||
RZ_ANALYSIS_ESIL_FLAG_PARITY = 8,
|
||||
RZ_ANALYSIS_ESIL_FLAG_SIGN = 16,
|
||||
// ...
|
||||
};
|
||||
|
||||
enum {
|
||||
RZ_ANALYSIS_TRAP_NONE = 0,
|
||||
RZ_ANALYSIS_TRAP_UNHANDLED = 1,
|
||||
|
|
@ -989,161 +983,11 @@ enum {
|
|||
RZ_ANALYSIS_TRAP_HALT = 10,
|
||||
};
|
||||
|
||||
enum {
|
||||
RZ_ANALYSIS_ESIL_PARM_INVALID = 0,
|
||||
RZ_ANALYSIS_ESIL_PARM_REG,
|
||||
RZ_ANALYSIS_ESIL_PARM_NUM,
|
||||
};
|
||||
|
||||
typedef struct rz_analysis_ref_char {
|
||||
char *str;
|
||||
char *cols;
|
||||
} RzAnalysisRefStr;
|
||||
|
||||
// must be a char
|
||||
#define ESIL_INTERNAL_PREFIX '$'
|
||||
#define ESIL_STACK_NAME "esil.ram"
|
||||
|
||||
typedef struct rz_analysis_esil_source_t {
|
||||
ut32 id;
|
||||
ut32 claimed;
|
||||
void *content;
|
||||
} RzAnalysisEsilSource;
|
||||
|
||||
typedef struct rz_analysis_esil_t RzAnalysisEsil;
|
||||
|
||||
RZ_API void rz_analysis_esil_sources_init(RzAnalysisEsil *esil);
|
||||
RZ_API ut32 rz_analysis_esil_load_source(RzAnalysisEsil *esil, const char *path);
|
||||
RZ_API void *rz_analysis_esil_get_source(RzAnalysisEsil *esil, ut32 src_id);
|
||||
RZ_API bool rz_analysis_esil_claim_source(RzAnalysisEsil *esil, ut32 src_id);
|
||||
RZ_API void rz_analysis_esil_release_source(RzAnalysisEsil *esil, ut32 src_id);
|
||||
RZ_API void rz_analysis_esil_sources_fini(RzAnalysisEsil *esil);
|
||||
|
||||
typedef bool (*RzAnalysisEsilInterruptCB)(RzAnalysisEsil *esil, ut32 interrupt, void *user);
|
||||
|
||||
typedef struct rz_analysis_esil_interrupt_handler_t {
|
||||
const ut32 num;
|
||||
const char *name;
|
||||
void *(*init)(RzAnalysisEsil *esil);
|
||||
RzAnalysisEsilInterruptCB cb;
|
||||
void (*fini)(void *user);
|
||||
} RzAnalysisEsilInterruptHandler;
|
||||
|
||||
typedef struct rz_analysis_esil_change_reg_t {
|
||||
int idx;
|
||||
ut64 data;
|
||||
} RzAnalysisEsilRegChange;
|
||||
|
||||
typedef struct rz_analysis_esil_change_mem_t {
|
||||
int idx;
|
||||
ut8 data;
|
||||
} RzAnalysisEsilMemChange;
|
||||
|
||||
typedef struct rz_analysis_esil_trace_t {
|
||||
int idx;
|
||||
int end_idx;
|
||||
HtUP *registers;
|
||||
HtUP *memory;
|
||||
RzRegArena *arena[RZ_REG_TYPE_LAST];
|
||||
ut64 stack_addr;
|
||||
ut64 stack_size;
|
||||
ut8 *stack_data;
|
||||
RzPVector /*<RzILTraceInstruction *>*/ *instructions;
|
||||
} RzAnalysisEsilTrace;
|
||||
|
||||
typedef int (*RzAnalysisEsilHookRegWriteCB)(RzAnalysisEsil *esil, const char *name, ut64 *val);
|
||||
|
||||
typedef struct rz_analysis_esil_callbacks_t {
|
||||
void *user;
|
||||
/* callbacks */
|
||||
int (*hook_flag_read)(RzAnalysisEsil *esil, const char *flag, ut64 *num);
|
||||
int (*hook_command)(RzAnalysisEsil *esil, const char *op);
|
||||
int (*hook_mem_read)(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len);
|
||||
int (*mem_read)(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len);
|
||||
int (*hook_mem_write)(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len);
|
||||
int (*mem_write)(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len);
|
||||
int (*hook_reg_read)(RzAnalysisEsil *esil, const char *name, ut64 *res, int *size);
|
||||
int (*reg_read)(RzAnalysisEsil *esil, const char *name, ut64 *res, int *size);
|
||||
RzAnalysisEsilHookRegWriteCB hook_reg_write;
|
||||
int (*reg_write)(RzAnalysisEsil *esil, const char *name, ut64 val);
|
||||
} RzAnalysisEsilCallbacks;
|
||||
|
||||
struct rz_analysis_esil_t {
|
||||
RzCore *core;
|
||||
RzAnalysis *analysis;
|
||||
char **stack;
|
||||
ut64 addrmask;
|
||||
int stacksize;
|
||||
int stackptr;
|
||||
ut32 skip;
|
||||
int nowrite;
|
||||
int iotrap;
|
||||
int exectrap;
|
||||
int repeat;
|
||||
int parse_stop;
|
||||
int parse_goto;
|
||||
int parse_goto_count;
|
||||
int verbose;
|
||||
ut64 flags;
|
||||
ut64 address;
|
||||
ut64 stack_addr;
|
||||
ut32 stack_size;
|
||||
int delay; // mapped to $ds in ESIL
|
||||
ut64 jump_target; // mapped to $jt in ESIL
|
||||
int jump_target_set; // mapped to $js in ESIL
|
||||
int trap;
|
||||
ut32 trap_code; // extend into a struct to store more exception info?
|
||||
// parity flag? done with cur
|
||||
ut64 old; // used for carry-flagging and borrow-flagging
|
||||
ut64 cur; // used for carry-flagging and borrow-flagging
|
||||
ut8 lastsz; // in bits //used for signature-flag
|
||||
/* native ops and custom ops */
|
||||
HtSP *ops;
|
||||
RzStrBuf current_opstr;
|
||||
RzIDStorage *sources;
|
||||
HtUP *interrupts;
|
||||
/* deep esil parsing fills this */
|
||||
Sdb *stats;
|
||||
RzAnalysisEsilTrace *trace;
|
||||
RzAnalysisEsilCallbacks cb;
|
||||
// this is so cursed, can we please remove external commands from esil internals.
|
||||
// Function pointers are fine, but not commands
|
||||
char *cmd_step; // rizin (external) command to run before a step is performed
|
||||
char *cmd_step_out; // rizin (external) command to run after a step is performed
|
||||
char *cmd_intr; // rizin (external) command to run when an interrupt occurs
|
||||
char *cmd_trap; // rizin (external) command to run when a trap occurs
|
||||
char *cmd_mdev; // rizin (external) command to run when an memory mapped device address is used
|
||||
char *cmd_todo; // rizin (external) command to run when esil expr contains TODO
|
||||
char *cmd_ioer; // rizin (external) command to run when esil fails to IO
|
||||
char *mdev_range; // string containing the rz_str_range to match for read/write accesses
|
||||
bool (*cmd)(RzAnalysisEsil *esil, const char *name, ut64 a0, ut64 a1);
|
||||
void *user;
|
||||
int stack_fd; // ahem, let's not do this
|
||||
bool in_cmd_step;
|
||||
};
|
||||
|
||||
/* During the analysis RzAnalysisEsil could be reset multiple times,
|
||||
* thus there is a need to preserve some values between those runs.
|
||||
*/
|
||||
typedef struct rz_analysis_esil_inter_state_t {
|
||||
bool analysis_stop;
|
||||
ut64 last_read;
|
||||
ut64 last_data;
|
||||
ut64 emustack_min;
|
||||
ut64 emustack_max;
|
||||
RzList /*<RzAnalysisEsilMemoryRegion *>*/ *memreads;
|
||||
RzList /*<RzAnalysisEsilMemoryRegion *>*/ *memwrites;
|
||||
RzAnalysisEsilCallbacks callbacks;
|
||||
bool callbacks_set;
|
||||
} RzAnalysisEsilInterState;
|
||||
|
||||
/* Alias RegChange and MemChange */
|
||||
typedef RzAnalysisEsilRegChange RzAnalysisRzilRegChange;
|
||||
typedef RzAnalysisEsilMemChange RzAnalysisRzilMemChange;
|
||||
|
||||
/* Alias esil strace */
|
||||
typedef RzAnalysisEsilTrace RzAnalysisRzilTrace;
|
||||
|
||||
/**
|
||||
* \brief Description of the contents of a single IL variable
|
||||
*/
|
||||
|
|
@ -1215,68 +1059,10 @@ typedef enum {
|
|||
RZ_ANALYSIS_IL_STEP_INVALID_OP
|
||||
} RzAnalysisILStepResult;
|
||||
|
||||
#undef ESIL
|
||||
|
||||
typedef struct rz_analysis_esil_interrupt_t {
|
||||
RzAnalysisEsilInterruptHandler *handler;
|
||||
void *user;
|
||||
ut32 src_id;
|
||||
RzAnalysisEsil *esil;
|
||||
} RzAnalysisEsilInterrupt;
|
||||
|
||||
enum {
|
||||
RZ_ANALYSIS_ESIL_OP_TYPE_UNKNOWN = 0x1,
|
||||
RZ_ANALYSIS_ESIL_OP_TYPE_CONTROL_FLOW,
|
||||
RZ_ANALYSIS_ESIL_OP_TYPE_MEM_READ = 0x4,
|
||||
RZ_ANALYSIS_ESIL_OP_TYPE_MEM_WRITE = 0x8,
|
||||
RZ_ANALYSIS_ESIL_OP_TYPE_REG_WRITE = 0x10,
|
||||
RZ_ANALYSIS_ESIL_OP_TYPE_MATH = 0x20,
|
||||
RZ_ANALYSIS_ESIL_OP_TYPE_CUSTOM = 0x40
|
||||
};
|
||||
|
||||
typedef bool (*RzAnalysisEsilOpCb)(RzAnalysisEsil *esil);
|
||||
|
||||
typedef struct rz_analysis_esil_operation_t {
|
||||
RzAnalysisEsilOpCb code;
|
||||
ut32 push; // amount of operands pushed
|
||||
ut32 pop; // amount of operands popped
|
||||
ut32 type;
|
||||
} RzAnalysisEsilOp;
|
||||
|
||||
// this is 80-bit offsets so we can address every piece of esil in an instruction
|
||||
typedef struct rz_analysis_esil_expr_offset_t {
|
||||
ut64 off;
|
||||
ut16 idx;
|
||||
} RzAnalysisEsilEOffset;
|
||||
|
||||
typedef enum {
|
||||
RZ_ANALYSIS_ESIL_BLOCK_ENTER_NORMAL = 0,
|
||||
RZ_ANALYSIS_ESIL_BLOCK_ENTER_TRUE,
|
||||
RZ_ANALYSIS_ESIL_BLOCK_ENTER_FALSE,
|
||||
RZ_ANALYSIS_ESIL_BLOCK_ENTER_GLUE,
|
||||
} RzAnalysisEsilBlockEnterType;
|
||||
|
||||
typedef struct rz_analysis_esil_basic_block_t {
|
||||
RzAnalysisEsilEOffset first;
|
||||
RzAnalysisEsilEOffset last;
|
||||
char *expr; // synthesized esil-expression for this block
|
||||
RzAnalysisEsilBlockEnterType enter; // maybe more type is needed here
|
||||
} RzAnalysisEsilBB;
|
||||
|
||||
// Structure to represent memory reads and writes during ESIL tracing
|
||||
typedef struct rz_analysis_esil_memory_region_t {
|
||||
ut64 addr; ///< memory address
|
||||
size_t size; ///< size of the region
|
||||
} RzAnalysisEsilMemoryRegion;
|
||||
|
||||
// TODO: rm data + len
|
||||
typedef int (*RzAnalysisOpCallback)(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask);
|
||||
typedef char *(*RzAnalysisRegProfGetCallback)(RzAnalysis *a);
|
||||
|
||||
typedef int (*RzAnalysisEsilCB)(RzAnalysisEsil *esil);
|
||||
typedef int (*RzAnalysisEsilLoopCB)(RzAnalysisEsil *esil, RzAnalysisOp *op);
|
||||
typedef int (*RzAnalysisEsilTrapCB)(RzAnalysisEsil *esil, int trap_type, int trap_code);
|
||||
|
||||
typedef RZ_OWN RzAnalysisILConfig *(*RzAnalysisILConfigCB)(RzAnalysis *analysis);
|
||||
|
||||
typedef struct rz_analysis_plugin_t {
|
||||
|
|
@ -1305,15 +1091,49 @@ typedef struct rz_analysis_plugin_t {
|
|||
RzAnalysisOpCallback op;
|
||||
|
||||
RzAnalysisRegProfGetCallback get_reg_profile;
|
||||
|
||||
RzAnalysisEsilCB esil_init; // initialize esil-related stuff
|
||||
RzAnalysisEsilLoopCB esil_post_loop; // cycle-counting, firing interrupts, ...
|
||||
RzAnalysisEsilTrapCB esil_trap; // traps / exceptions
|
||||
RzAnalysisEsilCB esil_fini; // deinitialize
|
||||
RzAnalysisILConfigCB il_config; ///< return an IL config to execute lifted code of the given analysis' arch/cpu/bits
|
||||
|
||||
// Deprecated.
|
||||
bool (*esil_init)(void *esil);
|
||||
bool (*esil_fini)(void *esil);
|
||||
} RzAnalysisPlugin;
|
||||
|
||||
typedef enum {
|
||||
RZ_IL_TRACE_OP_READ, ///< read
|
||||
RZ_IL_TRACE_OP_WRITE ///< write
|
||||
} RzILTraceOpType;
|
||||
|
||||
typedef struct {
|
||||
ut64 addr; ///< memory address
|
||||
RzILTraceOpType behavior; ///< read or write, see RzILTraceOpType enums
|
||||
ut8 data_buf[32]; ///< data either written to or read from
|
||||
int data_len; ///< data length
|
||||
} RzILTraceMemOp;
|
||||
|
||||
typedef struct {
|
||||
const char *reg_name; ///< name of register
|
||||
RzILTraceOpType behavior; ///< READ or WRITE, see RzILTraceOpType enums
|
||||
ut64 value; ///< data either written to or read from
|
||||
} RzILTraceRegOp;
|
||||
|
||||
typedef enum {
|
||||
RZ_IL_TRACE_INS_HAS_MEM_R = 0x1U, ///< instruction include memory read
|
||||
RZ_IL_TRACE_INS_HAS_MEM_W = 0x2U, ///< instruction include memory write
|
||||
RZ_IL_TRACE_INS_HAS_REG_R = 0x4U, ///< instruction include register read
|
||||
RZ_IL_TRACE_INS_HAS_REG_W = 0x8U ///< instruction include register write
|
||||
} RzILTraceInsOp;
|
||||
|
||||
typedef struct rz_il_trace_instruction_t {
|
||||
ut64 addr; ///< Address of instruction
|
||||
ut32 stats; ///< Has write/read to reg/mem ? see RZ_IL_TRACE_INS_HAS_* enums
|
||||
|
||||
RzPVector /*<RzILTraceMemOp *>*/ *write_mem_ops; ///< Vector<RzILTraceMemOp>
|
||||
RzPVector /*<RzILTraceMemOp *>*/ *read_mem_ops; ///< Vector<RzILTraceMemOp>
|
||||
|
||||
RzPVector /*<RzILTraceRegOp *>*/ *write_reg_ops; ///< Vector<RzILTraceRegOp>
|
||||
RzPVector /*<RzILTraceRegOp *>*/ *read_reg_ops; ///< Vector<RzILTraceRegOp>
|
||||
} RzILTraceInstruction;
|
||||
|
||||
/*----------------------------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef RZ_API
|
||||
|
|
@ -1568,8 +1388,6 @@ RZ_DEPRECATE RZ_API void rz_analysis_set_core(RZ_NONNULL RzAnalysis *analysis, R
|
|||
RZ_DEPRECATE RZ_API void rz_analysis_set_event(RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzEvent *ev);
|
||||
RZ_DEPRECATE RZ_API RZ_BORROW RzAnalysisEsil *rz_analysis_get_esil(RZ_NONNULL RzAnalysis *analysis);
|
||||
RZ_DEPRECATE RZ_API void rz_analysis_set_esil(RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzAnalysisEsil *esil);
|
||||
RZ_DEPRECATE RZ_API RZ_BORROW RzAnalysisEsilInterState *rz_analysis_get_esil_inter_state(RZ_NONNULL RzAnalysis *analysis);
|
||||
RZ_DEPRECATE RZ_API void rz_analysis_set_esil_inter_state(RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzAnalysisEsilInterState *esilinterstate);
|
||||
RZ_DEPRECATE RZ_API const char *rz_analysis_get_arch(RZ_NONNULL const RzAnalysis *analysis);
|
||||
RZ_DEPRECATE RZ_API int rz_analysis_get_bits(RZ_NONNULL const RzAnalysis *analysis);
|
||||
RZ_DEPRECATE RZ_API bool rz_analysis_is_big_endian_set(RZ_NONNULL const RzAnalysis *analysis);
|
||||
|
|
@ -1623,76 +1441,6 @@ RZ_API int rz_analysis_op(RZ_NONNULL RzAnalysis *analysis, RZ_OUT RzAnalysisOp *
|
|||
RZ_API RzAnalysisOp *rz_analysis_op_hexstr(RzAnalysis *analysis, ut64 addr, const char *hexstr);
|
||||
RZ_API char *rz_analysis_op_to_string(RzAnalysis *analysis, RzAnalysisOp *op);
|
||||
|
||||
RZ_API RzAnalysisEsil *rz_analysis_esil_new(int stacksize, int iotrap, unsigned int addrsize);
|
||||
RZ_API bool rz_analysis_esil_set_pc(RzAnalysisEsil *esil, ut64 addr);
|
||||
RZ_API bool rz_analysis_esil_setup(RzAnalysisEsil *esil, RzAnalysis *analysis, int romem, int stats, int nonull, RzCore *core);
|
||||
RZ_API void rz_analysis_esil_free(RzAnalysisEsil *esil);
|
||||
RZ_API bool rz_analysis_esil_runword(RzAnalysisEsil *esil, const char *word);
|
||||
RZ_API bool rz_analysis_esil_parse(RzAnalysisEsil *esil, const char *str);
|
||||
RZ_API int rz_analysis_esil_mem_read(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len);
|
||||
RZ_API int rz_analysis_esil_mem_write(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len);
|
||||
RZ_API int rz_analysis_esil_reg_read(RzAnalysisEsil *esil, const char *regname, ut64 *num, int *size);
|
||||
RZ_API int rz_analysis_esil_reg_write(RzAnalysisEsil *esil, const char *dst, ut64 num);
|
||||
RZ_API bool rz_analysis_esil_pushnum(RzAnalysisEsil *esil, ut64 num);
|
||||
RZ_API bool rz_analysis_esil_push(RzAnalysisEsil *esil, const char *str);
|
||||
RZ_API char *rz_analysis_esil_pop(RzAnalysisEsil *esil);
|
||||
RZ_API const char *rz_analysis_esil_trapstr(int type);
|
||||
RZ_API bool rz_analysis_esil_set_op(RzAnalysisEsil *esil, const char *op, RzAnalysisEsilOpCb code, ut32 push, ut32 pop, ut32 type);
|
||||
RZ_API void rz_analysis_esil_stack_free(RzAnalysisEsil *esil);
|
||||
RZ_API int rz_analysis_esil_get_parm_type(RzAnalysisEsil *esil, const char *str);
|
||||
RZ_API int rz_analysis_esil_get_parm(RzAnalysisEsil *esil, const char *str, ut64 *num);
|
||||
RZ_API int rz_analysis_esil_condition(RzAnalysisEsil *esil, const char *str);
|
||||
|
||||
// esil_interrupt.c
|
||||
RZ_API void rz_analysis_esil_interrupts_init(RzAnalysisEsil *esil);
|
||||
RZ_API RzAnalysisEsilInterrupt *rz_analysis_esil_interrupt_new(RzAnalysisEsil *esil, ut32 src_id, RzAnalysisEsilInterruptHandler *ih);
|
||||
RZ_API void rz_analysis_esil_interrupt_free(RzAnalysisEsil *esil, RzAnalysisEsilInterrupt *intr);
|
||||
RZ_API bool rz_analysis_esil_set_interrupt(RzAnalysisEsil *esil, RzAnalysisEsilInterrupt *intr);
|
||||
RZ_API int rz_analysis_esil_fire_interrupt(RzAnalysisEsil *esil, ut32 intr_num);
|
||||
RZ_API bool rz_analysis_esil_load_interrupts(RzAnalysisEsil *esil, RzAnalysisEsilInterruptHandler **handlers, ut32 src_id);
|
||||
RZ_API bool rz_analysis_esil_load_interrupts_from_lib(RzAnalysisEsil *esil, const char *path);
|
||||
RZ_API void rz_analysis_esil_interrupts_fini(RzAnalysisEsil *esil);
|
||||
|
||||
RZ_API void rz_analysis_esil_mem_ro(RzAnalysisEsil *esil, int mem_readonly);
|
||||
RZ_API void rz_analysis_esil_stats(RzAnalysisEsil *esil, int enable);
|
||||
|
||||
/* new trace implementation */
|
||||
typedef enum {
|
||||
RZ_IL_TRACE_OP_READ, ///< read
|
||||
RZ_IL_TRACE_OP_WRITE ///< write
|
||||
} RzILTraceOpType;
|
||||
|
||||
typedef struct {
|
||||
ut64 addr; ///< memory address
|
||||
RzILTraceOpType behavior; ///< read or write, see RzILTraceOpType enums
|
||||
ut8 data_buf[32]; ///< data either written to or read from
|
||||
int data_len; ///< data length
|
||||
} RzILTraceMemOp;
|
||||
|
||||
typedef struct {
|
||||
const char *reg_name; ///< name of register
|
||||
RzILTraceOpType behavior; ///< READ or WRITE, see RzILTraceOpType enums
|
||||
ut64 value; ///< data either written to or read from
|
||||
} RzILTraceRegOp;
|
||||
|
||||
typedef enum {
|
||||
RZ_IL_TRACE_INS_HAS_MEM_R = 0x1U, ///< instruction include memory read
|
||||
RZ_IL_TRACE_INS_HAS_MEM_W = 0x2U, ///< instruction include memory write
|
||||
RZ_IL_TRACE_INS_HAS_REG_R = 0x4U, ///< instruction include register read
|
||||
RZ_IL_TRACE_INS_HAS_REG_W = 0x8U ///< instruction include register write
|
||||
} RzILTraceInsOp;
|
||||
|
||||
typedef struct {
|
||||
ut64 addr; ///< Address of instruction
|
||||
ut32 stats; ///< Has write/read to reg/mem ? see RZ_IL_TRACE_INS_HAS_* enums
|
||||
|
||||
RzPVector /*<RzILTraceMemOp *>*/ *write_mem_ops; ///< Vector<RzILTraceMemOp>
|
||||
RzPVector /*<RzILTraceMemOp *>*/ *read_mem_ops; ///< Vector<RzILTraceMemOp>
|
||||
|
||||
RzPVector /*<RzILTraceRegOp *>*/ *write_reg_ops; ///< Vector<RzILTraceRegOp>
|
||||
RzPVector /*<RzILTraceRegOp *>*/ *read_reg_ops; ///< Vector<RzILTraceRegOp>
|
||||
} RzILTraceInstruction;
|
||||
|
||||
/* Independent Trace Functions */
|
||||
RZ_API RzILTraceInstruction *rz_analysis_il_trace_instruction_new(ut64 addr);
|
||||
RZ_API void rz_analysis_il_trace_instruction_free(RzILTraceInstruction *instruction);
|
||||
|
|
@ -1703,15 +1451,6 @@ RZ_API RzILTraceRegOp *rz_analysis_il_get_reg_op_trace(RzILTraceInstruction *tra
|
|||
RZ_API bool rz_analysis_il_mem_trace_contains(RzILTraceInstruction *trace, ut64 addr, RzILTraceOpType op_type);
|
||||
RZ_API bool rz_analysis_il_reg_trace_contains(RzILTraceInstruction *trace, const char *regname, RzILTraceOpType op_type);
|
||||
|
||||
/* ESIL trace */
|
||||
RZ_API RZ_BORROW RzILTraceInstruction *rz_analysis_esil_get_instruction_trace(RZ_NONNULL RzAnalysisEsilTrace *etrace, int idx);
|
||||
RZ_API RzAnalysisEsilTrace *rz_analysis_esil_trace_new(RzAnalysisEsil *esil);
|
||||
RZ_API void rz_analysis_esil_trace_free(RzAnalysisEsilTrace *trace);
|
||||
RZ_API void rz_analysis_esil_trace_op(RzAnalysisEsil *esil, RZ_NONNULL RzAnalysisOp *op);
|
||||
RZ_API void rz_analysis_esil_trace_list(RzAnalysisEsil *esil);
|
||||
RZ_API void rz_analysis_esil_trace_show(RzAnalysisEsil *esil, int idx);
|
||||
RZ_API void rz_analysis_esil_trace_restore(RzAnalysisEsil *esil, int idx);
|
||||
|
||||
/* RzIL */
|
||||
RZ_API RzAnalysisILInitState *rz_analysis_il_init_state_new();
|
||||
RZ_API void rz_analysis_il_init_state_free(RzAnalysisILInitState *state);
|
||||
|
|
@ -1742,9 +1481,9 @@ RZ_API bool rz_analysis_il_vm_set_bool(RZ_NONNULL RzAnalysis *analysis, RZ_NULLA
|
|||
RZ_API bool rz_analysis_il_vm_set_float(RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE const char *var_name, long double value);
|
||||
|
||||
/* trace */
|
||||
RZ_API RzAnalysisRzilTrace *rz_analysis_rzil_trace_new(RzAnalysis *analysis, RZ_NONNULL RzAnalysisILVM *rzil);
|
||||
RZ_API void rz_analysis_rzil_trace_free(RzAnalysisRzilTrace *trace);
|
||||
RZ_API void rz_analysis_rzil_trace_op(RzAnalysis *analysis, RZ_NONNULL RzAnalysisILVM *rzil, RZ_NONNULL RzAnalysisLiftedILOp op);
|
||||
RZ_API RzAnalysisILTrace *rz_analysis_il_trace_new(RzAnalysis *analysis, RZ_NONNULL RzAnalysisILVM *rzil);
|
||||
RZ_API void rz_analysis_il_trace_free(RzAnalysisILTrace *trace);
|
||||
RZ_API void rz_analysis_il_trace_op(RzAnalysis *analysis, RZ_NONNULL RzAnalysisILVM *rzil, RZ_NONNULL RzAnalysisLiftedILOp op);
|
||||
|
||||
RZ_API bool rz_analysis_add_device_peripheral_map(RzBinObject *o, RzAnalysis *analysis);
|
||||
|
||||
|
|
|
|||
281
librz/include/rz_esil/rz_esil.h
Normal file
281
librz/include/rz_esil/rz_esil.h
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
// SPDX-FileCopyrightText: 2014-2021 pancake <pancake@nopcode.org>
|
||||
// SPDX-FileCopyrightText: 2014-2021 condret <condr3t@protonmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#ifndef RZ_ANALYSIS_ESIL_H
|
||||
#define RZ_ANALYSIS_ESIL_H
|
||||
|
||||
#include <rz_util.h>
|
||||
#include <rz_reg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RZ_ANALYSIS_ESIL_GOTO_LIMIT 4096
|
||||
|
||||
#define esilprintf(op, fmt, ...) rz_strbuf_setf(&op->esil, fmt, ##__VA_ARGS__)
|
||||
|
||||
typedef struct rz_analysis_esil_word_t {
|
||||
int type;
|
||||
const char *str;
|
||||
} RzAnalysisEsilWord;
|
||||
|
||||
// only flags that affect control flow
|
||||
enum {
|
||||
RZ_ANALYSIS_ESIL_FLAG_ZERO = 1,
|
||||
RZ_ANALYSIS_ESIL_FLAG_CARRY = 2,
|
||||
RZ_ANALYSIS_ESIL_FLAG_OVERFLOW = 4,
|
||||
RZ_ANALYSIS_ESIL_FLAG_PARITY = 8,
|
||||
RZ_ANALYSIS_ESIL_FLAG_SIGN = 16,
|
||||
// ...
|
||||
};
|
||||
|
||||
enum {
|
||||
RZ_ANALYSIS_ESIL_PARM_INVALID = 0,
|
||||
RZ_ANALYSIS_ESIL_PARM_REG,
|
||||
RZ_ANALYSIS_ESIL_PARM_NUM,
|
||||
};
|
||||
|
||||
// must be a char
|
||||
#define ESIL_INTERNAL_PREFIX '$'
|
||||
#define ESIL_STACK_NAME "esil.ram"
|
||||
|
||||
typedef struct rz_analysis_esil_source_t {
|
||||
ut32 id;
|
||||
ut32 claimed;
|
||||
void *content;
|
||||
} RzAnalysisEsilSource;
|
||||
|
||||
typedef struct rz_analysis_esil_t RzAnalysisEsil;
|
||||
|
||||
RZ_API void rz_analysis_esil_sources_init(RzAnalysisEsil *esil);
|
||||
RZ_API ut32 rz_analysis_esil_load_source(RzAnalysisEsil *esil, const char *path);
|
||||
RZ_API void *rz_analysis_esil_get_source(RzAnalysisEsil *esil, ut32 src_id);
|
||||
RZ_API bool rz_analysis_esil_claim_source(RzAnalysisEsil *esil, ut32 src_id);
|
||||
RZ_API void rz_analysis_esil_release_source(RzAnalysisEsil *esil, ut32 src_id);
|
||||
RZ_API void rz_analysis_esil_sources_fini(RzAnalysisEsil *esil);
|
||||
|
||||
typedef bool (*RzAnalysisEsilInterruptCB)(RzAnalysisEsil *esil, ut32 interrupt, void *user);
|
||||
|
||||
typedef struct rz_analysis_esil_interrupt_handler_t {
|
||||
const ut32 num;
|
||||
const char *name;
|
||||
void *(*init)(RzAnalysisEsil *esil);
|
||||
RzAnalysisEsilInterruptCB cb;
|
||||
void (*fini)(void *user);
|
||||
} RzAnalysisEsilInterruptHandler;
|
||||
|
||||
typedef struct rz_analysis_esil_change_reg_t {
|
||||
int idx;
|
||||
ut64 data;
|
||||
} RzAnalysisEsilRegChange;
|
||||
|
||||
typedef struct rz_analysis_esil_change_mem_t {
|
||||
int idx;
|
||||
ut8 data;
|
||||
} RzAnalysisEsilMemChange;
|
||||
|
||||
typedef struct rz_analysis_esil_trace_t {
|
||||
int idx;
|
||||
int end_idx;
|
||||
HtUP *registers;
|
||||
HtUP *memory;
|
||||
RzRegArena *arena[RZ_REG_TYPE_LAST];
|
||||
ut64 stack_addr;
|
||||
ut64 stack_size;
|
||||
ut8 *stack_data;
|
||||
RzPVector /*<RzILTraceInstruction *>*/ *instructions;
|
||||
} RzAnalysisEsilTrace;
|
||||
|
||||
typedef int (*RzAnalysisEsilHookRegWriteCB)(RzAnalysisEsil *esil, const char *name, ut64 *val);
|
||||
|
||||
typedef struct rz_analysis_esil_callbacks_t {
|
||||
void *user;
|
||||
/* callbacks */
|
||||
int (*hook_flag_read)(RzAnalysisEsil *esil, const char *flag, ut64 *num);
|
||||
int (*hook_command)(RzAnalysisEsil *esil, const char *op);
|
||||
int (*hook_mem_read)(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len);
|
||||
int (*mem_read)(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len);
|
||||
int (*hook_mem_write)(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len);
|
||||
int (*mem_write)(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len);
|
||||
int (*hook_reg_read)(RzAnalysisEsil *esil, const char *name, ut64 *res, int *size);
|
||||
int (*reg_read)(RzAnalysisEsil *esil, const char *name, ut64 *res, int *size);
|
||||
RzAnalysisEsilHookRegWriteCB hook_reg_write;
|
||||
int (*reg_write)(RzAnalysisEsil *esil, const char *name, ut64 val);
|
||||
} RzAnalysisEsilCallbacks;
|
||||
|
||||
/* During the analysis RzAnalysisEsil could be reset multiple times,
|
||||
* thus there is a need to preserve some values between those runs.
|
||||
*/
|
||||
typedef struct rz_analysis_esil_inter_state_t {
|
||||
bool analysis_stop;
|
||||
ut64 last_read;
|
||||
ut64 last_data;
|
||||
ut64 emustack_min;
|
||||
ut64 emustack_max;
|
||||
RzList /*<RzAnalysisEsilMemoryRegion *>*/ *memreads;
|
||||
RzList /*<RzAnalysisEsilMemoryRegion *>*/ *memwrites;
|
||||
RzAnalysisEsilCallbacks callbacks;
|
||||
bool callbacks_set;
|
||||
} RzAnalysisEsilInterState;
|
||||
|
||||
struct rz_analysis_esil_t {
|
||||
void *pcore;
|
||||
void *panalysis;
|
||||
char **stack;
|
||||
ut64 addrmask;
|
||||
int stacksize;
|
||||
int stackptr;
|
||||
ut32 skip;
|
||||
int nowrite;
|
||||
int iotrap;
|
||||
int exectrap;
|
||||
int repeat;
|
||||
int parse_stop;
|
||||
int parse_goto;
|
||||
int parse_goto_count;
|
||||
int verbose;
|
||||
ut64 flags;
|
||||
ut64 address;
|
||||
ut64 stack_addr;
|
||||
ut32 stack_size;
|
||||
int delay; // mapped to $ds in ESIL
|
||||
ut64 jump_target; // mapped to $jt in ESIL
|
||||
int jump_target_set; // mapped to $js in ESIL
|
||||
int trap;
|
||||
ut32 trap_code; // extend into a struct to store more exception info?
|
||||
// parity flag? done with cur
|
||||
ut64 old; // used for carry-flagging and borrow-flagging
|
||||
ut64 cur; // used for carry-flagging and borrow-flagging
|
||||
ut8 lastsz; // in bits //used for signature-flag
|
||||
/* native ops and custom ops */
|
||||
HtSP *ops;
|
||||
RzStrBuf current_opstr;
|
||||
RzIDStorage *sources;
|
||||
HtUP *interrupts;
|
||||
/* deep esil parsing fills this */
|
||||
Sdb *stats;
|
||||
RzAnalysisEsilTrace *trace;
|
||||
RzAnalysisEsilCallbacks cb;
|
||||
// this is so cursed, can we please remove external commands from esil internals.
|
||||
// Function pointers are fine, but not commands
|
||||
char *cmd_step; // rizin (external) command to run before a step is performed
|
||||
char *cmd_step_out; // rizin (external) command to run after a step is performed
|
||||
char *cmd_intr; // rizin (external) command to run when an interrupt occurs
|
||||
char *cmd_trap; // rizin (external) command to run when a trap occurs
|
||||
char *cmd_mdev; // rizin (external) command to run when an memory mapped device address is used
|
||||
char *cmd_todo; // rizin (external) command to run when esil expr contains TODO
|
||||
char *cmd_ioer; // rizin (external) command to run when esil fails to IO
|
||||
char *mdev_range; // string containing the rz_str_range to match for read/write accesses
|
||||
bool (*cmd)(RzAnalysisEsil *esil, const char *name, ut64 a0, ut64 a1);
|
||||
void *user;
|
||||
int stack_fd; // ahem, let's not do this
|
||||
bool in_cmd_step;
|
||||
RzAnalysisEsilInterState *esilinterstate;
|
||||
};
|
||||
|
||||
/* Alias RegChange and MemChange */
|
||||
typedef RzAnalysisEsilRegChange RzAnalysisRzilRegChange;
|
||||
typedef RzAnalysisEsilMemChange RzAnalysisRzilMemChange;
|
||||
|
||||
/* Alias esil strace */
|
||||
typedef struct rz_analysis_esil_interrupt_t {
|
||||
RzAnalysisEsilInterruptHandler *handler;
|
||||
void *user;
|
||||
ut32 src_id;
|
||||
RzAnalysisEsil *esil;
|
||||
} RzAnalysisEsilInterrupt;
|
||||
|
||||
enum {
|
||||
RZ_ANALYSIS_ESIL_OP_TYPE_UNKNOWN = 0x1,
|
||||
RZ_ANALYSIS_ESIL_OP_TYPE_CONTROL_FLOW,
|
||||
RZ_ANALYSIS_ESIL_OP_TYPE_MEM_READ = 0x4,
|
||||
RZ_ANALYSIS_ESIL_OP_TYPE_MEM_WRITE = 0x8,
|
||||
RZ_ANALYSIS_ESIL_OP_TYPE_REG_WRITE = 0x10,
|
||||
RZ_ANALYSIS_ESIL_OP_TYPE_MATH = 0x20,
|
||||
RZ_ANALYSIS_ESIL_OP_TYPE_CUSTOM = 0x40
|
||||
};
|
||||
|
||||
typedef bool (*RzAnalysisEsilOpCb)(RzAnalysisEsil *esil);
|
||||
|
||||
typedef struct rz_analysis_esil_operation_t {
|
||||
RzAnalysisEsilOpCb code;
|
||||
ut32 push; // amount of operands pushed
|
||||
ut32 pop; // amount of operands popped
|
||||
ut32 type;
|
||||
} RzAnalysisEsilOp;
|
||||
|
||||
// this is 80-bit offsets so we can address every piece of esil in an instruction
|
||||
typedef struct rz_analysis_esil_expr_offset_t {
|
||||
ut64 off;
|
||||
ut16 idx;
|
||||
} RzAnalysisEsilEOffset;
|
||||
|
||||
typedef enum {
|
||||
RZ_ANALYSIS_ESIL_BLOCK_ENTER_NORMAL = 0,
|
||||
RZ_ANALYSIS_ESIL_BLOCK_ENTER_TRUE,
|
||||
RZ_ANALYSIS_ESIL_BLOCK_ENTER_FALSE,
|
||||
RZ_ANALYSIS_ESIL_BLOCK_ENTER_GLUE,
|
||||
} RzAnalysisEsilBlockEnterType;
|
||||
|
||||
typedef struct rz_analysis_esil_basic_block_t {
|
||||
RzAnalysisEsilEOffset first;
|
||||
RzAnalysisEsilEOffset last;
|
||||
char *expr; // synthesized esil-expression for this block
|
||||
RzAnalysisEsilBlockEnterType enter; // maybe more type is needed here
|
||||
} RzAnalysisEsilBB;
|
||||
|
||||
// Structure to represent memory reads and writes during ESIL tracing
|
||||
typedef struct rz_analysis_esil_memory_region_t {
|
||||
ut64 addr; ///< memory address
|
||||
size_t size; ///< size of the region
|
||||
} RzAnalysisEsilMemoryRegion;
|
||||
|
||||
RZ_API RzAnalysisEsil *rz_analysis_esil_new(int stacksize, int iotrap, unsigned int addrsize);
|
||||
RZ_API bool rz_analysis_esil_set_pc(RzAnalysisEsil *esil, ut64 addr);
|
||||
RZ_API bool rz_analysis_esil_setup(RzAnalysisEsil *esil, void /*RzAnalysis*/ *analysis, int romem, int stats, int nonull, void /*RzCore*/ *core);
|
||||
RZ_API void rz_analysis_esil_free(RzAnalysisEsil *esil);
|
||||
RZ_API bool rz_analysis_esil_runword(RzAnalysisEsil *esil, const char *word);
|
||||
RZ_API bool rz_analysis_esil_parse(RzAnalysisEsil *esil, const char *str);
|
||||
RZ_API int rz_analysis_esil_mem_read(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len);
|
||||
RZ_API int rz_analysis_esil_mem_write(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len);
|
||||
RZ_API int rz_analysis_esil_reg_read(RzAnalysisEsil *esil, const char *regname, ut64 *num, int *size);
|
||||
RZ_API int rz_analysis_esil_reg_write(RzAnalysisEsil *esil, const char *dst, ut64 num);
|
||||
RZ_API bool rz_analysis_esil_pushnum(RzAnalysisEsil *esil, ut64 num);
|
||||
RZ_API bool rz_analysis_esil_push(RzAnalysisEsil *esil, const char *str);
|
||||
RZ_API char *rz_analysis_esil_pop(RzAnalysisEsil *esil);
|
||||
RZ_API const char *rz_analysis_esil_trapstr(int type);
|
||||
RZ_API bool rz_analysis_esil_set_op(RzAnalysisEsil *esil, const char *op, RzAnalysisEsilOpCb code, ut32 push, ut32 pop, ut32 type);
|
||||
RZ_API void rz_analysis_esil_stack_free(RzAnalysisEsil *esil);
|
||||
RZ_API int rz_analysis_esil_get_parm_type(RzAnalysisEsil *esil, const char *str);
|
||||
RZ_API int rz_analysis_esil_get_parm(RzAnalysisEsil *esil, const char *str, ut64 *num);
|
||||
RZ_API int rz_analysis_esil_condition(RzAnalysisEsil *esil, const char *str);
|
||||
|
||||
// esil_interrupt.c
|
||||
RZ_API void rz_analysis_esil_interrupts_init(RzAnalysisEsil *esil);
|
||||
RZ_API RzAnalysisEsilInterrupt *rz_analysis_esil_interrupt_new(RzAnalysisEsil *esil, ut32 src_id, RzAnalysisEsilInterruptHandler *ih);
|
||||
RZ_API void rz_analysis_esil_interrupt_free(RzAnalysisEsil *esil, RzAnalysisEsilInterrupt *intr);
|
||||
RZ_API bool rz_analysis_esil_set_interrupt(RzAnalysisEsil *esil, RzAnalysisEsilInterrupt *intr);
|
||||
RZ_API int rz_analysis_esil_fire_interrupt(RzAnalysisEsil *esil, ut32 intr_num);
|
||||
RZ_API bool rz_analysis_esil_load_interrupts(RzAnalysisEsil *esil, RzAnalysisEsilInterruptHandler **handlers, ut32 src_id);
|
||||
RZ_API bool rz_analysis_esil_load_interrupts_from_lib(RzAnalysisEsil *esil, const char *path);
|
||||
RZ_API void rz_analysis_esil_interrupts_fini(RzAnalysisEsil *esil);
|
||||
|
||||
RZ_API void rz_analysis_esil_mem_ro(RzAnalysisEsil *esil, int mem_readonly);
|
||||
RZ_API void rz_analysis_esil_stats(RzAnalysisEsil *esil, int enable);
|
||||
|
||||
/* ESIL trace */
|
||||
RZ_API RZ_BORROW void /*RzILTraceInstruction*/ *rz_analysis_esil_get_instruction_trace(RZ_NONNULL RzAnalysisEsilTrace *etrace, int idx);
|
||||
RZ_API RzAnalysisEsilTrace *rz_analysis_esil_trace_new(RzAnalysisEsil *esil);
|
||||
RZ_API void rz_analysis_esil_trace_free(RzAnalysisEsilTrace *trace);
|
||||
RZ_API void rz_analysis_esil_trace_op(RzAnalysisEsil *esil, ut64 pc, RZ_NULLABLE const char *esil_expr);
|
||||
RZ_API void rz_analysis_esil_trace_list(RzAnalysisEsil *esil);
|
||||
RZ_API void rz_analysis_esil_trace_show(RzAnalysisEsil *esil, int idx);
|
||||
RZ_API void rz_analysis_esil_trace_restore(RzAnalysisEsil *esil, int idx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* RZ_ANALYSIS_ESIL_H */
|
||||
|
|
@ -2,7 +2,6 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_util/rz_annotated_code.h>
|
||||
#include <rz_core.h>
|
||||
#include <rz_util.h>
|
||||
|
||||
RZ_API RzAnnotatedCode *rz_annotated_code_new(char *code) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <rz_types.h>
|
||||
#include <rz_core.h>
|
||||
#include <rz_util.h>
|
||||
|
||||
#include "axml_resources.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// SPDX-FileCopyrightText: 2020 karliss <karlis3p70l1ij@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_core.h>
|
||||
#include <rz_util.h>
|
||||
#include <rz_util/rz_graph_drawable.h>
|
||||
#include "graph_priv.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,9 @@
|
|||
#include <rz_util/rz_strbuf.h>
|
||||
#include <rz_vector.h>
|
||||
#include <rz_util/rz_print.h>
|
||||
#define RZ_NO_ESIL 1
|
||||
#include <rz_analysis.h>
|
||||
#undef RZ_NO_ESIL
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
// SPDX-FileCopyrightText: 2013-2020 pancake <pancake@nopcode.org>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include "rz_types.h"
|
||||
#include "rz_util/rz_sys.h"
|
||||
#include <rz_types.h>
|
||||
#include <rz_util/rz_sys.h>
|
||||
#include <rz_util/rz_str.h>
|
||||
#include <rz_core.h>
|
||||
#include <rz_util.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue