From 83e40b0c0cc76fc344dd778ec89c5eb43a2eaa8a Mon Sep 17 00:00:00 2001 From: Rot127 <45763064+Rot127@users.noreply.github.com> Date: Fri, 7 Jul 2023 17:29:28 +0000 Subject: [PATCH] Fix ESIL issues: Shift by register, double word store (#3645) * Test for shifting via registers. * Fix ESIL strd --- librz/analysis/arch/arm/arm_accessors32.h | 9 ++++--- librz/analysis/arch/arm/arm_esil32.c | 32 ++++++++++++++--------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/librz/analysis/arch/arm/arm_accessors32.h b/librz/analysis/arch/arm/arm_accessors32.h index 81ebdd4b35..1302a27edc 100644 --- a/librz/analysis/arch/arm/arm_accessors32.h +++ b/librz/analysis/arch/arm/arm_accessors32.h @@ -28,9 +28,12 @@ #define LSHIFT(x) 0 #define LSHIFT2(x) 0 #endif -#define OPCOUNT() insn->detail->arm.op_count -#define ISSHIFTED(x) (insn->detail->arm.operands[x].shift.type != ARM_SFT_INVALID && insn->detail->arm.operands[x].shift.value != 0) -#define SHIFTTYPE(x) insn->detail->arm.operands[x].shift.type +#define OPCOUNT() insn->detail->arm.op_count +#define ISSHIFTED(x) (insn->detail->arm.operands[x].shift.type != ARM_SFT_INVALID && insn->detail->arm.operands[x].shift.value != 0) +#define SHIFTTYPE(x) insn->detail->arm.operands[x].shift.type +#define SHIFTTYPEREG(x) (SHIFTTYPE(x) == ARM_SFT_ASR_REG || SHIFTTYPE(x) == ARM_SFT_LSL_REG || \ + SHIFTTYPE(x) == ARM_SFT_LSR_REG || SHIFTTYPE(x) == ARM_SFT_ROR_REG || \ + SHIFTTYPE(x) == ARM_SFT_RRX_REG) #define SHIFTVALUE(x) insn->detail->arm.operands[x].shift.value #define ISWRITEBACK32() insn->detail->arm.writeback diff --git a/librz/analysis/arch/arm/arm_esil32.c b/librz/analysis/arch/arm/arm_esil32.c index 65a755b23f..385d39f04c 100644 --- a/librz/analysis/arch/arm/arm_esil32.c +++ b/librz/analysis/arch/arm/arm_esil32.c @@ -138,11 +138,19 @@ static const char *arg(RzAnalysis *a, csh *handle, cs_insn *insn, char *buf, int switch (insn->detail->arm.operands[n].type) { case ARM_OP_REG: if (ISSHIFTED(n)) { - sprintf(buf, "%u,%s,%s", - LSHIFT2(n), - rz_str_get_null(cs_reg_name(*handle, - insn->detail->arm.operands[n].reg)), - DECODE_SHIFT(n)); + if (SHIFTTYPEREG(n)) { + sprintf(buf, "%s,%s,%s", + cs_reg_name(*handle, LSHIFT2(n)), + rz_str_get_null(cs_reg_name(*handle, + insn->detail->arm.operands[n].reg)), + DECODE_SHIFT(n)); + } else { + sprintf(buf, "%u,%s,%s", + LSHIFT2(n), + rz_str_get_null(cs_reg_name(*handle, + insn->detail->arm.operands[n].reg)), + DECODE_SHIFT(n)); + } } else { sprintf(buf, "%s", rz_str_get_null(cs_reg_name(*handle, @@ -602,11 +610,10 @@ r6,r5,r4,3,sp,[*],12,sp,+= } } if (OPCOUNT() == 3) { // e.g. 'str r2, [r3], 4 - if (ISIMM(2)) { // e.g. 'str r2, [r3], 4 + if (ISIMM(2) && str_ldr_bytes != 8) { // e.g. 'str r2, [r3], 4 rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%d,%s,+=", REG(0), MEMBASE(1), str_ldr_bytes, IMM(2), MEMBASE(1)); - } - if (ISREG(2)) { // e.g. 'str r2, [r3], r1 + } else if (str_ldr_bytes != 8) { if (ISSHIFTED(2)) { // e.g. 'str r2, [r3], r1, lsl 4' switch (SHIFTTYPE(2)) { case ARM_SFT_LSL: @@ -652,11 +659,12 @@ r6,r5,r4,3,sp,[*],12,sp,+= if (ISSHIFTED(2)) { // it seems strd does not support SHIFT which is good, but have a check nonetheless } else { - rz_strbuf_appendf(&op->esil, "%s,%s,%s,+,0xffffffff,&,=[4],%s,4,%s,+,%s,+,0xffffffff,&,=[4]", - REG(0), MEMINDEX(2), MEMBASE(2), REG(1), MEMINDEX(2), MEMBASE(2)); + rz_strbuf_appendf(&op->esil, "%s,%s,+,0xffffffff,&,=[4],%s,4,%s,+,0xffffffff,&,=[4]", + REG(0), MEMBASE(2), REG(1), MEMBASE(2)); if (insn->detail->arm.writeback) { - rz_strbuf_appendf(&op->esil, ",%s,%s,+,%s,=", - MEMINDEX(2), MEMBASE(2), MEMBASE(2)); + const char sign = ISMEMINDEXSUB(2) ? '-' : '+'; + rz_strbuf_appendf(&op->esil, ",%s,%s,%c=", + MEMINDEX(2), MEMBASE(2), sign); } } }