From 0ac3cf99d488a0df3fb019edb2e00bcc10b808b6 Mon Sep 17 00:00:00 2001 From: Ryan Hileman Date: Fri, 21 Aug 2015 16:24:21 -0700 Subject: [PATCH 1/2] call int80 callback from x86_64 syscall helper --- qemu/target-i386/seg_helper.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/qemu/target-i386/seg_helper.c b/qemu/target-i386/seg_helper.c index 7245fa81..93d58566 100644 --- a/qemu/target-i386/seg_helper.c +++ b/qemu/target-i386/seg_helper.c @@ -22,6 +22,7 @@ #include "qemu/log.h" #include "exec/helper-proto.h" #include "exec/cpu_ldst.h" +#include "uc_priv.h" //#define DEBUG_PCALL @@ -944,6 +945,16 @@ void helper_syscall(CPUX86State *env, int next_eip_addend) #else void helper_syscall(CPUX86State *env, int next_eip_addend) { + // Unicorn: call interrupt callback if registered + struct uc_struct *uc = env->uc; + if (uc->hook_intr_idx) { + ((uc_cb_hookintr_t)uc->hook_callbacks[uc->hook_intr_idx].callback)( + (uch)uc, 80, + uc->hook_callbacks[uc->hook_intr_idx].user_data); + env->eip += next_eip_addend; + return; + } + int selector; if (!(env->efer & MSR_EFER_SCE)) { From 2dd3983ee3cd7a16f147ab4a13610f1b1e874324 Mon Sep 17 00:00:00 2001 From: Ryan Hileman Date: Fri, 21 Aug 2015 18:02:26 -0700 Subject: [PATCH 2/2] add syscall test --- bindings/python/sample_x86.py | 44 +++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/bindings/python/sample_x86.py b/bindings/python/sample_x86.py index efbf6375..2d9cd8a0 100755 --- a/bindings/python/sample_x86.py +++ b/bindings/python/sample_x86.py @@ -12,6 +12,7 @@ X86_CODE32_MEM_READ = b"\x8B\x0D\xAA\xAA\xAA\xAA\x41\x4a" # mov ecx,[0xaaaaaaaa] X86_CODE32_MEM_WRITE = b"\x89\x0D\xAA\xAA\xAA\xAA\x41\x4a" # mov [0xaaaaaaaa], ecx; INC ecx; dec edx X86_CODE64 = b"\x41\xBC\x3B\xB0\x28\x2A\x49\x0F\xC9\x90\x4D\x0F\xAD\xCF\x49\x87\xFD\x90\x48\x81\xD2\x8A\xCE\x77\x35\x48\xF7\xD9\x4D\x29\xF4\x49\x81\xC9\xF6\x8A\xC6\x53\x4D\x87\xED\x48\x0F\xAD\xD2\x49\xF7\xD4\x48\xF7\xE1\x4D\x19\xC5\x4D\x89\xC5\x48\xF7\xD6\x41\xB8\x4F\x8D\x6B\x59\x4D\x87\xD0\x68\x6A\x1E\x09\x3C\x59" X86_CODE32_INOUT = b"\x41\xE4\x3F\x4a\xE6\x46\x43" # INC ecx; IN AL, 0x3f; DEC edx; OUT 0x46, AL; INC ebx +X86_CODE64_SYSCALL = '\x0f\x05' # SYSCALL # memory address where emulation starts ADDRESS = 0x1000000 @@ -395,6 +396,47 @@ def test_x86_64(): print("ERROR: %s" % e) +def test_x86_64_syscall(): + print("Emulate x86_64 code with 'syscall' instruction") + try: + # Initialize emulator in X86-64bit mode + mu = Uc(UC_ARCH_X86, UC_MODE_64) + + # map 2MB memory for this emulation + mu.mem_map(ADDRESS, 2 * 1024 * 1024) + + # write machine code to be emulated to memory + mu.mem_write(ADDRESS, X86_CODE64_SYSCALL) + + def hook_intr(mu, intno, user_data): + rax = mu.reg_read(X86_REG_RAX) + if intno == 80 and rax == 0x100: + mu.reg_write(X86_REG_RAX, 0x200) + else: + print('ERROR: was not expecting rax=%d in syscall' % rax) + + # hook interrupts for syscall + mu.hook_add(UC_HOOK_INTR, hook_intr) + + # syscall handler is expecting rax=0x100 + mu.reg_write(X86_REG_RAX, 0x100) + + try: + # emulate machine code in infinite time + mu.emu_start(ADDRESS, ADDRESS + len(X86_CODE64_SYSCALL)) + except UcError as e: + print("ERROR: %s" % e) + + # now print out some registers + print(">>> Emulation done. Below is the CPU context") + + rax = mu.reg_read(X86_REG_RAX) + print(">>> RAX = 0x%x" % rax) + + except UcError as e: + print("ERROR: %s" % e) + + if __name__ == '__main__': test_i386() print("=" * 20) @@ -407,3 +449,5 @@ if __name__ == '__main__': test_i386_inout() print("=" * 20) test_x86_64() + print("=" * 20) + test_x86_64_syscall()