Exemplo n.º 1
0
    def simulate(self, simstate, processed=[]):
        self._get_blocks()
        blockaddr = self.faddr
        while True:
            try:
                (baddr,
                 processed) = self.simulate_block(simstate, blockaddr,
                                                  processed)
                bsuccessors = self.cfg.get_successors(baddr)
            except SU.SimFallthroughException as e:
                baddr = e.blockaddr
                processed = e.processed
                bsuccessors = self.cfg.get_successors(baddr)
                bsuccessors = [x for x in bsuccessors if not x == e.tgtaddr]

            if len(bsuccessors) == 1:
                blockaddr = bsuccessors[0]
                if not (blockaddr in self.blocks):
                    raise SU.CHBSimError(
                        simstate, baddr,
                        'Block successor not found: ' + str(blockaddr))
            elif len(bsuccessors) == 0:
                raise SU.CHBSimError(
                    simstate, baddr,
                    'No block successors found' + str(self.cfg))
            else:
                e = SU.CHBSimError(
                    simstate, baddr, 'Multiple block successors found: ' +
                    ','.join([str(x) for x in bsuccessors]))
                e.set_instructions_processed(processed)
                raise e
Exemplo n.º 2
0
 def set_register(self, iaddr, reg, srcval):
     if SU.is_full_reg(reg):
         if srcval.is_doubleword():
             self.registers[reg] = srcval
         else:
             raise SU.CHBSimError(
                 self, iaddr,
                 'Cannot assign byte/word value to full register: ' +
                 str(srcval) + ' (width: ' + str(srcval.get_width()) + ')')
     elif SU.is_half_reg(reg):
         fullreg = SU.fullregmap[reg]
         fullregval = self.get_regval(iaddr, fullreg)
         newval = fullregval.set_word(srcval)
         self.set_register(iaddr, fullreg, newval)
     elif SU.is_qlow_reg(reg):
         fullreg = SU.fullregmap[reg]
         fullregval = self.get_regval(iaddr, fullreg)
         newval = fullregval.set_low_byte(srcval)
         self.set_register(iaddr, fullreg, newval)
     elif is_qhigh_reg(reg):
         fullreg = fullregmap(reg)
         fullregval = self.get_regval(iaddr, fullreg)
         newval = fullregval.set_snd_byte(srcval)
         self.set_register(iaddr, fullreg, newval)
     else:
         self.registers[reg] = srcval
 def set_memval(self, iaddr, address, srcval):
     try:
         if address.is_address():
             if address.is_global_address(
             ) and self.libapp and self.instaticlib:
                 return self.libglobalmem.set(iaddr, address, srcval)
             if address.is_global_address():
                 self.globalmem.set(iaddr, address, srcval)
             elif address.is_stack_address():
                 self.stackmem.set(iaddr, address, srcval)
             elif address.is_base_address():
                 base = address.get_base()
                 if not base in self.basemem:
                     self.basemem[base] = MM.MIPSimBaseMemory(
                         self, base, buffersize=address.get_buffer_size())
                 self.basemem[base].set(iaddr, address, srcval)
             else:
                 raise SU.CHBSimError(
                     self, iaddr,
                     'set-memval: ' + str(address) + ' not recognized')
         else:
             self.add_logmsg(
                 iaddr, 'attempt to address memory with absolute value: ' +
                 str(address))
     except SU.CHBSimError as e:
         self.add_logmsg(iaddr, 'error in set-memval: ' + str(e))
         raise SU.CHBSimError(self, iaddr,
                              'set-memval: ' + str(address) + ': ' + str(e))
 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))
Exemplo n.º 5
0
    def simulate_block(self, simstate, blockaddr, processed):
        if not blockaddr in self.blocks:
            raise SU.CHBSimError(simstate, blockaddr,
                                 'Block address not found: ' + str(blockaddr))
        block = self.blocks[blockaddr]

        def f(_, i):
            i.simulate(simstate)
            processed.append(i)

        try:
            block.iter_instructions(f)
            return (block.baddr, processed)
        except SU.CHBSimError as e:
            e.set_instructions_processed(processed)
            raise
        except SU.SimFallthroughException as e:
            e.set_instructions_processed(processed)
            e.set_block_address(block.baddr)
            raise
        except SU.SimJumpException as e:
            processed.append(self.get_instruction(e.iaddr))
            tgtaddr = str(e.tgtaddr)
            if tgtaddr in self.blocks:
                return self.simulate_block(simstate, tgtaddr, processed)
            else:
                targets = ','.join([str(t) for t in self.blocks])
                eerror = SU.CHBSimError(
                    simstate, e.iaddr, 'Target block address not found: ' +
                    str(e.tgtaddr) + ' (targets: ' + targets + ')')
                raise eerror
Exemplo n.º 6
0
 def simulate(self, iaddr, simstate):
     ecxval = simstate.get_regval(iaddr, 'ecx')
     newval = ecxval.sub(SV.simone)
     simstate.set_register(iaddr, 'ecx', newval)
     tgtaddr = str(self.get_target_address())
     if newval.value != 0:
         raise SU.KTSimJumpException(iaddr, tgtaddr)
     raise SU.KTSimFallthroughException(iaddr, tgtaddr)
