Skip to content

Commit 78d4043

Browse files
authored
Fix arm64 analysis to fix regression on ARM64 switch tables. (#4284)
* Bump capstone next * Fix arm64 analysis to fix regression on ARM64 switch tables. * Fix tests
1 parent a6c7864 commit 78d4043

File tree

4 files changed

+65
-11
lines changed

4 files changed

+65
-11
lines changed

librz/analysis/p/analysis_arm_cs.c

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,15 @@ inline static const char *ARMCondCodeToString(arm_cc cc) {
5252
return "al";
5353
}
5454
}
55-
#endif
55+
#else /* CS_NEXT_VERSION >= 6 */
56+
static inline bool is_alias64(cs_insn *insn, aarch64_insn alias_id) {
57+
return insn->is_alias && (insn->alias_id == alias_id);
58+
}
59+
60+
static inline bool is_alias32(cs_insn *insn, arm_insn alias_id) {
61+
return insn->is_alias && (insn->alias_id == alias_id);
62+
}
63+
#endif /* CS_NEXT_VERSION < 6 */
5664

5765
typedef struct arm_cs_context_t {
5866
RzArmITContext it; ///< Save IT values between instruction disassembly.
@@ -991,8 +999,43 @@ static void anop64(ArmCSContext *ctx, RzAnalysisOp *op, cs_insn *insn) {
991999
case CS_AARCH64(_INS_CMN):
9921000
case CS_AARCH64(_INS_TST):
9931001
#endif
1002+
if (ISIMM64(1)) {
1003+
op->val = IMM64(1);
1004+
}
9941005
op->type = RZ_ANALYSIS_OP_TYPE_CMP;
9951006
break;
1007+
#if CS_NEXT_VERSION >= 6
1008+
case CS_AARCH64(_INS_ADDS):
1009+
if (is_alias64(insn, AArch64_INS_ALIAS_CMN)) {
1010+
op->type = RZ_ANALYSIS_OP_TYPE_CMP;
1011+
} else {
1012+
op->type = RZ_ANALYSIS_OP_TYPE_ADD;
1013+
}
1014+
if (ISIMM64(1)) {
1015+
op->val = IMM64(1);
1016+
}
1017+
break;
1018+
case CS_AARCH64(_INS_SUBS):
1019+
if (is_alias64(insn, AArch64_INS_ALIAS_CMP)) {
1020+
op->type = RZ_ANALYSIS_OP_TYPE_CMP;
1021+
} else {
1022+
op->type = RZ_ANALYSIS_OP_TYPE_SUB;
1023+
}
1024+
if (ISIMM64(1)) {
1025+
op->val = IMM64(1);
1026+
}
1027+
break;
1028+
case CS_AARCH64(_INS_ANDS):
1029+
if (is_alias64(insn, AArch64_INS_ALIAS_TST)) {
1030+
op->type = RZ_ANALYSIS_OP_TYPE_CMP;
1031+
} else {
1032+
op->type = RZ_ANALYSIS_OP_TYPE_AND;
1033+
}
1034+
if (ISIMM64(1)) {
1035+
op->val = IMM64(1);
1036+
}
1037+
break;
1038+
#endif
9961039
case CS_AARCH64(_INS_ROR):
9971040
op->cycles = 1;
9981041
op->type = RZ_ANALYSIS_OP_TYPE_ROR;
@@ -1175,8 +1218,13 @@ static void anop64(ArmCSContext *ctx, RzAnalysisOp *op, cs_insn *insn) {
11751218
op->jump = IMM64(0);
11761219
}
11771220
break;
1221+
#if CS_NEXT_VERSION >= 6
1222+
case CS_AARCH64(_INS_UDF):
1223+
op->type = RZ_ANALYSIS_OP_TYPE_ILL;
1224+
break;
1225+
#endif
11781226
default:
1179-
RZ_LOG_DEBUG("ARM64 analysis: Op type %d at 0x%" PFMT64x " not handled\n", insn->id, op->addr);
1227+
RZ_LOG_DEBUG("ARM64 analysis: Op type %d (%s) at 0x%" PFMT64x " not handled\n", insn->id, insn->mnemonic, op->addr);
11801228
break;
11811229
}
11821230
}
@@ -1293,7 +1341,7 @@ jmp $$ + 4 + ( [delta] * 2 )
12931341
case ARM_INS_NOP:
12941342
#else
12951343
case ARM_INS_HINT:
1296-
if (insn->alias_id != ARM_INS_ALIAS_NOP) {
1344+
if (!is_alias32(insn, ARM_INS_ALIAS_NOP)) {
12971345
break;
12981346
}
12991347
#endif
@@ -1313,7 +1361,9 @@ jmp $$ + 4 + ( [delta] * 2 )
13131361
case ARM_INS_LDMIB:
13141362
case ARM_INS_LDM:
13151363
#if CS_NEXT_VERSION >= 6
1316-
if (insn->alias_id == ARM_INS_ALIAS_POP || insn->alias_id == ARM_INS_ALIAS_POPW || insn->alias_id == ARM_INS_ALIAS_VPOP) {
1364+
if (is_alias32(insn, ARM_INS_ALIAS_POP) ||
1365+
is_alias32(insn, ARM_INS_ALIAS_POPW) ||
1366+
is_alias32(insn, ARM_INS_ALIAS_VPOP)) {
13171367
op->type = RZ_ANALYSIS_OP_TYPE_POP;
13181368
op->stackop = RZ_ANALYSIS_STACK_DEC;
13191369
op->stackptr = -4LL * (insn->detail->arm.op_count - 1);
@@ -1501,7 +1551,9 @@ jmp $$ + 4 + ( [delta] * 2 )
15011551
case ARM_INS_STMDA:
15021552
case ARM_INS_STMDB:
15031553
#if CS_NEXT_VERSION >= 6
1504-
if (insn->alias_id == ARM_INS_ALIAS_PUSH || insn->alias_id == ARM_INS_ALIAS_PUSHW || insn->alias_id == ARM_INS_ALIAS_VPUSH) {
1554+
if (is_alias32(insn, ARM_INS_ALIAS_PUSH) ||
1555+
is_alias32(insn, ARM_INS_ALIAS_PUSHW) ||
1556+
is_alias32(insn, ARM_INS_ALIAS_VPUSH)) {
15051557
op->type = RZ_ANALYSIS_OP_TYPE_PUSH;
15061558
op->stackop = RZ_ANALYSIS_STACK_INC;
15071559
op->stackptr = 4LL * (insn->detail->arm.op_count - 1);
@@ -1534,7 +1586,8 @@ jmp $$ + 4 + ( [delta] * 2 )
15341586
case ARM_INS_STRT:
15351587
op->cycles = 4;
15361588
#if CS_NEXT_VERSION >= 6
1537-
if (insn->alias_id == ARM_INS_ALIAS_PUSH || insn->alias_id == ARM_INS_ALIAS_PUSHW) {
1589+
if (is_alias32(insn, ARM_INS_ALIAS_PUSH) ||
1590+
is_alias32(insn, ARM_INS_ALIAS_PUSHW)) {
15381591
op->type = RZ_ANALYSIS_OP_TYPE_PUSH;
15391592
op->stackop = RZ_ANALYSIS_STACK_INC;
15401593
op->stackptr = 4LL * (insn->detail->arm.op_count - 1);
@@ -1572,7 +1625,8 @@ jmp $$ + 4 + ( [delta] * 2 )
15721625
case ARM_INS_LDRT:
15731626
op->cycles = 4;
15741627
#if CS_NEXT_VERSION >= 6
1575-
if (insn->alias_id == ARM_INS_ALIAS_POP || insn->alias_id == ARM_INS_ALIAS_POPW) {
1628+
if (is_alias32(insn, ARM_INS_ALIAS_POP) ||
1629+
is_alias32(insn, ARM_INS_ALIAS_POPW)) {
15761630
op->type = RZ_ANALYSIS_OP_TYPE_POP;
15771631
op->stackop = RZ_ANALYSIS_STACK_DEC;
15781632
op->stackptr = -4LL * (insn->detail->arm.op_count - 1);

subprojects/capstone-next.wrap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[wrap-git]
22
url = https://github.com/capstone-engine/capstone.git
3-
revision = 34a1e012b7eb8a3b03971cdf2d32b603855d5b09
3+
revision = b4fde983de9d14c038afef88e79fe1111388e569
44
directory = capstone-next
55
patch_directory = capstone-next
66
depth = 1

test/db/analysis/golang

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,7 @@ EXPECT=<<EOF
648648
0x100006e64 str.pointer
649649
0x100006eac str.panicwrap:_no___in
650650
0x1000076d0 str.internal_error___misuse_of_itab
651-
1710
651+
1709
652652
0x10008bada 31 31 slice bounds out of range [:%x]
653653
0x10008babb 31 31 slice bounds out of range [%x:]
654654
0x10008be19 32 32 slice bounds out of range [::%x]

test/db/cmd/cmd_plf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ EXPECT=<<EOF
5959
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))))))
6060
0x34 (set x14 (cast 64 false (^ (cast 32 false (var x10)) (cast 32 false (var x14)))))
6161
0x38 (set x15 (cast 64 false (^ (cast 32 false (var x11)) (cast 32 false (var x8)))))
62-
0x3c (set x8 (bv 64 0x5fe60))
62+
0x3c (set x8 (bv 64 0x5fe9c))
6363
0x40 nop
6464
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))))
6565
0x48 (branch (var zf) (jmp (bv 64 0x394)) nop)
@@ -727,7 +727,7 @@ EXPECT=<<EOF
727727
0xaa0 (set x8 (cast 64 false (^ (cast 32 false (var x8)) (cast 32 false (var x10)))))
728728
0xaa4 (set x8 (cast 64 false (^ (cast 32 false (var x8)) (cast 32 false (var x11)))))
729729
0xaa8 (set x9 (cast 64 false (& (cast 32 false (var x15)) (bv 32 0xff))))
730-
0xaac (set x10 (bv 64 0x603f0))
730+
0xaac (set x10 (bv 64 0x60e9c))
731731
0xab0 nop
732732
0xab4 (set x9 (cast 64 false (loadw 0 32 (+ (var x10) (<< (cast 64 false (cast 32 false (var x9))) (bv 6 0x2) false)))))
733733
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)))))

0 commit comments

Comments
 (0)