Fix ESIL issues: Shift by register, double word store (#3645)

* Test for shifting via registers.
* Fix ESIL strd
This commit is contained in:
Rot127 2023-07-07 17:29:28 +00:00 committed by GitHub
parent 40a01ef36f
commit 83e40b0c0c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 15 deletions

View file

@ -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

View file

@ -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);
}
}
}