5 #include <capstone/capstone.h>
19 "qf",
"vf",
"cf",
"zf",
"nf",
"gef",
20 "r0",
"r1",
"r2",
"r3",
"r4",
"r5",
"r6",
"r7",
"r8",
"r9",
"r10",
"r11",
"r12",
21 "d0",
"d1",
"d2",
"d3",
"d4",
"d5",
"d6",
"d7",
"d8",
"d9",
"d10",
"d11",
"d12",
"d13",
"d14",
"d15",
22 "d16",
"d17",
"d18",
"d19",
"d20",
"d21",
"d22",
"d23",
"d24",
"d25",
"d26",
"d27",
"d28",
"d29",
"d30",
"d31",
108 #define PC(addr, is_thumb) (addr + (is_thumb ? 4 : 8))
109 #define PCALIGN(addr, is_thumb) (PC(addr, is_thumb) & ~3ul)
110 #define REG_VAL(id) read_reg(PC(insn->address, is_thumb), id)
111 #define REG(n) REG_VAL(REGID(n))
112 #define MEMBASE(x) REG_VAL(insn->detail->arm.operands[x].mem.base)
226 dist->op.cast.length = 5;
250 return ADD(base_plus_disp,
shift(index, carry_out,
op->shift.type,
UN(5,
op->shift.value)));
252 return base_plus_disp;
277 dist =
UN(5,
op->shift.value);
307 }
else if (disp < 0) {
310 return arg_mem(
addr, &insn->detail->arm.operands[
n], carry_out);
318 #define ARG_C(n, carry) arg(insn, is_thumb, n, carry)
319 #define ARG(n) ARG_C(n, NULL)
344 return setf && sets ?
SEQ2(sets, setf) : (setf ? setf : sets);
360 if (insn->detail->arm.operands[base_op].shift.type ==
ARM_SFT_INVALID) {
361 base_op =
OPCOUNT() < 3 ? 0 : 1;
393 dist =
ARG(base_op + 1);
499 bool with_carry =
false;
508 if (insn->detail->arm.update_flags) {
518 if (!strcmp(insn->mnemonic,
"adc") || !strcmp(insn->mnemonic,
"rsc") || !strcmp(insn->mnemonic,
"sbc") ||
519 !strcmp(insn->mnemonic,
"adc.w") || !strcmp(insn->mnemonic,
"sbc.w")) {
528 SETG(
"cf", (is_sub ? sub_carry : add_carry)(
VARL(
"a"),
VARL(
"b"), with_carry, 32)),
529 SETG(
"vf", (is_sub ? sub_overflow : add_overflow)(
VARL(
"a"),
VARL(
"b"),
REG(0))),
566 size_t mem_idx = is_double ? 2 : 1;
571 cs_arm_op *memop = &insn->detail->arm.operands[mem_idx];
581 bool writeback = insn->detail->arm.writeback;
582 if (
ISIMM(mem_idx + 1)) {
587 bool writeback_post =
false;
589 arm_reg base = insn->detail->arm.operands[mem_idx].mem.base;
590 if (
ISIMM(mem_idx + 1)) {
592 addr = insn->detail->arm.operands[mem_idx + 1].subtracted
595 writeback_post =
true;
598 if (!writeback_eff) {
637 if (writeback_post) {
651 return writeback_post ?
SEQ2(eff, writeback_eff) :
SEQ2(writeback_eff, eff);
670 bool writeback = insn->detail->arm.writeback;
671 if (
ISIMM(mem_idx + 1)) {
676 bool writeback_post =
false;
678 arm_reg base = insn->detail->arm.operands[mem_idx].mem.base;
679 if (
ISIMM(mem_idx + 1)) {
681 addr = insn->detail->arm.operands[mem_idx + 1].subtracted
684 writeback_post =
true;
687 if (!writeback_eff) {
726 return writeback_post ?
SEQ2(eff, writeback_eff) :
SEQ2(writeback_eff, eff);
745 if (!
addr || !
val || !ret_eff) {
777 return SEQ2(eff, ret_eff);
822 if (insn->detail->arm.update_flags) {
958 SETG(
"cf", (is_sub ? sub_carry : add_carry)(
VARL(
"a"),
VARL(
"b"),
false, 32)),
959 SETG(
"vf", (is_sub ? sub_overflow : add_overflow)(
VARL(
"a"),
VARL(
"b"),
VARL(
"res"))),
984 size_t op_count =
OPCOUNT() - op_first;
1002 ?
SUB(
DUP(ptr),
U32(op_count * regsize))
1003 :
ADD(
DUP(ptr),
U32(op_count * regsize)));
1005 for (
size_t i = 0;
i < op_count;
i++) {
1006 size_t idx = op_first + (op_count - 1 -
i);
1015 ?
SUB(
DUP(ptr),
U32((
i + (before ? 1 : 0)) * regsize))
1016 :
ADD(
DUP(ptr),
U32((op_count -
i - (before ? 0 : 1)) * regsize)),
1018 eff = eff ?
SEQ2(store, eff) : store;
1043 writeback = insn->detail->arm.writeback;
1045 size_t op_count =
OPCOUNT() - op_first;
1055 for (
size_t i = 0;
i < op_count;
i++) {
1056 size_t idx = op_first + (op_count - 1 -
i);
1069 :
ADD(
VARL(
"base"),
U32(op_count * regsize)));
1070 eff = eff ?
SEQ2(wb, eff) : wb;
1072 for (
size_t i = 0;
i < op_count;
i++) {
1073 size_t idx = op_first + (op_count - 1 -
i);
1081 ?
SUB(
VARL(
"base"),
U32((
i + (before ? 1 : 0)) * regsize))
1082 :
ADD(
VARL(
"base"),
U32((op_count -
i - (before ? 0 : 1)) * regsize)));
1091 return SEQ2(
SETL(
"base", ptr_initial), eff);
1104 SETG(
"lr",
U32(((insn->address + insn->size) & ~1ul) | (
is_thumb ? 1 : 0))),
1142 #if CS_API_MAJOR > 3
1181 if (!dval || !nval) {
1224 if (!op0 || !op1 || !addend) {
1231 ?
SUB(addend,
MUL(op0, op1))
1232 :
ADD(
MUL(op0, op1), addend);
1237 return insn->detail->arm.update_flags
1274 bool update_f =
false;
1275 bool update_s =
false;
1292 if (!update_f && !update_s) {
1449 return dbl ?
SEQ2(dbl, eff) : eff;
1509 return SEQ3(
saturate(is_signed, l_sub,
"rl", 16, l, 17,
false),
saturate(is_signed, h_sub,
"rh", 16,
h, 17,
false), eff);
1535 saturate(is_signed, is_sub,
"rb0", 8,
1540 saturate(is_signed, is_sub,
"rb1", 8,
1543 :
ADD(
cast(9,
UNSIGNED(8,
SHIFTR0(
DUP(
a),
UN(5, 8)))),
cast(9,
UNSIGNED(8,
SHIFTR0(
DUP(
b),
UN(5, 8))))),
1545 saturate(is_signed, is_sub,
"rb2", 8,
1548 :
ADD(
cast(9,
UNSIGNED(8,
SHIFTR0(
DUP(
a),
UN(5, 16)))),
cast(9,
UNSIGNED(8,
SHIFTR0(
DUP(
b),
UN(5, 16))))),
1550 saturate(is_signed, is_sub,
"rb3", 8,
1553 :
ADD(
cast(9,
UNSIGNED(8,
SHIFTR0(
DUP(
a),
UN(5, 24)))),
cast(9,
UNSIGNED(8,
SHIFTR0(
DUP(
b),
UN(5, 24))))),
1636 if (insn->detail->arm.writeback) {
1729 bool set_ge = !halve;
1740 ut64 tval = is_signed ? 0 : 3;
1741 ut64 fval = 3 - tval;
1802 bool set_ge = !halve;
1808 r0->op.add.x =
cast(9,
r0->op.add.x);
1809 r0->op.add.y =
cast(9,
r0->op.add.y);
1810 r1->op.add.x =
cast(9,
r1->op.add.x);
1811 r1->op.add.y =
cast(9,
r1->op.add.y);
1812 r2->op.add.x =
cast(9,
r2->op.add.x);
1813 r2->op.add.y =
cast(9,
r2->op.add.y);
1814 r3->op.add.x =
cast(9,
r3->op.add.x);
1815 r3->op.add.y =
cast(9,
r3->op.add.y);
1844 ut64 tval = is_signed ? 0 : 1;
1845 ut64 fval = 1 - tval;
1963 if (!dl || !dh || !
a || !
b || !wl || !wh) {
1989 if (!
a || !
b || !wl || !wh) {
1996 if (insn->detail->arm.update_flags) {
2021 if (!
a || !
b || (have_acc && !acc)) {
2036 sum =
ADD(acc, sum);
2052 if (!ra || !rb || !acc) {
2079 :
ADD(proda, prodb);
2112 if (!dl || !dh || !ra || !rb || !wl || !wh) {
2151 product =
MUL(
a,
b);
2154 return insn->detail->arm.update_flags
2172 if (!
a || !
b || !acc || !rres || !eff) {
2200 if (!
a || !
b || !acc) {
2210 res =
ADD(res,
U64(0x80000000));
2232 res =
ADD(res,
U64(0x80000000));
2248 if (!ra || !rb || !eff) {
2484 #if CS_API_MAJOR > 3
RZ_API void rz_analysis_il_config_add_label(RZ_NONNULL RzAnalysisILConfig *cfg, RZ_NONNULL RZ_OWN RzILEffectLabel *label)
RZ_API RZ_OWN RzAnalysisILConfig * rz_analysis_il_config_new(ut32 pc_size, bool big_endian, ut32 mem_key_size)
static void update_flags(RzAnalysisOp *op, int flags)
static RzILOpEffect * bfi(cs_insn *insn, bool is_thumb)
static RzILOpEffect * mrs(cs_insn *insn, bool is_thumb)
static RzILOpEffect * strex(cs_insn *insn, bool is_thumb)
static RzILOpEffect * vmov(cs_insn *insn, bool is_thumb)
static RzILOpEffect * bitwise(cs_insn *insn, bool is_thumb)
static RzILOpEffect * sadd16(cs_insn *insn, bool is_thumb)
static RzILOpEffect * rfe(cs_insn *insn, bool is_thumb)
static RzILOpEffect * clz(cs_insn *insn, bool is_thumb)
static RzILOpEffect * smlal(cs_insn *insn, bool is_thumb)
static RzILOpEffect * write_reg(arm_reg reg, RZ_OWN RZ_NONNULL RzILOpBitVector *v)
static RzILOpEffect * adr(cs_insn *insn, bool is_thumb)
static const char * regs_bound_32[]
static RzILOpEffect * msr(cs_insn *insn, bool is_thumb)
static RzILOpEffect * sbfx(cs_insn *insn, bool is_thumb)
static RzILOpEffect * sdiv(cs_insn *insn, bool is_thumb)
static RzILOpEffect * uxt16(cs_insn *insn, bool is_thumb)
static RzILOpEffect * qadd8(cs_insn *insn, bool is_thumb)
static RzILOpEffect * cmp(cs_insn *insn, bool is_thumb)
static RzILOpEffect * rev(cs_insn *insn, bool is_thumb)
static RzILOpEffect * smlaw(cs_insn *insn, bool is_thumb)
static RzILOpEffect * ssat16(cs_insn *insn, bool is_thumb)
static RzILOpEffect * sadd8(cs_insn *insn, bool is_thumb)
static RzILOpBitVector * absdiff(RzILOpBitVector *a, RzILOpBitVector *b)
static RzILOpBitVector * read_reg(ut64 pc, arm_reg reg)
static void label_hvc(RzILVM *vm, RzILOpEffect *op)
static RzILOpEffect * uxt(cs_insn *insn, bool is_thumb)
static RzILOpEffect * smmla(cs_insn *insn, bool is_thumb)
static RzILOpBitVector * arg_mem(RzILOpBitVector *base_plus_disp, cs_arm_op *op, RZ_NULLABLE RzILOpBool **carry_out)
static RzILOpEffect * movt(cs_insn *insn, bool is_thumb)
static RzILOpEffect * tst(cs_insn *insn, bool is_thumb)
static RzILOpEffect * svc(cs_insn *insn, bool is_thumb)
static RzILOpEffect * mla(cs_insn *insn, bool is_thumb)
#define PCALIGN(addr, is_thumb)
static RzILOpEffect * smlabb(cs_insn *insn, bool is_thumb)
static RzILOpEffect * tbb(cs_insn *insn, bool is_thumb)
static RzILOpEffect * smulbb(cs_insn *insn, bool is_thumb)
static bool is_reg_shift(arm_shifter type)
static RzILOpEffect * smmul(cs_insn *insn, bool is_thumb)
static RzILOpEffect * udiv(cs_insn *insn, bool is_thumb)
static RzILOpEffect * saturate_signed_to_range(const char *dst, ut32 bits, RzILOpBitVector *val, ut32 ext_bits, bool set_q, st64 min, st64 max)
RZ_IPI RzAnalysisILConfig * rz_arm_cs_32_il_config(bool big_endian)
static RzILOpEffect * saturate_signed(bool to_signed, const char *dst, ut32 bits, RzILOpBitVector *val, ut32 ext_bits, bool set_q)
static void label_svc(RzILVM *vm, RzILOpEffect *op)
static RzILOpEffect * bl(cs_insn *insn, bool is_thumb)
static RzILOpEffect * bfc(cs_insn *insn, bool is_thumb)
static RzILOpEffect * revsh(cs_insn *insn, bool is_thumb)
static RzILOpEffect * usad8(cs_insn *insn, bool is_thumb)
static RzILOpEffect * str(cs_insn *insn, bool is_thumb)
static RzILOpEffect * ldm(cs_insn *insn, bool is_thumb)
static RzILOpEffect * qadd(cs_insn *insn, bool is_thumb)
static RzILOpEffect * il_unconditional(csh *handle, cs_insn *insn, bool is_thumb)
static const char * reg_var_name(arm_reg reg)
static RzILOpEffect * ldr(cs_insn *insn, bool is_thumb)
static RzILOpEffect * saturate(bool sign, bool is_sub, const char *dst, ut32 bits, RzILOpBitVector *val, ut32 ext_bits, bool set_q)
static RzILOpEffect * umull(cs_insn *insn, bool is_thumb)
static RzILOpEffect * update_flags_from_cpsr(RzILOpBitVector *val, bool f, bool s)
static RzILOpEffect * add_sub(cs_insn *insn, bool is_thumb)
static RZ_NULLABLE RzILOpBool * cond(arm_cc c)
static RzILOpEffect * ssat(cs_insn *insn, bool is_thumb)
static RzILOpBitVector * arg(cs_insn *insn, bool is_thumb, int n, RZ_NULLABLE RzILOpBool **carry_out)
RZ_IPI RzILOpEffect * rz_arm_cs_32_il(csh *handle, cs_insn *insn, bool thumb)
static RZ_NULLABLE RzILOpBitVector * shift(RzILOpBitVector *val, RZ_NULLABLE RzILOpBool **carry_out, arm_shifter type, RZ_OWN RzILOpBitVector *dist)
#define PC(addr, is_thumb)
static ut32 reg_bits(arm_reg reg)
static RzILOpEffect * qadd16(cs_insn *insn, bool is_thumb)
static RzILOpEffect * sel(cs_insn *insn, bool is_thumb)
static RzILOpEffect * mov(cs_insn *insn, bool is_thumb)
static RzILOpEffect * saturate_unsigned(bool is_sub, const char *dst, ut32 bits, RzILOpBitVector *val, ut32 ext_bits, bool set_q)
static RzILOpEffect * pkhbt(cs_insn *insn, bool is_thumb)
static RzILOpEffect * umaal(cs_insn *insn, bool is_thumb)
static RzILOpEffect * cbz(cs_insn *insn, bool is_thumb)
static RzILOpEffect * rbit(cs_insn *insn, bool is_thumb)
static RzILOpEffect * update_flags_zn(RzILOpBitVector *v)
static RzILOpEffect * stm(cs_insn *insn, bool is_thumb)
static RzILOpEffect * mul(cs_insn *insn, bool is_thumb)
static RzILOpEffect * smuad(cs_insn *insn, bool is_thumb)
static RzILOpEffect * writeback(cs_insn *insn, size_t addr_op, RZ_BORROW RzILOpBitVector *addr)
static RzILOpEffect * hvc(cs_insn *insn)
static mcore_handle handle
int bits(struct state *s, int need)
arm_shifter
ARM shift type.
@ ARM_SFT_ROR_REG
shift with register
@ ARM_SFT_ASR
shift with immediate const
@ ARM_SFT_LSR_REG
shift with register
@ ARM_SFT_LSL_REG
shift with register
@ ARM_SFT_ROR
shift with immediate const
@ ARM_SFT_LSL
shift with immediate const
@ ARM_SFT_RRX_REG
shift with register
@ ARM_SFT_LSR
shift with immediate const
@ ARM_SFT_RRX
shift with immediate const
@ ARM_SFT_ASR_REG
shift with register
@ ARM_OP_IMM
= CS_OP_IMM (Immediate operand).
@ ARM_OP_REG
= CS_OP_REG (Register operand).
@ ARM_OP_MEM
= CS_OP_MEM (Memory operand).
@ ARM_OP_SYSREG
MSR/MRS special register operand.
arm_cc
ARM condition code.
@ ARM_CC_GT
Greater than Greater than.
@ ARM_CC_LE
Less than or equal <, ==, or unordered.
@ ARM_CC_AL
Always (unconditional) Always (unconditional)
@ ARM_CC_HI
Unsigned higher Greater than, or unordered.
@ ARM_CC_VC
No overflow Not unordered.
@ ARM_CC_LS
Unsigned lower or same Less than or equal.
@ ARM_CC_GE
Greater than or equal Greater than or equal.
@ ARM_CC_VS
Overflow Unordered.
@ ARM_CC_PL
Plus, positive or zero >, ==, or unordered.
@ ARM_CC_NE
Not equal Not equal, or unordered.
@ ARM_CC_LO
Carry clear Less than.
@ ARM_CC_LT
Less than Less than, or unordered.
@ ARM_CC_HS
Carry set >, ==, or unordered.
@ ARM_CC_MI
Minus, negative Less than.
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
RZ_API void rz_il_op_pure_free(RZ_NULLABLE RzILOpPure *op)
RZ_API RZ_OWN RzILOpBitVector * rz_il_op_new_signed(ut32 length, RZ_NONNULL RzILOpBitVector *val)
Extend val to length bits, filling up with val's most significant bit.
RZ_API void rz_il_op_effect_free(RZ_NULLABLE RzILOpEffect *op)
RZ_API RZ_OWN RzILOpBitVector * rz_il_op_new_unsigned(ut32 length, RZ_NONNULL RzILOpBitVector *val)
Extend val to length bits, filling up with zeroes.
RZ_API RzILEffectLabel * rz_il_effect_label_new(RZ_NONNULL const char *name, RzILEffectLabelType type)
static bool is_thumb(RzBinFile *bf)
void * load(const char *name, size_t *len)
#define rz_return_val_if_fail(expr, val)
Syntax Macros for RzIL Lifting.
#define APPEND(high, low)
#define LET(name, v, body)
#define STOREW(addr, val)
#define SEQ5(e0, e1, e2, e3, e4)
#define SEQ4(e0, e1, e2, e3)
#define SHIFTR(f, v, dist)
#define SEQ6(e0, e1, e2, e3, e4, e5)
static ut64 rz_num_bitmask(ut8 width)
Get the 64-bit value that has exactly its width lowest bits set to 1. e.g. rz_num_bitmask(2) == 0b11 ...
arm_reg base
base register
arm_op_mem mem
base/index/scale/disp value for MEM operand
Description of the global context of an RzAnalysisILVM.
void * hook
Function pointer if EFFECT_LABEL_SYSCALL / EFFECT_LABEL_HOOK.
An IL op performing a pure computation, 'a pure.
Low-level VM to execute raw IL code.
ut64(WINAPI *w32_GetEnabledXStateFeatures)()