From bf1713d9e011b55ca1f502a6779fc4722b4bb077 Mon Sep 17 00:00:00 2001 From: lazymio Date: Tue, 30 Mar 2021 12:06:26 +0800 Subject: [PATCH] Add arm ite blocks samples from #853 (#1381) --- samples/sample_arm.c | 68 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/samples/sample_arm.c b/samples/sample_arm.c index 1e142c13..bcaabc8d 100644 --- a/samples/sample_arm.c +++ b/samples/sample_arm.c @@ -11,6 +11,8 @@ #define ARM_CODE "\x37\x00\xa0\xe3\x03\x10\x42\xe0" // mov r0, #0x37; sub r1, r2, r3 #define THUMB_CODE "\x83\xb0" // sub sp, #0xc +#define ARM_THUM_COND_CODE "\x9a\x42\x14\xbf\x68\x22\x4d\x22" // 'cmp r2, r3\nit ne\nmov r2, #0x68\nmov r2, #0x4d' + // memory address where emulation starts #define ADDRESS 0x10000 @@ -130,6 +132,69 @@ static void test_thumb(void) uc_close(uc); } +static void test_thumb_ite() { + uc_engine *uc; + uc_err err; + + uint32_t sp = 0x1234; + uint32_t r2 = 0, r3 = 1; + uint32_t step_r2, step_r3; + + int i, addr=ADDRESS; + + printf("Emulate a THUMB ITE block as a whole or per instruction.\n"); + err = uc_open(UC_ARCH_ARM, UC_MODE_THUMB, &uc); + if (err) { + printf("Failed on uc_open() with error returned: %u (%s)\n", + err, uc_strerror(err)); + return; + } + + uc_mem_map(uc, ADDRESS, 2 * 1024 * 1024, UC_PROT_ALL); + + uc_mem_write(uc, ADDRESS, ARM_THUM_COND_CODE, sizeof(ARM_THUM_COND_CODE) - 1); + + uc_reg_write(uc, UC_ARM_REG_SP, &sp); + + uc_reg_write(uc, UC_ARM_REG_R2, &r2); + uc_reg_write(uc, UC_ARM_REG_R3, &r3); + + // Run once. + printf("Running the entire binary.\n"); + err = uc_emu_start(uc, ADDRESS | 1, ADDRESS + sizeof(ARM_THUM_COND_CODE) - 1, 0, 0); + if (err) { + printf("Failed on uc_emu_start() with error returned: %u\n", err); + } + uc_reg_read(uc, UC_ARM_REG_R2, &r2); + uc_reg_read(uc, UC_ARM_REG_R3, &r3); + + printf(">>> R2: %d\n", r2); + printf(">>> R3: %d\n\n", r3); + + // Step each instruction. + printf("Running the binary one instruction at a time.\n"); + for (i = 0; i < sizeof(ARM_THUM_COND_CODE) / 2; i++) { + err = uc_emu_start(uc, addr | 1, ADDRESS + sizeof(ARM_THUM_COND_CODE) - 1, 0, 1); + if (err) { + printf("Failed on uc_emu_start() with error returned: %u\n", err); + } + uc_reg_read(uc, UC_ARM_REG_PC, &addr); + } + + uc_reg_read(uc, UC_ARM_REG_R2, &step_r2); + uc_reg_read(uc, UC_ARM_REG_R3, &step_r3); + + printf(">>> R2: %d\n", step_r2); + printf(">>> R3: %d\n\n", step_r3); + + if (step_r2 != r2 || step_r3 != r3) { + printf("Failed with ARM ITE blocks stepping!\n"); + } + + uc_close(uc); +} + + int main(int argc, char **argv, char **envp) { // dynamically load shared library @@ -146,7 +211,8 @@ int main(int argc, char **argv, char **envp) test_arm(); printf("==========================\n"); test_thumb(); - + printf("==========================\n"); + test_thumb_ite(); // dynamically free shared library #ifdef DYNLOAD uc_dyn_free();