예제 #1
0
 def get_from_section(self, iaddr, address, size):
     if address.is_defined():
         if self.has_patched_global(address):
             return self.get_patched_global(address)
         elfheader = self.app.get_elf_header()
         sectionindex = elfheader.get_elf_section_index(
             address.get_offset_value())
         if sectionindex is None:
             memval = SV.mk_simvalue(0, size=size)
             self.simstate.add_logmsg('global memory',
                                      str(address) + ' uninitialized')
             return memval
         offset = address.get_offset_value()
         for i in range(offset, offset + size):
             byteval = self.app.get_elf_header().get_memory_value(
                 i, sectionindex)
             if byteval is not None:
                 self.set_byte(iaddr, i, SV.SimByteValue(byteval))
             else:
                 raise UF.CHBError('No value found for ' + hex(i) +
                                   ' in section ' + str(sectionindex))
         memval = M.SimMemory.get(self, iaddr, address, size)
         if not memval.is_defined():
             memval = mk_simvalue(0, size=size)
             self.simstate.add_logmsg('global memory',
                                      str(address) + ' uninitialized')
         self.accesses.setdefault(str(address), [])
         chrrep = ' (' + chr(
             memval.value) + ')' if memval.value < 128 else ''
         self.accesses[str(address)].append(
             str(iaddr) + ':' + str(memval) + chrrep)
         return memval
 def get_memval(self, iaddr, address, size, signextend=False):
     try:
         if address.is_address():
             if address.is_global_address(
             ) and self.libapp and self.instaticlib:
                 return self.libglobalmem.get(iaddr, address, size)
             if address.is_global_address and self.is_libc_ctype_toupper(
                     address.get_offset_value()):
                 return self._handle_ctype_toupper()
             elif address.is_global_address and self.is_libc_ctype_b(
                     address.get_offset_value()):
                 return self._handle_ctype_b()
             elif address.is_global_address():
                 return self.globalmem.get(iaddr, address, size)
             elif address.is_stack_address():
                 return self.stackmem.get(iaddr, address, size)
             elif address.is_base_address() and address.get_base(
             ) in self.basemem:
                 return self.basemem[address.get_base()].get(
                     iaddr, address, size)
             else:
                 self.add_logmsg(
                     iaddr, 'base ' + address.base + ' not yet supported')
                 return SV.mk_undefined_simvalue(size)
         else:
             self.add_logmsg(
                 iaddr, 'attempt to address memory with absolute value: ' +
                 str(address))
             return SV.simUndefinedDW
     except SU.CHBSimError as e:
         self.add_logmsg(
             iaddr, 'no value for memory address ' + str(address) + ' (' +
             str(e) + ')')
         return SV.simUndefinedDW