Exemplo n.º 7
0
    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))
Exemplo n.º 8
0
 def get_regval(self, iaddr, reg):
     if SU.is_half_reg(reg):
         fullreg = SU.get_full_reg(reg)
         if fullreg in self.registers:
             return self.registers[fullreg].get_low_word()
         raise SU.CHBSimError(
             self, iaddr, 'get_regval: no value found  for ' + reg + ' (' +
             fullreg + ')')
     elif SU.is_qlow_reg(reg):
         fullreg = SU.get_full_reg(reg)
         if fullreg in self.registers:
             return self.registers[fullreg].get_low_byte()
         raise SU.CHBSimError(
             self, iaddr,
             'get_regval: no value found for ' + reg + ' (' + fullreg + ')')
     elif SU.is_qhigh_reg(reg):
         fullreg = SU.get_full_reg(reg)
         if fullreg in self.registers:
             return self.registers[fullreg].get_snd_byte()
         raise SU.CHBSimError(
             self, iaddr,
             'get_regval: no value found for ' + reg + ' (' + fullreg + ')')
     elif reg in self.registers:
         return self.registers[reg]
     else:
         self.add_logmsg(iaddr, 'no value for register ' + reg)
         return SV.simundefined
Exemplo n.º 9
0
 def set_byte3(self, b3):
     if b3.is_byte():
         newval = SU.compute_dw_value(self.byte1, self.byte2, b3.value,
                                      self.byte4)
         newdefined = self.b1defined and self.b2defined and b3.is_defined(
         ) and self.b4defined
         return SimDoubleWordValue(newval,
                                   defined=newdefined,
                                   b1defined=self.b1defined,
                                   b2defined=self.b2defined,
                                   b3defined=b3.is_defined(),
                                   b4defined=self.b4defined)
     raise SU.CHBSimOpError('set byte3', [self, b3])
Exemplo n.º 10
0
 def set_byte1(self, b1):
     if b1.is_byte():
         newval = SU.compute_dw_value(b1.value, self.byte2, self.byte3,
                                      self.byte4)
         newdefined = b1.is_defined(
         ) and self.b2defined and self.b3defined and self.b4defined
         return SimDoubleWordValue(newval,
                                   defined=newdefined,
                                   b1defined=not b1.is_defined(),
                                   b2defined=self.b2defined,
                                   b3defined=self.b3defined,
                                   b4defined=self.b4defined)
     raise SU.CHBSimOpError('set byte1', [self, b1])
Exemplo n.º 11
0
 def set_byte4(self, b4):
     if b4.is_byte():
         newval = SU.compute_dw_value(self.byte1, self.byte2, self.byte3,
                                      b4.value)
         newdefined = self.b1defined and self.b2defined and self.b3defined and b4.is_defined(
         )
         return SimDoubleWordValue(newval,
                                   defined=newdefined,
                                   b1defined=self.b1defined,
                                   b2defined=self.b2defined,
                                   b3defined=self.b3defined,
                                   b4defined=b4.is_defined())
     raise SU.CHBSimOpError('set byte4', [self, b4])
Exemplo n.º 12
0
def compose_simvalue(bytes):
    for b in bytes:
        if not check_byte(b):
            raise UF.CHBError('One of the bytes is not a literal value: ' +
                              ','.join(str(b) for b in bytes))
    if len(bytes) == 1:
        return bytes[0]
    elif len(bytes) == 2:
        b1 = bytes[0]
        b2 = bytes[1]
        if b1.is_defined() and b2.is_defined():
            return SimWordValue((b2.value << 8) + b1.value)
        else:
            return SimWordValue(0, defined=False)
    elif len(bytes) == 4:
        b1 = bytes[0]
        b2 = bytes[1]
        b3 = bytes[2]
        b4 = bytes[3]
        if b1.is_defined() and b2.is_defined() and b3.is_defined(
        ) and b4.is_defined():
            bval = SU.compute_dw_value(b1.value, b2.value, b3.value, b4.value)
            return SimDoubleWordValue(bval)
        else:
            return SimDoubleWordValue(0, defined=False)
    else:
        raise UF.CHBError('Number of bytes not supported: ' + str(len(bytes)))
Exemplo n.º 13
0
 def add(self, other):
     if other.is_defined() and other.is_literal():
         return mk_libc_table_value(self.name, self.offset + other.value)
     else:
         raise SU.CHBError(
             'Argument to libc-table-value.add not recognized: ' +
             str(other))
Exemplo n.º 14
0
    def simulate(self, iaddr, simstate):
        tag = self.tags[0]
        tgt = str(self.get_target_address())

        def jump():
            raise SU.KTSimJumpException(iaddr, tgt)

        def fallthrough():
            raise SU.KTSimFallthroughException(iaddr, tgt)

        def undefined(flag):
            raise SU.KTCHBError('Flag value ' + flag + ' is undefined')

        if tag == 'jc':
            cf = simstate.get_flag_value('CF')
            if cf == 1: jump()
            elif cf == 0: fallthrough()
            else: undefined('CF')
        elif tag == 'jnz':
            zf = simstate.get_flag_value('ZF')
            if zf == 0: jump()
            elif zf == 1: fallthrough()
            else: undefined('ZF')
        else:
            raise SU.KTCHBError('Conditional jump tag not yet supported: ' +
                                tag)
