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
Example #4
0
 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)