예제 #3
0
 def get_b_result(self):
     if self.name == 'ctype_b':
         result = 0
         print('ctype_b deref table value: ' + str(self.offset1) + ', ' +
               str(chr(self.offset1 // 2)))
         c = str(chr(self.offset1 // 2))
         if c.isupper():
             result += 1
         if c.islower():
             result += 2
         if c.isalpha():
             result += 4
         if c.isnumeric():
             result += 8
         if c.isspace() or c == '\r' or c == '\n':
             result += 32
         if c.isprintable():
             result += 64
         if c.isspace():
             result += 256
         if not c.isprintable():
             result += 512
         if c in string.punctuation:
             result += 1024
         if c.isalnum():
             result += 2048
         return SV.mk_simvalue(result)
     else:
         return SV.simZero
예제 #4
0
 def simulate(self, iaddr, simstate):
     srcop = self.get_src_operand()
     dstop = self.get_dst_operand()
     srcptrop = self.get_srcptr_operand()
     dstptrop = self.get_dstptr_operand()
     srcval = simstate.get_rhs(iaddr, srcop)
     srcptrval = simstate.get_rhs(iaddr, srcptrop)
     dstptrval = simstate.get_rhs(iaddr, dstptrop)
     # raise UF.KTCHBError(str(iaddr) + ': '
     #                        + 'srcop: ' + str(srcop)
     #                        + '; srcval: ' + str(srcval)
     #                        + '; esi: ' + str(srcptrval)
     #                        + '; edi: ' + str(dstptrval)
     #                        + '\n' + str(simstate))
     dflag = simstate.get_flag_value('DF')
     incr = SV.mk_simvalue(srcptrop.get_size(), self.get_size())
     simstate.set(iaddr, dstop, srcval)
     if dflag == 0:
         simstate.set(iaddr, srcptrop, srcptrval.add(incr))
         simstate.set(iaddr, dstptrop, dstptrval.add(incr))
     elif dflag == 1:
         simstate.set(iaddr, srcptrop, srcptrval.sub(incr))
         simstate.set(iaddr, dstptrop, dstptrval.sub(incr))
     else:
         raise UF.KTCHBError('Unexpected value for direction flag: ' +
                             str(dflag))
예제 #5
0
 def simulate(self, iaddr, simstate):
     srcop = self.get_src_operand()
     dstop = self.get_dst_operand()
     if (srcop.is_register() and dstop.is_register()
             and srcop.get_register() == dstop.get_register()):
         zero = SV.mk_simvalue(dstop.get_size(), 0)
         simstate.set(iaddr, dstop, zero)
         simstate.set_flag('ZF')
         simstate.clear_flag('PF')
         simstate.clear_flag('CF')
         simstate.clear_flag('OF')
         simstate.clear_flag('SF')
     else:
         try:
             srcval = simstate.get_rhs(iaddr, srcop)
             dstval = simstate.get_rhs(iaddr, dstop)
             result = dstval.bitwise_xor(srcval)
             simstate.set(iaddr, dstop, result)
             simstate.clear_flag('OF')
             simstate.clear_flag('CF')
             simstate.update_flag('SF', result.is_negative())
             simstate.update_flag('ZF', result.is_zero())
             simstate.update_flag('PF', result.is_odd_parity())
         except SU.KTCHBSimError as e:
             raise
         except UF.KTError as e:
             raise SU.KTCHBSimError(simstate, iaddr, str(e))
예제 #6
0
 def subu(self, simval):
     if simval.is_literal() and simval.is_defined():
         return self.add_offset(-simval.to_unsigned_int())
     elif simval.is_stack_address():
         return SV.mk_simvalue(self.get_offset_value() -
                               simval.get_offset_value())
     else:
         return self.add_offset(-simval.to_unsigned_int())
예제 #7
0
 def subu(self, simval):
     if simval.is_literal() and simval.is_defined():
         return self.add_offset(-simval.to_unsigned_int())
     elif simval.is_base_address() and simval.get_base() == self.get_base():
         return SV.mk_simvalue(self.get_offset_value() -
                               simval.get_offset_value())
     else:
         raise UF.CHBError('Argument ' + str(simval) +
                           ' not recognized in SimBaseAddress.subu')
예제 #8
0
 def simulate(self, iaddr, simstate):
     op = self.get_operand()
     srcval = simstate.get_rhs(iaddr, op)
     incval = SV.mk_simvalue(op.get_size(), 1)
     newval = srcval.add(incval)
     simstate.set(iaddr, op, newval)
     simstate.update_flag('OF', srcval.add_overflows(incval))
     simstate.update_flag('ZF', newval.is_zero())
     simstate.update_flag('SF', newval.is_negative())
     simstate.update_flag('PF', newval.is_odd_parity())
예제 #9
0
 def get_b_result(self):
     if self.name == 'ctype_b':
         result = 0
         print('ctype_b: ' + str(self.offset) + ', ' +
               str(chr(self.offset // 2)))
         c = chr(self.offset // 2)
         if isspace(c):
             result += 32
         return SV.mk_simvalue(result)
     else:
         return SV.simZero
예제 #10
0
 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
예제 #11
0
 def simulate(self,iaddr,simstate):
     op = self.get_operand()
     srcval = simstate.get_rhs(iaddr,op)
     zero = SV.mk_simvalue(op.get_size(),0)
     result = zero.sub(srcval)
     simstate.set(iaddr,op,result)
     if srcval.is_zero():
         simstate.set_flag('CF')
     else:
         simstate.clear_flag('CF')
     simstate.update_flag('OF',zero.sub_overflows(srcval))
     simstate.update_flag('SF',result.is_negative())
     simstate.update_flag('ZF',result.is_zero())
     simstate.update_flag('PF',result.is_odd_parity())
예제 #12
0
 def simulate(self, iaddr, simstate):
     dstop = self.get_dst_operand()
     srcop = self.get_src_operand()
     size = dstop.get_size()
     ediop = self.get_edi_operand()
     dfop = self.get_df_operand()
     srcval = simstate.get_rhs(iaddr, srcop)
     edival = simstate.get_rhs(iaddr, ediop)
     dfval = simstate.get_rhs(iaddr, dfop)
     ediinc = SV.mk_simvalue(4, size)
     if dfval.is_set():
         edinewval = srcval.sub(ediinc)
     else:
         edinewval = srcval.add(ediinc)
     simstate.set(iaddr, dstop, srcval)
     simstate.set(iaddr, ediop, edinewval)
예제 #13
0
 def simulate(self, iaddr, simstate):
     srcop = self.get_src_operand()
     dstop = self.get_dst_operand()
     size = dstop.get_size()
     srcval = simstate.get_rhs(iaddr, srcop)
     srcval = srcval.sign_extend(size)
     dstval = simstate.get_rhs(iaddr, dstop)
     cflag = simstate.get_flag_value('CF')
     if cflag is None:
         result = SV.simundefined
         simstate.set(iaddr, dstop, SV.simundefined)
     else:
         cflagval = SV.mk_simvalue(size, cflag)
         srcval = srcval.add(cflagval)
         result = dstval.sub(srcval)
         simstate.set(iaddr, dstop, result)
         simstate.update_flag('CF', dstval.sub_carries(srcval))
         simstate.update_flag('OF', dstval.sub_overflows(srcval))
         simstate.update_flag('SF', result.is_negative())
         simstate.update_flag('ZF', result.is_zero())
         simstate.update_flag('PF', result.is_odd_parity())
예제 #14
0
    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))
예제 #15
0
def mk_base_address(base, offset=0, buffersize=None, tgttype=None):
    """Makes a base address with offset (int) and buffer size (simvalue)."""
    return SimBaseAddress(base,
                          SV.mk_simvalue(offset),
                          buffersize=buffersize,
                          tgttype=tgttype)
예제 #16
0
def mk_stack_address(offset):  # integer
    return SimStackAddress(SV.mk_simvalue(offset))
예제 #17
0
 def get_toupper_result(self):
     if self.name == 'ctype_toupper':
         if self.offset1 >= 97 and self.offset2 <= 122:
             return SV.mk_simvalue(self.offset1 // 2)
         else:
             return SV.mk_simvalue(self.offset1)
예제 #18
0
def mk_global_address(offset):  # integer
    return SimGlobalAddress(SV.mk_simvalue(offset))
예제 #19
0
 def set_uninitialized_region(self, low, high):
     self.uninitializedregion = (SV.mk_global_hex_address(low),
                                 SV.mk_global_hex_address(high))
예제 #20
0
    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)
예제 #21
0
 def add_offset(self, intval):
     newoffset = self.offset.add(SV.SimDoubleWordValue(intval))
     return SimBaseAddress(self.base, newoffset, buffersize=self.buffersize)
예제 #22
0
 def set_image_base(self, value):
     self.imagebase = SSV.SimGlobalAddress(
         SV.SimDoubleWordValue(int(value, 16)))
예제 #23
0
 def add_offset(self, intval):
     newoffset = self.offset.add(SV.SimDoubleWordValue(intval))
     return SimStackAddress(newoffset)
예제 #24
0
 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))
예제 #25
0
 def is_not_equal(self, other):
     if other.is_symbolic() and other.is_stack_address():
         if self.get_offset_value() == other.get_offset_value():
             return SV.SimBoolValue(0)
     return SV.SimBoolValue(1)
예제 #26
0
 def get_patched_global(self, address):
     if self.has_patched_global(address):
         hexval = self.patched_globals[hex(address.get_offset_value())]
         return SV.mk_simvalue(int(hexval, 16))
     raise UF.CHBError('No patched global found for ' + str(address))