Skip to content

Commit

Permalink
Fix arm64 analysis to fix regression on ARM64 switch tables. (#4284)
Browse files Browse the repository at this point in the history
* Bump capstone next
* Fix arm64 analysis to fix regression on ARM64 switch tables.
* Fix tests
  • Loading branch information
wargio authored Feb 23, 2024
1 parent a6c7864 commit 78d4043
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 11 deletions.
68 changes: 61 additions & 7 deletions librz/analysis/p/analysis_arm_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,15 @@ inline static const char *ARMCondCodeToString(arm_cc cc) {
return "al";
}
}
#endif
#else /* CS_NEXT_VERSION >= 6 */
static inline bool is_alias64(cs_insn *insn, aarch64_insn alias_id) {
return insn->is_alias && (insn->alias_id == alias_id);
}

static inline bool is_alias32(cs_insn *insn, arm_insn alias_id) {
return insn->is_alias && (insn->alias_id == alias_id);
}
#endif /* CS_NEXT_VERSION < 6 */

typedef struct arm_cs_context_t {
RzArmITContext it; ///< Save IT values between instruction disassembly.
Expand Down Expand Up @@ -991,8 +999,43 @@ static void anop64(ArmCSContext *ctx, RzAnalysisOp *op, cs_insn *insn) {
case CS_AARCH64(_INS_CMN):
case CS_AARCH64(_INS_TST):
#endif
if (ISIMM64(1)) {
op->val = IMM64(1);
}
op->type = RZ_ANALYSIS_OP_TYPE_CMP;
break;
#if CS_NEXT_VERSION >= 6
case CS_AARCH64(_INS_ADDS):
if (is_alias64(insn, AArch64_INS_ALIAS_CMN)) {
op->type = RZ_ANALYSIS_OP_TYPE_CMP;
} else {
op->type = RZ_ANALYSIS_OP_TYPE_ADD;
}
if (ISIMM64(1)) {
op->val = IMM64(1);
}
break;
case CS_AARCH64(_INS_SUBS):
if (is_alias64(insn, AArch64_INS_ALIAS_CMP)) {
op->type = RZ_ANALYSIS_OP_TYPE_CMP;
} else {
op->type = RZ_ANALYSIS_OP_TYPE_SUB;
}
if (ISIMM64(1)) {
op->val = IMM64(1);
}
break;
case CS_AARCH64(_INS_ANDS):
if (is_alias64(insn, AArch64_INS_ALIAS_TST)) {
op->type = RZ_ANALYSIS_OP_TYPE_CMP;
} else {
op->type = RZ_ANALYSIS_OP_TYPE_AND;
}
if (ISIMM64(1)) {
op->val = IMM64(1);
}
break;
#endif
case CS_AARCH64(_INS_ROR):
op->cycles = 1;
op->type = RZ_ANALYSIS_OP_TYPE_ROR;
Expand Down Expand Up @@ -1175,8 +1218,13 @@ static void anop64(ArmCSContext *ctx, RzAnalysisOp *op, cs_insn *insn) {
op->jump = IMM64(0);
}
break;
#if CS_NEXT_VERSION >= 6
case CS_AARCH64(_INS_UDF):
op->type = RZ_ANALYSIS_OP_TYPE_ILL;
break;
#endif
default:
RZ_LOG_DEBUG("ARM64 analysis: Op type %d at 0x%" PFMT64x " not handled\n", insn->id, op->addr);
RZ_LOG_DEBUG("ARM64 analysis: Op type %d (%s) at 0x%" PFMT64x " not handled\n", insn->id, insn->mnemonic, op->addr);
break;
}
}
Expand Down Expand Up @@ -1293,7 +1341,7 @@ jmp $$ + 4 + ( [delta] * 2 )
case ARM_INS_NOP:
#else
case ARM_INS_HINT:
if (insn->alias_id != ARM_INS_ALIAS_NOP) {
if (!is_alias32(insn, ARM_INS_ALIAS_NOP)) {
break;
}
#endif
Expand All @@ -1313,7 +1361,9 @@ jmp $$ + 4 + ( [delta] * 2 )
case ARM_INS_LDMIB:
case ARM_INS_LDM:
#if CS_NEXT_VERSION >= 6
if (insn->alias_id == ARM_INS_ALIAS_POP || insn->alias_id == ARM_INS_ALIAS_POPW || insn->alias_id == ARM_INS_ALIAS_VPOP) {
if (is_alias32(insn, ARM_INS_ALIAS_POP) ||
is_alias32(insn, ARM_INS_ALIAS_POPW) ||
is_alias32(insn, ARM_INS_ALIAS_VPOP)) {
op->type = RZ_ANALYSIS_OP_TYPE_POP;
op->stackop = RZ_ANALYSIS_STACK_DEC;
op->stackptr = -4LL * (insn->detail->arm.op_count - 1);
Expand Down Expand Up @@ -1501,7 +1551,9 @@ jmp $$ + 4 + ( [delta] * 2 )
case ARM_INS_STMDA:
case ARM_INS_STMDB:
#if CS_NEXT_VERSION >= 6
if (insn->alias_id == ARM_INS_ALIAS_PUSH || insn->alias_id == ARM_INS_ALIAS_PUSHW || insn->alias_id == ARM_INS_ALIAS_VPUSH) {
if (is_alias32(insn, ARM_INS_ALIAS_PUSH) ||
is_alias32(insn, ARM_INS_ALIAS_PUSHW) ||
is_alias32(insn, ARM_INS_ALIAS_VPUSH)) {
op->type = RZ_ANALYSIS_OP_TYPE_PUSH;
op->stackop = RZ_ANALYSIS_STACK_INC;
op->stackptr = 4LL * (insn->detail->arm.op_count - 1);
Expand Down Expand Up @@ -1534,7 +1586,8 @@ jmp $$ + 4 + ( [delta] * 2 )
case ARM_INS_STRT:
op->cycles = 4;
#if CS_NEXT_VERSION >= 6
if (insn->alias_id == ARM_INS_ALIAS_PUSH || insn->alias_id == ARM_INS_ALIAS_PUSHW) {
if (is_alias32(insn, ARM_INS_ALIAS_PUSH) ||
is_alias32(insn, ARM_INS_ALIAS_PUSHW)) {
op->type = RZ_ANALYSIS_OP_TYPE_PUSH;
op->stackop = RZ_ANALYSIS_STACK_INC;
op->stackptr = 4LL * (insn->detail->arm.op_count - 1);
Expand Down Expand Up @@ -1572,7 +1625,8 @@ jmp $$ + 4 + ( [delta] * 2 )
case ARM_INS_LDRT:
op->cycles = 4;
#if CS_NEXT_VERSION >= 6
if (insn->alias_id == ARM_INS_ALIAS_POP || insn->alias_id == ARM_INS_ALIAS_POPW) {
if (is_alias32(insn, ARM_INS_ALIAS_POP) ||
is_alias32(insn, ARM_INS_ALIAS_POPW)) {
op->type = RZ_ANALYSIS_OP_TYPE_POP;
op->stackop = RZ_ANALYSIS_STACK_DEC;
op->stackptr = -4LL * (insn->detail->arm.op_count - 1);
Expand Down
2 changes: 1 addition & 1 deletion subprojects/capstone-next.wrap
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[wrap-git]
url = https://github.com/capstone-engine/capstone.git
revision = 34a1e012b7eb8a3b03971cdf2d32b603855d5b09
revision = b4fde983de9d14c038afef88e79fe1111388e569
directory = capstone-next
patch_directory = capstone-next
depth = 1
2 changes: 1 addition & 1 deletion test/db/analysis/golang
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,7 @@ EXPECT=<<EOF
0x100006e64 str.pointer
0x100006eac str.panicwrap:_no___in
0x1000076d0 str.internal_error___misuse_of_itab
1710
1709
0x10008bada 31 31 slice bounds out of range [:%x]
0x10008babb 31 31 slice bounds out of range [%x:]
0x10008be19 32 32 slice bounds out of range [::%x]
Expand Down
4 changes: 2 additions & 2 deletions test/db/cmd/cmd_plf
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ EXPECT=<<EOF
0x30 (seq (set addr (+ (var x8) (bv 64 0x8))) (set x14 (cast 64 false (loadw 0 32 (var addr)))) (set x8 (cast 64 false (loadw 0 32 (+ (var addr) (bv 64 0x4))))))
0x34 (set x14 (cast 64 false (^ (cast 32 false (var x10)) (cast 32 false (var x14)))))
0x38 (set x15 (cast 64 false (^ (cast 32 false (var x11)) (cast 32 false (var x8)))))
0x3c (set x8 (bv 64 0x5fe60))
0x3c (set x8 (bv 64 0x5fe9c))
0x40 nop
0x44 (seq (set a (cast 32 false (var x9))) (set b (bv 32 0xa)) (set r (- (var a) (var b))) (set cf (ule (var b) (var a))) (set vf (&& (^^ (msb (var a)) (msb (var b))) (^^ (msb (var a)) (msb (var r))))) (set zf (is_zero (var r))) (set nf (msb (var r))))
0x48 (branch (var zf) (jmp (bv 64 0x394)) nop)
Expand Down Expand Up @@ -727,7 +727,7 @@ EXPECT=<<EOF
0xaa0 (set x8 (cast 64 false (^ (cast 32 false (var x8)) (cast 32 false (var x10)))))
0xaa4 (set x8 (cast 64 false (^ (cast 32 false (var x8)) (cast 32 false (var x11)))))
0xaa8 (set x9 (cast 64 false (& (cast 32 false (var x15)) (bv 32 0xff))))
0xaac (set x10 (bv 64 0x603f0))
0xaac (set x10 (bv 64 0x60e9c))
0xab0 nop
0xab4 (set x9 (cast 64 false (loadw 0 32 (+ (var x10) (<< (cast 64 false (cast 32 false (var x9))) (bv 6 0x2) false)))))
0xab8 (set x11 (cast 64 false (let res (cast 8 false (>> (cast 32 false (var x8)) (bv 6 0x8) false)) (cast 32 false (var res)))))
Expand Down

0 comments on commit 78d4043

Please sign in to comment.