def resolve_import_symbol(self, importsym: str) -> SSV.SimGlobalAddress: for dynlib in self.dynlibs: if dynlib.is_exported(importsym): faddr = dynlib.export_address(importsym) return SSV.mk_global_address(faddr, dynlib.name) else: return SSV.mk_undefined_global_address(self.modulename)
def simulate(self, iaddr: str, simstate: "SimulationState") -> str: dstop = self.dst_operand srcop = self.src_operand srcval = simstate.rhs(iaddr, srcop) result: SV.SimValue if srcval.is_undefined: result = SV.simUndefinedDW if srcval.is_global_address: val = cast(SV.SimDoubleWordValue, SV.mk_simvalue(srcval.literal_value)) srcval = cast(SSV.SimGlobalAddress, srcval) name = srcval.modulename resultval = val.swap_bytes_within_halfwords() result = SSV.mk_global_address(resultval.literal_value, name) elif srcval.is_literal: val = cast(SV.SimDoubleWordValue, srcval) result = val.swap_bytes_within_halfwords() else: raise SU.CHBSimError( simstate, iaddr, "wsbh: operand not recognized: " + str(srcop) + ": " + str(srcval)) lhs = simstate.set(iaddr, dstop, result) simstate.increment_programcounter() return SU.simassign(iaddr, simstate, lhs, result, intermediates=str(srcval))
def simulate_arm_function(xname: str, app: "ARMAccess", asm: "ARMAssembly", faddr: str) -> NoReturn: base = app.header.image_base mainparticipant = SimModule("app", app, base, app.max_address) simstate = SimulationState( faddr, mainparticipant, ARMSimProgramCounter(SSV.mk_global_address(int(faddr, 16), xname))) currentinstr = asm.instructions[faddr] print(str(currentinstr)) exit(0)
def do_initialization(self, simstate: "SimulationState") -> None: simstate.registers["sp"] = SSV.SimStackAddress(SV.simZero) simstate.registers["zero"] = SV.simZero for reg in [ "ra", "gp", "fp", "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7" ]: simstate.registers[reg] = SSV.SimSymbol(reg + "_in") simstate.registers["t9"] = SSV.mk_global_address( int(simstate.startaddr, 16), modulename=simstate.modulename) if len(self.cmdlineargs) > 0: self.initialize_cmdline_arguments(simstate)
def resolve_literal_address(self, iaddr: str, addrvalue: int) -> SSV.SimGlobalAddress: addr = self.modulestates[self.modulename].resolve_literal_address( iaddr, addrvalue) if addr.is_defined: return addr # elif addrvalue == 2: # return SFU.sim_openfile("sim_stderr", "w") else: for shmid in self.sharedmem: if self.sharedmem[shmid].has_address(addrvalue): addr = SSV.mk_global_address(addrvalue, "shared:" + str(shmid)) return addr else: raise SU.CHBSimError( self, iaddr, ("Unable to resolve address: " + hex(addrvalue) + " in " + self.modulename))
def set_uninitialized_region(self, low: str, high: str) -> None: self.uninitializedregion = (SSV.mk_global_address( int(low, 16), self.modulename), SSV.mk_global_address( int(high, 16), self.modulename))
def simulate_mips_function( xname: str, app: "MIPSAccess", asm: "MIPSAssembly", faddr: str, stepcount: int = 100, libs: Dict[str, Tuple["MIPSAccess", "MIPSAssembly"]] = {}, support: Optional[str] = None, stub_imports: List[str] = [], mainargs: List[str] = [], optargaddrstr: Optional[str] = None, optargstatestr: Optional[str] = None, patched_globals: Dict[str, str] = {}, envptr_addr: Optional[str] = None) -> NoReturn: bigendian = app.header.is_big_endian print("big endian " if bigendian else "little endian") stubs: Dict[str, "MIPSimStub"] = stubbed_libc_functions() for stubimport in stub_imports: importedstubs = importlib.import_module(stubimport) print("\nImported user stubs: " + importedstubs.__name__) for d in dir(importedstubs): if d.endswith("stubs"): userstubs: Dict[str, "MIPSimStub"] = getattr(importedstubs, d)() stubs.update(userstubs) print( "Main module " + xname + ": " + app.header.image_base + " - " + app.max_address) mainmodule = SimModule(xname, app, app.header.image_base, app.max_address) dynlibs: List[SimModule] = [] dynasms: Dict[str, "MIPSAssembly"] = {} for (libname, (libapp, libasm)) in libs.items(): print( "Lib module " + libname + ": " + libapp.header.image_base + " - " + app.max_address) dynlibs.append(SimModule( libname, libapp, libapp.header.image_base, libapp.max_address)) dynasms[libname] = libasm if envptr_addr is not None: environmentptr_address: Optional[SSV.SimGlobalAddress] = SSV.mk_global_address( int(envptr_addr, 16), modulename=mainmodule.name) else: environmentptr_address = None optargaddr: SV.SimValue = SV.simZero optargstate: SV.SimValue = SV.simZero if optargaddrstr: optargaddr = SSV.mk_global_address(int(optargaddrstr, 16), xname) if optargstatestr: optargstate = SSV.mk_global_address(int(optargstatestr, 16), xname) def default_simsupport() -> SimSupport: return SimSupport( stepcount=stepcount, optargaddr=optargaddr, optargstate=optargstate, patched_globals=patched_globals, environmentptr_address=environmentptr_address) if support: importedmodule = importlib.import_module(support) print('\nCustom Import: ' + importedmodule.__name__) for d in dir(importedmodule): print("Module: " + d) if importedmodule.__name__.endswith(d): print("found module: " + d) simsupport = getattr(importedmodule, d)( stepcount=stepcount, optargaddr=optargaddr, optargstate=optargstate, patched_globals=patched_globals, environmentptr_address=environmentptr_address) break else: simsupport = default_simsupport() else: simsupport = default_simsupport() programcounter = MIPSimProgramCounter( SSV.mk_global_address(int(faddr, 16), xname)) initializer = MIPSimInitializer(mainargs) simstate = SimulationState( faddr, mainmodule, programcounter, siminitializer=initializer, dynlibs=dynlibs, simsupport=simsupport, stubs=stubs, bigendian=bigendian) currentinstr = asm.instructions[faddr] blocktrace: List[Tuple[str, str]] = [] for i in range(0, simsupport.stepcount): try: action = currentinstr.simulate(simstate) simstate.trace.add( str(i).rjust(5) + " " + str(currentinstr).ljust(48) + str(action)) simstate.trace.include_delayed() if action == "return": print("=" * 80) print("Simulation ended normally: returning from starting function") print("=" * 80) print("\nSimulation trace:") print("-" * 80) print(str(simstate.trace)) print("\nSimulation state:") print("-" * 80) print(str(simstate)) exit(0) except SU.CHBSimCallTargetUnknownError as e: simstate.trace.add( str(i).rjust(5) + "**" + str(currentinstr).ljust(48) + str(e.calltgt)) pc = simstate.programcounter if pc.is_global_address: addr = pc.to_hex() if addr in asm.instructions: currentinstr = asm.instructions[addr] except SU.CHBSimSystemCallException as e: syscall = SC.get_mips_linux_syscall(e.syscallindex) if syscall in simstate.stubs: stub = cast(MIPSimStub, simstate.stubs[syscall]) # in MIPS register $a3 will be set to 0 or 1 to indicate success # ref: https://www.linux-mips.org/wiki/Syscall simstate.set_register(e.iaddr, "a3", SV.simZero) msg = stub.simulate(e.iaddr, simstate) simstate.trace.add( " ".ljust(15) + "syscall:" + syscall + ": " + msg) simstate.increment_programcounter() else: print(str(simstate.trace)) print(str(simstate)) print("No stub for syscall: " + syscall) exit(1) except SU.CHBSimBranchUnknownError as e: simstate.trace.add( str(i).rjust(5) + "**" + str(currentinstr).ljust(48) + str(e.truetgt) + " (" + e.msg + ")") if simstate.simsupport.branch_decision(e.iaddr, simstate): simstate.simprogramcounter.set_delayed_programcounter(e.truetgt) else: simstate.simprogramcounter.set_delayed_programcounter(e.falsetgt) except SU.CHBSymbolicExpression as e: print( "Symbolic expression: " + str(e) + "; " + str(currentinstr).ljust(48)) print("=" * 80) print("") print(str(simstate.trace)) print(str(simstate)) exit(1) except SU.CHBSimExitException as e: print("=" * 80) print( "System exit at address " + e.iaddr + " with exit value " + e.exitvalue) print("=" * 80) print("\n") print(str(simstate.trace)) print(str(simstate)) exit(1) except SU.CHBSimError as e: print("*" * 80) print("Error: " + str(e)) print("*" * 80) print("\nSimulation trace") print("-" * 80) print(str(simstate.trace)) print("\nSimulation state") print("-" * 80) print(str(simstate)) exit(1) except Exception as e: print("*" * 80) print("Exception: " + str(e)) print("Current instruction: " + str(currentinstr)) print("*" * 80) print("") print(str(simstate.trace)) print(str(simstate)) exit(1) pc = simstate.programcounter addr = pc.to_hex() try: if pc.modulename == xname: if addr in asm.instructions: currentinstr = asm.instructions[addr] else: raise UF.CHBError( "No instruction found at " + addr + " in " + xname) else: libasm = dynasms[pc.modulename] if addr in libasm.instructions: currentinstr = libasm.instructions[addr] else: raise UF.CHBError( "No instruction found at " + addr + " in " + pc.modulename) except UF.CHBError as e: print("*" * 80) print("Exception in fetching next instruction: " + str(e)) print("*" * 80) print("") print(str(simstate.trace)) print(str(simstate)) exit(1) print("\n\nSimulation trace") print(str(simstate.trace)) with open("simstackmemory.json", "w") as fp: json.dump(simstate.stackmem.jsonval(), fp, indent=3) print("\n\nSimulation state") print("=" * 80) print(str(simstate)) exit(0)
def initialize(self, iaddr: str): addr = SSV.mk_global_address(0, "shared") for i in range(0, self.buffersize): SimMemory.set(self, iaddr, addr.add_offset(i), SV.simZerobyte)
def resolve_literal_address(self, iaddr: str, addrvalue: int) -> SSV.SimGlobalAddress: if self.module.has_address(addrvalue): return SSV.mk_global_address(addrvalue, modulename=self.modulename) else: return SSV.mk_undefined_global_address(self.modulename)
def simulate(self, iaddr: str, simstate: "SimulationState") -> str: tgt = SSV.mk_global_address(self.target.absolute_address_value, modulename=simstate.modulename) simstate.increment_programcounter() simstate.simprogramcounter.set_delayed_programcounter(tgt) return "goto " + str(tgt)