import signal from sibyl.engine.engine import Engine from sibyl.commons import TimeoutException, END_ADDR class MiasmEngine(Engine): """Engine based on Miasm""" def __init__(self, machine, jit_engine): jitter = machine.jitter(jit_engine) jitter.set_breakpoint(END_ADDR, MiasmEngine._code_sentinelle) self.jitter = jitter # Signal handling # # Due to Python signal handling implementation, signals aren't handled # nor passed to Jitted code in case of registration with signal API if jit_engine == "python": signal.signal(signal.SIGALRM, MiasmEngine._timeout) elif jit_engine in ["llvm", "tcc", "gcc"]: self.jitter.vm.set_alarm() else: raise ValueError("Unknown engine: %s" % jit_engine) super(MiasmEngine, self).__init__(machine) @staticmethod def _code_sentinelle(jitter): jitter.run = False jitter.pc = 0 return True @staticmethod def _timeout(signum, frame): raise TimeoutException() def run(self, address, timeout_seconds): self.jitter.init_run(address) try: signal.alarm(timeout_seconds) self.jitter.continue_run() except (AssertionError, RuntimeError, ValueError, KeyError, IndexError, TimeoutException) as _: return False except Exception as error: self.logger.exception(error) return False finally: signal.alarm(0) return True def restore_snapshot(self, memory=True): # Restore memory if memory: self.jitter.vm.reset_memory_page_pool() self.jitter.vm.reset_code_bloc_pool() for addr, metadata in self.vm_mem.iteritems(): self.jitter.vm.add_memory_page(addr, metadata["access"], metadata["data"]) # Restore registers self.jitter.cpu.init_regs() self.jitter.cpu.set_gpreg(self.vm_regs) # Reset intern elements self.jitter.vm.set_exception(0) self.jitter.cpu.set_exception(0) self.jitter.bs._atomic_mode = False