Fix Unicorn exception handling; add a symbolic wrapper for exit(2) (#616)
* Fix unicorn tests and exception handling; add a sym wrapper for sys_exit * Add debug output when solving for exit() arg * Update how sys_exit(expr) is handled
This commit is contained in:
@@ -851,8 +851,6 @@ class Cpu(Eventful):
|
||||
logger.error("Unimplemented instruction: 0x%016x:\t%s\t%s\t%s",
|
||||
insn.address, text_bytes, insn.mnemonic, insn.op_str)
|
||||
raise InstructionEmulationError(str(e))
|
||||
except Exception as e:
|
||||
raise InstructionEmulationError(str(e))
|
||||
finally:
|
||||
# We have been seeing occasional Unicorn issues with it not clearing
|
||||
# the backing unicorn instance. Saw fewer issues with the following
|
||||
|
||||
@@ -1044,6 +1044,13 @@ class Linux(Platform):
|
||||
'''
|
||||
return data
|
||||
|
||||
def _exit(self, message):
|
||||
procid = self.procs.index(self.current)
|
||||
self.sched()
|
||||
self.running.remove(procid)
|
||||
if len(self.running) == 0 :
|
||||
raise TerminateState(message, testcase=True)
|
||||
|
||||
def sys_umask(self, mask):
|
||||
'''
|
||||
umask - Set file creation mode mask
|
||||
@@ -1716,13 +1723,7 @@ class Linux(Platform):
|
||||
Exits all threads in a process
|
||||
:raises Exception: 'Finished'
|
||||
'''
|
||||
procid = self.procs.index(self.current)
|
||||
self.sched()
|
||||
self.running.remove(procid)
|
||||
#self.procs[procid] = None
|
||||
if len(self.running) == 0 :
|
||||
raise TerminateState("Program finished with exit status: %r" % ctypes.c_int32(error_code).value, testcase=True)
|
||||
return error_code
|
||||
return self._exit("Program finished with exit status: {}".format(ctypes.c_int32(error_code).value))
|
||||
|
||||
def sys_ptrace(self, request, pid, addr, data):
|
||||
return 0
|
||||
@@ -2318,6 +2319,13 @@ class SLinux(Linux):
|
||||
|
||||
#Dispatchers...
|
||||
|
||||
def sys_exit_group(self, error_code):
|
||||
if issymbolic(error_code):
|
||||
error_code = solver.get_value(self.constraints, error_code)
|
||||
return self._exit("Program finished with exit status: {} (*)".format(ctypes.c_int32(error_code).value))
|
||||
else:
|
||||
return super(SLinux, self).sys_exit_group(error_code)
|
||||
|
||||
def sys_read(self, fd, buf, count):
|
||||
if issymbolic(fd):
|
||||
logger.debug("Ask to read from a symbolic file descriptor!!")
|
||||
|
||||
@@ -1328,6 +1328,8 @@ class UnicornConcretization(unittest.TestCase):
|
||||
self.cpu, self.state = self.__class__.get_state()
|
||||
self.mem = self.cpu.memory
|
||||
self.rf = self.cpu.regfile
|
||||
for r in self.cpu.regfile.canonical_registers:
|
||||
self.cpu.write_register(r, 0)
|
||||
|
||||
def _setupCpu(self, asm):
|
||||
self.code = self.mem.mmap(0x1000, 0x1000, 'rwx')
|
||||
@@ -1398,3 +1400,12 @@ class UnicornConcretization(unittest.TestCase):
|
||||
self.assertEqual(self.rf.read('PC'), self.code+8)
|
||||
self.assertEqual(self.rf.read('R0'), 0x12345678)
|
||||
|
||||
|
||||
@itest_custom("mov r1, r2")
|
||||
def test_concretize_register_isnt_consumed(self):
|
||||
val = self.state.new_symbolic_value(32)
|
||||
self.rf.write('R2', val)
|
||||
|
||||
with self.assertRaises(ConcretizeRegister):
|
||||
self.cpu.emulate(self.cpu.decode_instruction(self.cpu.PC))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user