Exemplo n.º 15
0
 def set_lib_memval(self, iaddr, address, srcval):
     if address.is_address():
         if address.is_global_address() and self.libapp:
             self.libglobalmem.set(iaddr, address, srcval)
             return
     raise SU.CHBSimError(
         self, iaddr, 'set-lib-memval: ' + str(address) + ' not supported')
Exemplo n.º 16
0
 def zero_extend(self, size):
     if self.is_defined():
         if size == 2: return self
         if size == 4: return self.to_doubleword(signextend=False)
         raise UF.CHBError('Size for zero-extension not supported: ' +
                           str(size))
     raise SU.CHBSimValueUndefinedError('SimWordValue:zero_extend')
Exemplo n.º 17
0
 def to_doubleword(self, signextend=True):
     if self.is_defined():
         if signextend:
             return SimDoubleWordValue(self.to_signed_int())
         else:
             return SimDoubleWordValue(self.value)
     raise SU.CHBSimValueUndefinedError('SimWordValue.to_doubleword')
Exemplo n.º 18
0
 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
Exemplo n.º 19
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))
Exemplo n.º 20
0
 def is_not_equal(self, other):
     if other.is_literal():
         result = 1 if self.value != other.value else 0
         return SimBoolValue(result,
                             self.is_defined() and other.is_defined())
     raise SU.CHBSimValueUndefinedError('SimDoubleWordValue:is_not_equal ' +
                                        str(other))
Exemplo n.º 21
0
 def sign_extend(self, size):
     if self.is_defined():
         if size == 2: return self
         if size == 4: return self.to_doubleword(signextend=True)
         raise UF.CHBError('Size of sign extension not supported: ' +
                           str(size))
     raise SU.CHBSimValueUndefinedError('SimWordValue.sign_extend')
Exemplo n.º 22
0
 def bitwise_xor(self, other):
     if other.is_literal():
         newval = self.value ^ other.value
         return SimDoubleWordValue(newval,
                                   defined=self.is_defined()
                                   and other.is_defined())
     raise SU.CHBSimValueUndefinedError('SimDoubleWordValue:bitwise_xor ' +
                                        str(other))
Exemplo n.º 23
0
 def modu(self, other):
     if other.is_literal() and other.value > 0:
         newval = self.value % other.value
         return SimDoubleWordValue(newval,
                                   defined=self.is_defined()
                                   and other.is_defined())
     raise SU.CHBSimValueUndefinedError('SimDoubleWordValue:mod ' +
                                        str(other))
Exemplo n.º 24
0
 def mul(self, other):
     if other.is_literal():
         newval = self.value * other.value
         return SimQuadWordValue(newval,
                                 defined=self.is_defined()
                                 and other.is_defined())
     raise SU.CHBSimValueUndefinedError('SimDoubleWordValue:mul ' +
                                        str(other))
Exemplo n.º 25
0
 def sub(self, other):
     if other.is_literal():
         newval = (self.value - other.value) % (SU.max32 + 1)
         return SimDoubleWordValue(newval,
                                   defined=self.is_defined()
                                   and other.is_defined())
     raise SU.CHBSimValueUndefinedError('SimDoubleWordValue:sub ' +
                                        str(other))
Exemplo n.º 26
0
 def get_flag_value(self, flag):
     if flag in self.flags:
         if self.flags[flag].undefined:
             return None
         else:
             return self.flags[flag].value
     else:
         raise SU.CHBSimError(self, iaddr, 'flag not recognized: ' + flag)
Exemplo n.º 27
0
 def to_signed_int(self):
     if self.is_defined():
         if self.is_negative():
             return self.value - 256
         else:
             return self.value
     else:
         raise SU.SimValueUndefinedError('SimByteValue: to_signed_int')
Exemplo n.º 28
0
 def set_low_word(self, w):
     if w.is_defined():
         if w.is_word():
             newval = w.value + ((self.value >> 16) << 16)
             return SimDoubleWordValue(newval, self.is_defined())
         raise SU.CHBSimOpError('set word', [self, w])
     else:
         return simundefinedDW
Exemplo n.º 29
0
 def to_signed_int(self):
     if self.is_defined():
         if self.is_negative():
             return self.value - (SU.max32 + 1)
         else:
             return self.value
     else:
         raise SU.CHBSimValueUndefinedError(
             'SimDoubleWordValue:to_signed_int')
Exemplo n.º 30
0
 def bitwise_nor(self, other):
     if other.is_literal():
         try:
             orvalue = self.bitwise_or(other)
             return orvalue.bitwise_not()
         except SU.CHBSimValueUndefinedError as e:
             raise SU.CHBSimValueUndefinedError(
                 'SimDoubleWordValue:bitwise_nor ' + str(other) + ': ' +
                 str(e))