From 78d4043afb39a56fe91ea7ab03c83da613319cc3 Mon Sep 17 00:00:00 2001 From: Giovanni <561184+wargio@users.noreply.github.com> Date: Sat, 24 Feb 2024 00:00:12 +0800 Subject: [PATCH] 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 --- librz/analysis/p/analysis_arm_cs.c | 68 +++++++++++++++++++++++++++--- subprojects/capstone-next.wrap | 2 +- test/db/analysis/golang | 2 +- test/db/cmd/cmd_plf | 4 +- 4 files changed, 65 insertions(+), 11 deletions(-) diff --git a/librz/analysis/p/analysis_arm_cs.c b/librz/analysis/p/analysis_arm_cs.c index 8cd895323fd..f31c36b5d25 100644 --- a/librz/analysis/p/analysis_arm_cs.c +++ b/librz/analysis/p/analysis_arm_cs.c @@ -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. @@ -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; @@ -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; } } @@ -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 @@ -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); @@ -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); @@ -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); @@ -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); diff --git a/subprojects/capstone-next.wrap b/subprojects/capstone-next.wrap index e826847a4e4..ceefbed490c 100644 --- a/subprojects/capstone-next.wrap +++ b/subprojects/capstone-next.wrap @@ -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 diff --git a/test/db/analysis/golang b/test/db/analysis/golang index 60bc1415a02..6bcf1703165 100644 --- a/test/db/analysis/golang +++ b/test/db/analysis/golang @@ -648,7 +648,7 @@ EXPECT=<> (cast 32 false (var x8)) (bv 6 0x8) false)) (cast 32 false (var res)))))