Unhandled interrupt will halt execution

This commit is contained in:
Hoang-Vu Dang 2016-07-04 17:07:57 -05:00
parent 3151451c87
commit 9cdca5a32b
8 changed files with 20 additions and 7 deletions

View file

@ -63,6 +63,7 @@ module Common =
let UC_ERR_FETCH_UNALIGNED = 18 let UC_ERR_FETCH_UNALIGNED = 18
let UC_ERR_HOOK_EXIST = 19 let UC_ERR_HOOK_EXIST = 19
let UC_ERR_RESOURCE = 20 let UC_ERR_RESOURCE = 20
let UC_ERR_UNHANDLED_INTERRUPT = 21
let UC_MEM_READ = 16 let UC_MEM_READ = 16
let UC_MEM_WRITE = 17 let UC_MEM_WRITE = 17
let UC_MEM_FETCH = 18 let UC_MEM_FETCH = 18

View file

@ -58,6 +58,7 @@ const (
ERR_FETCH_UNALIGNED = 18 ERR_FETCH_UNALIGNED = 18
ERR_HOOK_EXIST = 19 ERR_HOOK_EXIST = 19
ERR_RESOURCE = 20 ERR_RESOURCE = 20
ERR_UNHANDLED_INTERRUPT = 21
MEM_READ = 16 MEM_READ = 16
MEM_WRITE = 17 MEM_WRITE = 17
MEM_FETCH = 18 MEM_FETCH = 18

View file

@ -60,6 +60,7 @@ public interface UnicornConst {
public static final int UC_ERR_FETCH_UNALIGNED = 18; public static final int UC_ERR_FETCH_UNALIGNED = 18;
public static final int UC_ERR_HOOK_EXIST = 19; public static final int UC_ERR_HOOK_EXIST = 19;
public static final int UC_ERR_RESOURCE = 20; public static final int UC_ERR_RESOURCE = 20;
public static final int UC_ERR_UNHANDLED_INTERRUPT = 21;
public static final int UC_MEM_READ = 16; public static final int UC_MEM_READ = 16;
public static final int UC_MEM_WRITE = 17; public static final int UC_MEM_WRITE = 17;
public static final int UC_MEM_FETCH = 18; public static final int UC_MEM_FETCH = 18;

View file

@ -56,6 +56,7 @@ UC_ERR_WRITE_UNALIGNED = 17
UC_ERR_FETCH_UNALIGNED = 18 UC_ERR_FETCH_UNALIGNED = 18
UC_ERR_HOOK_EXIST = 19 UC_ERR_HOOK_EXIST = 19
UC_ERR_RESOURCE = 20 UC_ERR_RESOURCE = 20
UC_ERR_UNHANDLED_INTERRUPT = 21
UC_MEM_READ = 16 UC_MEM_READ = 16
UC_MEM_WRITE = 17 UC_MEM_WRITE = 17
UC_MEM_FETCH = 18 UC_MEM_FETCH = 18

View file

@ -145,6 +145,7 @@ typedef enum uc_err {
UC_ERR_FETCH_UNALIGNED, // Unaligned fetch UC_ERR_FETCH_UNALIGNED, // Unaligned fetch
UC_ERR_HOOK_EXIST, // hook for this event already existed UC_ERR_HOOK_EXIST, // hook for this event already existed
UC_ERR_RESOURCE, // Insufficient resource: uc_emu_start() UC_ERR_RESOURCE, // Insufficient resource: uc_emu_start()
UC_ERR_UNHANDLED_INTERRUPT // Unhandled CPU interrupt.
} uc_err; } uc_err;

View file

@ -130,9 +130,18 @@ int cpu_exec(struct uc_struct *uc, CPUArchState *env) // qq
ret = cpu->exception_index; ret = cpu->exception_index;
break; break;
#else #else
bool catched = false;
// Unicorn: call registered interrupt callbacks // Unicorn: call registered interrupt callbacks
HOOK_FOREACH(uc, hook, UC_HOOK_INTR) { HOOK_FOREACH(uc, hook, UC_HOOK_INTR) {
((uc_cb_hookintr_t)hook->callback)(uc, cpu->exception_index, hook->user_data); ((uc_cb_hookintr_t)hook->callback)(uc, cpu->exception_index, hook->user_data);
catched = true;
}
// Unicorn: If un-catched interrupt, stop executions.
if (!catched) {
cpu->halted = 1;
uc->invalid_error = UC_ERR_UNHANDLED_INTERRUPT;
ret = EXCP_HLT;
break;
} }
cpu->exception_index = -1; cpu->exception_index = -1;
#if defined(TARGET_X86_64) #if defined(TARGET_X86_64)

View file

@ -13,15 +13,12 @@ class VldrPcInsn(regress.RegressTest):
# mov gs, eax; mov eax, 1 # mov gs, eax; mov eax, 1
code = '8ee8b801000000'.decode('hex') code = '8ee8b801000000'.decode('hex')
uc.mem_write(0x1000, code) uc.mem_write(0x1000, code)
uc.reg_write(UC_X86_REG_EAX, 0xFFFFFFFF) uc.reg_write(UC_X86_REG_EAX, 0xFFFFFFFF)
# this should throw an error
# the eax test is just to prove the second instruction doesn't execute with self.assertRaises(UcError) as ex_ctx:
try:
uc.emu_start(0x1000, 0x1000 + len(code)) uc.emu_start(0x1000, 0x1000 + len(code))
except UcError:
return self.assertEquals(ex_ctx.exception.errno, UC_ERR_UNHANDLED_INTERRUPT)
self.assertEqual(uc.reg_read(UC_X86_REG_EAX), 1)
if __name__ == '__main__': if __name__ == '__main__':
regress.main() regress.main()

2
uc.c
View file

@ -96,6 +96,8 @@ const char *uc_strerror(uc_err code)
return "Fetch from unaligned memory (UC_ERR_FETCH_UNALIGNED)"; return "Fetch from unaligned memory (UC_ERR_FETCH_UNALIGNED)";
case UC_ERR_RESOURCE: case UC_ERR_RESOURCE:
return "Insufficient resource (UC_ERR_RESOURCE)"; return "Insufficient resource (UC_ERR_RESOURCE)";
case UC_ERR_UNHANDLED_INTERRUPT:
return "Unhandled machine interrupt (UC_ERR_UNHANDLED_INTERRUPT)";
} }
} }