From 8c60d0dca511af1fbf7f7725c0a177e3c3c57a51 Mon Sep 17 00:00:00 2001 From: Ryan Hileman Date: Fri, 23 Oct 2015 00:10:38 -0700 Subject: [PATCH 1/2] allow setting x86 segment base to host-sized value --- qemu/target-i386/unicorn.c | 48 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/qemu/target-i386/unicorn.c b/qemu/target-i386/unicorn.c index 37e744b3..acac9638 100644 --- a/qemu/target-i386/unicorn.c +++ b/qemu/target-i386/unicorn.c @@ -260,22 +260,22 @@ int x86_reg_read(struct uc_struct *uc, unsigned int regid, void *value) *(int16_t *)value = READ_WORD(X86_CPU(uc, mycpu)->env.eip); break; case UC_X86_REG_CS: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_CS].base; + *(int32_t *)value = X86_CPU(uc, mycpu)->env.segs[R_CS].base; break; case UC_X86_REG_DS: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_DS].base; + *(int32_t *)value = X86_CPU(uc, mycpu)->env.segs[R_DS].base; break; case UC_X86_REG_SS: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_SS].base; + *(int32_t *)value = X86_CPU(uc, mycpu)->env.segs[R_SS].base; break; case UC_X86_REG_ES: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_ES].base; + *(int32_t *)value = X86_CPU(uc, mycpu)->env.segs[R_ES].base; break; case UC_X86_REG_FS: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_FS].base; + *(int32_t *)value = X86_CPU(uc, mycpu)->env.segs[R_FS].base; break; case UC_X86_REG_GS: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_GS].base; + *(int32_t *)value = X86_CPU(uc, mycpu)->env.segs[R_GS].base; break; } break; @@ -412,22 +412,22 @@ int x86_reg_read(struct uc_struct *uc, unsigned int regid, void *value) *(int16_t *)value = READ_WORD(X86_CPU(uc, mycpu)->env.eip); break; case UC_X86_REG_CS: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_CS].base; + *(int64_t *)value = X86_CPU(uc, mycpu)->env.segs[R_CS].base; break; case UC_X86_REG_DS: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_DS].base; + *(int64_t *)value = X86_CPU(uc, mycpu)->env.segs[R_DS].base; break; case UC_X86_REG_SS: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_SS].base; + *(int64_t *)value = X86_CPU(uc, mycpu)->env.segs[R_SS].base; break; case UC_X86_REG_ES: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_ES].base; + *(int64_t *)value = X86_CPU(uc, mycpu)->env.segs[R_ES].base; break; case UC_X86_REG_FS: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_FS].base; + *(int64_t *)value = X86_CPU(uc, mycpu)->env.segs[R_FS].base; break; case UC_X86_REG_GS: - *(int16_t *)value = X86_CPU(uc, mycpu)->env.segs[R_GS].base; + *(int64_t *)value = X86_CPU(uc, mycpu)->env.segs[R_GS].base; break; case UC_X86_REG_R8: *(int64_t *)value = READ_QWORD(X86_CPU(uc, mycpu)->env.regs[8]); @@ -660,22 +660,22 @@ int x86_reg_write(struct uc_struct *uc, unsigned int regid, const void *value) WRITE_WORD(X86_CPU(uc, mycpu)->env.eip, *(uint16_t *)value); break; case UC_X86_REG_CS: - X86_CPU(uc, mycpu)->env.segs[R_CS].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_CS].base = *(uint32_t *)value; break; case UC_X86_REG_DS: - X86_CPU(uc, mycpu)->env.segs[R_DS].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_DS].base = *(uint32_t *)value; break; case UC_X86_REG_SS: - X86_CPU(uc, mycpu)->env.segs[R_SS].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_SS].base = *(uint32_t *)value; break; case UC_X86_REG_ES: - X86_CPU(uc, mycpu)->env.segs[R_ES].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_ES].base = *(uint32_t *)value; break; case UC_X86_REG_FS: - X86_CPU(uc, mycpu)->env.segs[R_FS].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_FS].base = *(uint32_t *)value; break; case UC_X86_REG_GS: - X86_CPU(uc, mycpu)->env.segs[R_GS].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_GS].base = *(uint32_t *)value; break; } break; @@ -812,22 +812,22 @@ int x86_reg_write(struct uc_struct *uc, unsigned int regid, const void *value) WRITE_WORD(X86_CPU(uc, mycpu)->env.eip, *(uint16_t *)value); break; case UC_X86_REG_CS: - X86_CPU(uc, mycpu)->env.segs[R_CS].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_CS].base = *(uint64_t *)value; break; case UC_X86_REG_DS: - X86_CPU(uc, mycpu)->env.segs[R_DS].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_DS].base = *(uint64_t *)value; break; case UC_X86_REG_SS: - X86_CPU(uc, mycpu)->env.segs[R_SS].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_SS].base = *(uint64_t *)value; break; case UC_X86_REG_ES: - X86_CPU(uc, mycpu)->env.segs[R_ES].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_ES].base = *(uint64_t *)value; break; case UC_X86_REG_FS: - X86_CPU(uc, mycpu)->env.segs[R_FS].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_FS].base = *(uint64_t *)value; break; case UC_X86_REG_GS: - X86_CPU(uc, mycpu)->env.segs[R_GS].base = *(uint16_t *)value; + X86_CPU(uc, mycpu)->env.segs[R_GS].base = *(uint64_t *)value; break; case UC_X86_REG_R8: X86_CPU(uc, mycpu)->env.regs[8] = *(uint64_t *)value; From 21ce78924c035d0898e7353f5e84d52be98793da Mon Sep 17 00:00:00 2001 From: gaffe Date: Fri, 23 Oct 2015 11:28:10 -0700 Subject: [PATCH 2/2] assert that PC was changed in callback-pc test --- tests/regress/callback-pc.py | 48 +++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/tests/regress/callback-pc.py b/tests/regress/callback-pc.py index 3edc67e6..77f4e5ab 100755 --- a/tests/regress/callback-pc.py +++ b/tests/regress/callback-pc.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # reg_write() can't modify PC from within trace callbacks -# Pull Request #4 +# issue #210 from __future__ import print_function from unicorn import * @@ -30,11 +30,7 @@ def hook_block(uc, address, size, user_data): class CallBackPCTest(regress.RegressTest): - def runTest(self): - self.instruction_trace_test() - - # set up emulation - def instruction_trace_test(self): + def test_instruction_trace(self): try: # initialize emulator in ARM's Thumb mode mu = Uc(UC_ARCH_ARM, UC_MODE_THUMB) @@ -51,14 +47,44 @@ class CallBackPCTest(regress.RegressTest): # tracing all instructions with customized callback mu.hook_add(UC_HOOK_CODE, hook_code, user_data=mu) - # tracing all basic blocks with customized callback - mu.hook_add(UC_HOOK_BLOCK, hook_block, user_data=mu) + # emulate one instruction + mu.emu_start(BASE_ADDRESS, BASE_ADDRESS + len(THUMB_CODE), count=1) - # emulate machine code in infinite time - mu.emu_start(BASE_ADDRESS, BASE_ADDRESS + len(THUMB_CODE)) + # the instruction trace callback set PC to 0xffffffff, so at this + # point, the PC value should be 0xffffffff. + pc = mu.reg_read(UC_ARM_REG_PC) + self.assertEqual(pc, 0xffffffff, "PC not set to 0xffffffff by instruction trace callback") except UcError as e: - assertFalse(0, "ERROR: %s" % e) + self.assertFalse(0, "ERROR: %s" % e) + + def test_block_trace(self): + try: + # initialize emulator in ARM's Thumb mode + mu = Uc(UC_ARCH_ARM, UC_MODE_THUMB) + + # map some memory + mu.mem_map(BASE_ADDRESS, 2 * 1024 * 1024) + + # write machine code to be emulated to memory + mu.mem_write(BASE_ADDRESS, THUMB_CODE) + + # setup stack + mu.reg_write(UC_ARM_REG_SP, BASE_ADDRESS + 2 * 1024 * 1024) + + # trace blocks with customized callback + mu.hook_add(UC_HOOK_BLOCK, hook_block, user_data=mu) + + # emulate one instruction + mu.emu_start(BASE_ADDRESS, BASE_ADDRESS + len(THUMB_CODE), count=1) + + # the block callback set PC to 0xffffffff, so at this point, the PC + # value should be 0xffffffff. + pc = mu.reg_read(UC_ARM_REG_PC) + self.assertEqual(pc, 0xffffffff, "PC not set to 0xffffffff by block callback") + + except UcError as e: + self.assertFalse(0, "ERROR: %s" % e) if __name__ == '__main__': regress.main()