def get_lhs(self, iaddr, op): opkind = op.get_mips_opkind() if opkind.is_mips_register() or opkind.is_mips_special_register(): return MSL.MIPSimRegister(opkind.get_mips_register()) elif opkind.is_mips_indirect_register(): reg = opkind.get_mips_register() offset = opkind.get_offset() regval = self.get_regval(iaddr, reg) if self.instaticlib: if regval.is_literal( ) and regval.value > self.libimagebase.get_offset_value(): address = SSV.SimGlobalAddress(regval).add_offset(offset) return MSL.MIPSimMemoryLocation(address) if regval.is_literal( ) and regval.value > self.imagebase.get_offset_value(): address = SSV.SimGlobalAddress(regval).add_offset(offset) return MSL.MIPSimMemoryLocation(address) elif regval.is_address(): address = regval.add_offset(offset) return MSL.MIPSimMemoryLocation(address) else: raise SU.CHBSimError( self, iaddr, 'get-lhs: operand not recognized: ' + str(op) + ' (regval: ' + str(regval) + ')') else: raise SU.CHBSimError(self, iaddr, 'get-lhs: ' + str(op))
def function_start_initialization(self): self.registers['sp'] = SSV.SimStackAddress(SV.simZero) # stackpointer for reg in [ 'ra', 'gp', 'fp', 's0', 's1', 's2', 's3', 's4', 's5', 's6', 's7' ]: self.registers[reg] = SSV.SimSymbol(reg + '_in') self.simsupport.do_initialization(self)
def get_arg_string(self, iaddr, reg): saddr = self.registers[reg] result = '' offset = 0 if saddr.is_literal(): if saddr.value > self.imagebase.get_offset_value(): saddr = SSV.SimGlobalAddress(saddr) else: raise SU.CHBSimError( self, iaddr, 'String argument is not a valid address: ' + str(saddr)) elif saddr.is_string_address(): return saddr.get_string() elif saddr.is_symbol(): return 'symbol:' + saddr.get_name() while True: srcaddr = saddr.add_offset(offset) srcval = self.get_memval(iaddr, srcaddr, 1) if srcval.is_defined(): if srcval.value == 0: break else: result += chr(srcval.value) offset += 1 else: break return result
def get(self, iaddr, address, size, bigendian=False): try: memval = M.SimMemory.get(self, iaddr, address, size) except SU.CHBSimError as e: name = self.name + '[' + str(address.get_offset( )) + ']' + ' (value not retrieved: ' + str(e) + ')' return SSV.SimSymbol(name) else: return memval
def get_lhs(self, iaddr, op): opkind = op.get_opkind() if opkind.is_register(): return SL.SimRegister(opkind.get_register()) elif opkind.is_double_register(): return SL.SimDoubleRegister(opkind.get_reg_low(), opkind.get_reg_high()) elif opkind.is_indirect_register(): reg = opkind.get_register() offset = opkind.get_offset() regval = self.get_regval(iaddr, reg) if regval.is_address(): return SL.SimMemoryLocation(regval.add_offset(offset)) elif regval.value > self.imagebase.value: address = SSV.SimGlobalAddress(regval.value + offset) return SL.SimMemoryLocation(address) else: raise SU.CHBSimError( self, iaddr, 'get-lhs: operand not recognized: ' + str(op) + ' (regval: ' + str(regval) + ')') elif opkind.is_scaled_indirect_register(): basereg = opkind.get_base_register() indexreg = opkind.get_ind_register() offset = opkind.get_offset() scale = opkind.get_scale() if (not basereg is None) and indexreg is None and scale == 1: regval = self.get_regval(iaddr, basereg) if regval.is_address(): return SL.SimMemoryLocation(regval.add_offset(offset)) else: raise SU.CHBSimError( self, iaddr, 'get-lhs: operand not recognized: ' + str(op) + ' produces: ' + str(regval)) elif (not basereg is None) and ( not indexreg is None) and scale == 1: baseregval = self.get_regval(iaddr, basereg) indexval = self.get_regval(iaddr, indexreg) if indexval.is_address(): memaddress = indexval.add_offset( baseregval.to_signed_int()) memaddress = memaddress.add_offset(offset) return SL.SimMemoryLocation(memaddress) else: raise SU.CHBSimError( self, iaddr, 'get-lhs: operand not recognized(A): ' + str(op)) else: raise SU.CHBSimError( self, iaddr, 'get-lhs: operand not recognized(B): ' + str(op) + ' (scaled indirect)') else: raise SU.CHBSimError( self, iaddr, 'get-lhs: operand not recognized(C): ' + str(op))
def __init__(self, asmfn): self.asmfn = asmfn # AsmFunction self.imagebase = None self.uninitializedregion = None self.flags = {} # flagname -> SimBoolValue self.registers = {} # register name -> SimDoubleWordValue self.globalmem = M.SimGlobalMemory(self) self.stackmem = M.SimStackMemory(self) self.fnlog = {} # iaddr -> msg list self.registers['esp'] = SSV.SimStackAddress(0) self.registers['ebp'] = SV.mk_symbolic_simvalue('ebp-in') self.registers['eax'] = SV.mk_symbolic_simvalue('eax-in') self.registers['ecx'] = SV.mk_symbolic_simvalue('ecx-in') self.stackmem.set(0, 0, SSV.SimReturnAddress()) self.flags['DF'] = SV.simflagclr # direction forward self.flags['CF'] = SV.simflagclr # no carry self.flags['PF'] = SV.simflagclr # even parity self.flags['ZF'] = SV.simflagclr # no zero result self.flags['SF'] = SV.simflagclr # unsigned result self.flags['OF'] = SV.simflagclr # no overflow occurred
def get_address_val(self, iaddr, op): opkind = op.get_opkind() if opkind.is_indirect_register(): reg = opkind.get_register() offset = opkind.get_offset() regval = self.get_regval(iaddr, reg) if regval.undefined: return SV.simundefined elif regval.is_address(): return regval.add_offset(offset) elif regval > self.imagebase.value: return SSV.SimGlobalAddress(regval.value + offset) else: raise SU.CHBSimError( self, iaddr, 'get-address-val: indirect register: ' + str(op)) elif opkind.is_scaled_indirect_register(): basereg = opkind.get_base_register() indexreg = opkind.get_ind_register() scale = opkind.get_scale() if indexreg is None and scale == 1: offset = opkind.get_offset() regval = self.get_regval(iaddr, basereg) print('Regval for ' + basereg + ': ' + str(regval)) print('Esp: ' + str(self.registers['esp'])) if regval.is_address(): return regval.add_offset(offset) elif regval > self.imagebase.value: return SSV.SimGlobalAddress(regval.value + offset) else: raise SU.CHBSimError( self, iaddr, 'get-address-val: indirect-scaled-register: ' + str(basereg)) else: raise SU.CHBSimError( self, iaddr, 'get-address-val: indirect-scaled-register: ' + str(basereg) + ', ' + str(indexreg)) else: raise SU.CHBSimError(self, iaddr, 'get-address-val: ' + str(op))
def _handle_ctype_b(self): return SSV.mk_libc_table_address('ctype_b')
def _handle_ctype_toupper(self): return SSV.mk_libc_table_address('ctype_toupper')
def get_rhs(self, iaddr, op, opsize=4): opkind = op.get_mips_opkind() if opkind.is_mips_register() or opkind.is_mips_special_register(): reg = opkind.get_mips_register() return self.get_regval(iaddr, reg, opsize) elif opkind.is_mips_immediate(): return SV.mk_simvalue(opsize, opkind.get_value()) elif opkind.is_mips_indirect_register(): reg = opkind.get_mips_register() offset = opkind.get_offset() regval = self.get_regval(iaddr, reg) if not regval.is_defined(): return SV.mk_undefined_simvalue(opsize) if regval.is_string_address() and opsize == 1: regstring = regval.get_string() if offset == len(regstring): return SV.SimByteValue(0) elif offset > len(regstring): print('Accessing string value out of bounds') exit(1) else: return SV.mk_simvalue(ord(regval.get_string()[offset]), size=1) if regval.is_symbol(): base = regval.get_name() if not base in self.basemem: self.basemem[base] = MM.MIPSimBaseMemory(self, base) address = SSV.mk_base_address(base, offset=offset) return self.get_memval(iaddr, address, opsize) elif regval.is_address(): address = regval.add_offset(offset) return self.get_memval(iaddr, address, opsize) elif (regval.is_literal() and self.instaticlib and regval.value > self.libimagebase.get_offset_value()): address = SSV.mk_global_address(regval.value + offset) return self.get_memval(iaddr, address, opsize) elif (regval.is_literal() and regval.value > self.imagebase.get_offset_value()): address = SSV.mk_global_address(regval.value + offset) return self.get_memval(iaddr, address, opsize) elif regval.is_literal( ) and regval.value <= self.imagebase.get_offset_value(): print('Invalid address: ' + str(regval)) return SV.mk_undefined_simvalue(opsize) elif regval.is_string_address(): s = regval.get_string() if offset < len(s): return SV.mk_simvalue(ord(s[0]), size=opsize) elif offset == len(s): return SV.mk_simvalue(0, size=opsize) # null terminator else: raise SU.CHBSimError( self, iaddr, 'string address: ' + s.get_string() + ' with offset: ' + str(offset)) elif regval.is_libc_table_address(): return SSV.mk_libc_table_value(regval.name) elif regval.is_libc_table_value(): return SSV.mk_libc_table_value_deref(regval.name, regval.offset) else: raise SU.CHBSimError( self, iaddr, 'register used in indirect register operand has no base: ' + str(regval) + ' (' + str(self.imagebase) + ')') else: raise SU.CHBSimError(self, iaddr, 'rhs-op not recognized(C): ' + str(op))
def set_image_base(self, value): self.imagebase = SSV.SimGlobalAddress( SV.SimDoubleWordValue(int(value, 16)))
def __init__( self, app, basename, # name of executable imagebase, # base address of the image (hex) startaddr, # address to start simulation (hex) bigendian=False, simsupport=BMS.BaseMIPSimSupport( '0x0'), # support class with custom initialization and stubs baseaddress=0, # load address, to be added to imagebase libapp=None, # library to statically include functions from xapp=None): # target executable for dynamic loading self.app = app self.basename = basename self.baseaddress = baseaddress self.bigendian = bigendian self.simsupport = simsupport # context self.imagebase = SSV.mk_global_address(int(imagebase, 16)) self.context = FunctionContext(self, app) self.programcounter = SSV.mk_global_address(int(startaddr, 16)) # SimAddress self.delayed_programcounter = None # SimAddress # registers and memory self.registers = {} # register name -> SimValue self.registers['zero'] = SV.SimDoubleWordValue(0) self.stackmem = MM.MIPSimStackMemory(self) self.globalmem = MM.MIPSimGlobalMemory(self, self.app) self.basemem = {} # base -> MM.MIPSimBaseMemory # static library (optional) self.libapp = libapp if self.libapp: self.libstubs = {} # int (int-address) -> (name,stub) self.libglobalmem = MM.MIPSimGlobalMemory(self, libapp) self.static_lib = { } # function-name -> function address in static lib libimgbase = self.libapp.get_elf_header().get_image_base() self.libimagebase = SSV.SimGlobalAddress( SV.SimDoubleWordValue(int(libimgbase, 16))) self.instaticlib = False # target executable for dynamic loading (optional) self.xapp = xapp if self.xapp: self.xglobalmem = MM.MIPSimGlobalMemory(self, xapp) # log self.fnlog = {} # iaddr -> msg list2 # environment self.environment = {} # string -> string self.nvram = {} # string -> string ; non-volatile ram default values self.network_input = {} # string -> f() -> string # library/application function stubs self.stubs = {} # int (int-address) -> (name,stub) self.appstubs = {} # int (int-address) -> (name,stub) self.dlstubs = {} # name -> stub ; dynamically linked symbols # libc functions implemented by tables self.ctype_toupper = None self.ctype_b = None self._initialize() self.function_start_initialization() self.push_context(startaddr)
def set_image_base(self, value): self.imagebase = SSV.SimGlobalAddress(int(value, 16))
def get_rhs(self, iaddr, op): opsize = op.get_size() opkind = op.get_opkind() if opkind.is_flag(): flag = opkind.get_flag() if flag in self.flags: return self.flags[flag] else: raise SU.CHBSimError(self, iaddr, 'flag value ' + flag + ' not found') elif opkind.is_register(): reg = opkind.get_register() return self.get_regval(iaddr, reg) elif opkind.is_double_register(): lowreg = opkind.get_reg_low() highreg = opkind.get_reg_high() lowval = self.get_regval(iaddr, lowreg) highval = self.get_regval(iaddr, highreg) return lowval.to_double_size(highval) elif opkind.is_immediate(): return SV.mk_simvalue(op.get_size(), opkind.get_value()) elif opkind.is_indirect_register(): reg = opkind.get_register() offset = opkind.get_offset() regval = self.get_regval(iaddr, reg) if regval.is_address(): address = regval.add_offset(offset) return self.get_memval(iaddr, address, op.get_size()) elif regval.value > self.imagebase.value: address = SSV.SimGlobalAddress(regval.value) address = address.add_offset(offset) return self.get_memval(iaddr, address, op.get_size()) else: raise SU.CHBSimError( self, iaddr, 'register used in indirect register operand has no base: ' + str(regval) + ' (' + str(self.imagebase) + ')') elif opkind.is_scaled_indirect_register(): basereg = opkind.get_base_register() indexreg = opkind.get_ind_register() offset = opkind.get_offset() scale = opkind.get_scale() if (not basereg is None) and indexreg is None and scale == 1: regval = self.get_regval(iaddr, basereg) if regval.is_address(): address = regval.add_offset(offset) return self.get_memval(iaddr, address, op.get_size()) elif (not basereg is None) and ( not indexreg is None) and scale == 1: baseval = self.get_regval(iaddr, basereg) indexval = self.get_regval(iaddr, indexreg) if indexval.is_address(): address = indexval.add_offset(offset) address = address.add_offset(scale * baseval.to_signed_int()) return self.get_memval(iaddr, address, op.get_size()) else: raise SU.CHBSimError( self, iaddr, 'rhs-op not recognized(A): ' + str(op)) else: raise SU.CHBSimError(self, iaddr, 'rhs-op not recognized(B): ' + str(op)) else: raise SU.CHBSimError(self, iaddr, 'rhs-op not recognized(C): ' + str(op))
def pop_value(self, iaddr): stackoffset = self.get_regval(iaddr, 'esp').get_offset() newoffset = stackoffset + 4 self.registers['esp'] = SSV.SimStackAddress(newoffset) return self.stackmem.get(iaddr, stackoffset, 4)
def push_value(self, iaddr, simval): stackoffset = self.get_regval(iaddr, 'esp').get_offset() newoffset = stackoffset - 4 self.registers['esp'] = SSV.SimStackAddress(newoffset) self.stackmem.set(iaddr, newoffset, simval)