Skip to content

Commit 5826f30

Browse files
committed
Merge pull request #2 from lunixbochs/master
call int80 callback from x86_64 syscall instruction
2 parents 1c72fdb + 2dd3983 commit 5826f30

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

bindings/python/sample_x86.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
X86_CODE32_MEM_WRITE = b"\x89\x0D\xAA\xAA\xAA\xAA\x41\x4a" # mov [0xaaaaaaaa], ecx; INC ecx; dec edx
1313
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"
1414
X86_CODE32_INOUT = b"\x41\xE4\x3F\x4a\xE6\x46\x43" # INC ecx; IN AL, 0x3f; DEC edx; OUT 0x46, AL; INC ebx
15+
X86_CODE64_SYSCALL = '\x0f\x05' # SYSCALL
1516

1617
# memory address where emulation starts
1718
ADDRESS = 0x1000000
@@ -395,6 +396,47 @@ def test_x86_64():
395396
print("ERROR: %s" % e)
396397

397398

399+
def test_x86_64_syscall():
400+
print("Emulate x86_64 code with 'syscall' instruction")
401+
try:
402+
# Initialize emulator in X86-64bit mode
403+
mu = Uc(UC_ARCH_X86, UC_MODE_64)
404+
405+
# map 2MB memory for this emulation
406+
mu.mem_map(ADDRESS, 2 * 1024 * 1024)
407+
408+
# write machine code to be emulated to memory
409+
mu.mem_write(ADDRESS, X86_CODE64_SYSCALL)
410+
411+
def hook_intr(mu, intno, user_data):
412+
rax = mu.reg_read(X86_REG_RAX)
413+
if intno == 80 and rax == 0x100:
414+
mu.reg_write(X86_REG_RAX, 0x200)
415+
else:
416+
print('ERROR: was not expecting rax=%d in syscall' % rax)
417+
418+
# hook interrupts for syscall
419+
mu.hook_add(UC_HOOK_INTR, hook_intr)
420+
421+
# syscall handler is expecting rax=0x100
422+
mu.reg_write(X86_REG_RAX, 0x100)
423+
424+
try:
425+
# emulate machine code in infinite time
426+
mu.emu_start(ADDRESS, ADDRESS + len(X86_CODE64_SYSCALL))
427+
except UcError as e:
428+
print("ERROR: %s" % e)
429+
430+
# now print out some registers
431+
print(">>> Emulation done. Below is the CPU context")
432+
433+
rax = mu.reg_read(X86_REG_RAX)
434+
print(">>> RAX = 0x%x" % rax)
435+
436+
except UcError as e:
437+
print("ERROR: %s" % e)
438+
439+
398440
if __name__ == '__main__':
399441
test_i386()
400442
print("=" * 20)
@@ -407,3 +449,5 @@ def test_x86_64():
407449
test_i386_inout()
408450
print("=" * 20)
409451
test_x86_64()
452+
print("=" * 20)
453+
test_x86_64_syscall()

qemu/target-i386/seg_helper.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "qemu/log.h"
2323
#include "exec/helper-proto.h"
2424
#include "exec/cpu_ldst.h"
25+
#include "uc_priv.h"
2526

2627
//#define DEBUG_PCALL
2728

@@ -944,6 +945,16 @@ void helper_syscall(CPUX86State *env, int next_eip_addend)
944945
#else
945946
void helper_syscall(CPUX86State *env, int next_eip_addend)
946947
{
948+
// Unicorn: call interrupt callback if registered
949+
struct uc_struct *uc = env->uc;
950+
if (uc->hook_intr_idx) {
951+
((uc_cb_hookintr_t)uc->hook_callbacks[uc->hook_intr_idx].callback)(
952+
(uch)uc, 80,
953+
uc->hook_callbacks[uc->hook_intr_idx].user_data);
954+
env->eip += next_eip_addend;
955+
return;
956+
}
957+
947958
int selector;
948959

949960
if (!(env->efer & MSR_EFER_SCE)) {

0 commit comments

Comments
 (0)