def simulate(self, iaddr: str, simstate: "SimulationState") -> str: src1op = self.src1_operand src2op = self.src2_operand src1val = simstate.rhs(iaddr, src1op) src2val = simstate.rhs(iaddr, src2op) expr = str(src1val) + ' == ' + str(src2val) if src1val.is_undefined or src2val.is_undefined: raise SU.CHBSimError( simstate, iaddr, "teq: some operands are undefined: " + expr) elif src1val.is_symbol or src2val.is_symbol: raise SU.CHBSymbolicExpression(simstate, iaddr, src1op, expr) elif src1val.is_literal and src2val.is_literal: if src1val.literal_value == src2val.literal_value: raise SU.CHBSimTrapSignalException( simstate, iaddr, src1val, src2val) else: simstate.increment_programcounter() return 'trap if equal: ' + expr else: raise SU.CHBSimError( simstate, iaddr, "teq: some operands not recognized: " + expr)
def simulate(self, simstate: "X86SimulationState", processed: List[X86Instruction] = []) -> None: blockaddr = self.faddr while True: try: (baddr, processed) = self.simulate_block(simstate, blockaddr, processed) bsuccessors = self.cfg.successors(baddr) except SU.CHBSimFallthroughException as e: baddr = e.blockaddr processed = cast(List[X86Instruction], e.processed) bsuccessors = self.cfg.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, blockaddr, 'Block successor not found: ' + str(blockaddr)) elif len(bsuccessors) == 0: raise SU.CHBSimError( simstate, blockaddr, 'No block successors found' + str(self.cfg)) else: err = SU.CHBSimError(simstate, blockaddr, ('Multiple block successors found: ' + ','.join([str(x) for x in bsuccessors]))) err.set_instructions_processed( cast(List[Instruction], processed)) raise err
def simulate(self, iaddr: str, simstate: "X86SimulationState") -> None: srcop = self.src_operand dstop = self.dst_operand srcptrop = self.srcptr_operand dstptrop = self.dstptr_operand srcval = simstate.get_rhs(iaddr, srcop) srcptrval = simstate.get_rhs(iaddr, srcptrop) dstptrval = simstate.get_rhs(iaddr, dstptrop) dflag = simstate.get_flag_value(iaddr, 'DF') incr = SV.mk_simvalue(srcptrop.size, self.size) simstate.set(iaddr, dstop, srcval) if (srcptrval.is_literal and srcptrval.is_defined and dstptrval.is_literal and dstptrval.is_defined): srcptrval = cast(SV.SimLiteralValue, srcptrval) dstptrval = cast(SV.SimLiteralValue, dstptrval) 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 SU.CHBSimError( simstate, iaddr, 'Unexpected value for direction flag: ' + str(dflag)) else: raise SU.CHBSimError( simstate, iaddr, ("Movs not supported for " + str(srcptrop) + ":" + str(srcptrval) + ", " + str(dstptrop) + ":" + str(dstptrval)))
def simulate(self, iaddr: str, simstate: "SimulationState") -> str: conop = self.test_operand conval = simstate.rhs(iaddr, conop) if conval.is_undefined: raise SU.CHBSimError( simstate, iaddr, "movn: condition value undefined") elif conval.is_literal: if conval.literal_value != 0: dstop = self.dst_operand srcop = self.src_operand srcval = simstate.rhs(iaddr, srcop) lhs = simstate.set(iaddr, dstop, srcval) result = SU.simassign(iaddr, simstate, lhs, srcval) else: result = str(conval) + " == 0: nop" else: raise SU.CHBSimError( simstate, iaddr, "movn: condition value not recognized: " + str(conval)) simstate.increment_programcounter() return result
def rhs(self, iaddr: str, op: Operand, opsize: int = 4) -> SV.SimValue: if op.is_register: return self.regval(iaddr, op.register, opsize=opsize) elif op.is_immediate: return SV.mk_simvalue(op.value, size=opsize) elif op.is_indirect_register: regval = self.regval(iaddr, op.indirect_register) offset = op.offset if not regval.is_defined: return SV.mk_undefined_simvalue(opsize) if regval.is_string_address and opsize == 1: regval = cast(SSV.SimStringAddress, regval) return self.rhs_string_char(iaddr, regval, offset) elif regval.is_symbol: regval = cast(SSV.SimSymbol, regval) return self.rhs_symbol(iaddr, regval, offset, opsize) elif regval.is_address: regval = cast(SSV.SimAddress, regval) return self.memval(iaddr, regval.add_offset(offset), opsize) elif regval.is_literal: regval = cast(SV.SimLiteralValue, regval) return self.rhs_literal_address(iaddr, regval.value, offset, opsize) else: raise SU.CHBSimError( self, iaddr, "Unable to resolve indirect register operand: " + str(op)) else: raise SU.CHBSimError( self, iaddr, "Operand " + str(op) + " not recognized in rhs")
def simulate_block( self, simstate: "X86SimulationState", blockaddr: str, processed: List[X86Instruction] ) -> Tuple[str, List[X86Instruction]]: if blockaddr not in self.blocks: raise SU.CHBSimError(simstate, blockaddr, 'Block address not found: ' + str(blockaddr)) block = self.blocks[blockaddr] def f(baddr: str, i: X86Instruction) -> None: i.simulate(simstate) processed.append(i) try: block.iter_instructions(f) return (block.baddr, processed) except SU.CHBSimError as e: e.set_instructions_processed(cast(List[Instruction], processed)) raise except SU.CHBSimFallthroughException as e: e.set_instructions_processed(cast(List[Instruction], processed)) e.set_block_address(block.baddr) raise except SU.CHBSimJumpException as e: processed.append(cast(X86Instruction, self.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
def simulate(self, iaddr: str, simstate: "SimulationState") -> str: srcval = simstate.rhs(iaddr, self.src_operand) simstate.increment_programcounter() if srcval.is_undefined: raise SU.CHBSimError( simstate, iaddr, "jr: jump target is undefined: " + str(srcval)) elif srcval.is_symbol: if str(srcval).endswith("ra_in"): simstate.trace.add_delayed("\n") return "return" else: raise SU.CHBSimError( simstate, iaddr, "jr: internal error: symbolic return address: " + str(srcval)) elif srcval.is_function_return_address: addr = cast(SSV.SimReturnAddress, srcval) simstate.simprogramcounter.set_delayed_programcounter(addr) simstate.trace.add_delayed("\n") simstate.set_function_address(addr.functionaddr) return "return to " + addr.functionaddr elif srcval.is_global_address: gaddr = cast(SSV.SimGlobalAddress, srcval) simstate.simprogramcounter.set_delayed_programcounter(gaddr) simstate.trace.add_delayed("\n") simstate.set_function_address(hex(gaddr.offsetvalue)) return "goto " + str(gaddr) elif srcval.is_literal: gaddr = simstate.resolve_literal_address(iaddr, srcval.literal_value) if gaddr.is_defined: simstate.simprogramcounter.set_delayed_programcounter(gaddr) return "goto " + str(gaddr) else: raise SU.CHBSimError( simstate, iaddr, "jr: target address cannot be resolved: " + str(srcval)) else: raise SU.CHBSimError( simstate, iaddr, "jr: illegal target address: " + str(srcval))
def get_regval(self, iaddr: str, reg: str) -> SV.SimValue: if SU.is_half_reg(reg): fullreg = SU.get_full_reg(reg) if fullreg in self.registers: regval = self.registers[fullreg] if regval.is_literal: regval = cast(SV.SimDoubleWordValue, regval) return regval.lowword else: return SV.simUndefinedWord else: 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: regval = self.registers[fullreg] if regval.is_literal: regval = cast(SV.SimDoubleWordValue, regval) return regval.simbyte1 else: return SV.simUndefinedByte else: 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: regval = self.registers[fullreg] if regval.is_literal: regval = cast(SV.SimDoubleWordValue, regval) return regval.simbyte2 else: return SV.simUndefinedByte else: 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.simUndefinedDW
def simulate(self, iaddr: str, simstate: "X86SimulationState") -> None: srcop = self.src_operand dstop = self.dst_operand srcval = simstate.get_rhs(iaddr, srcop) dstval = simstate.get_rhs(iaddr, dstop) if (srcval.is_literal and dstval.is_literal and dstval.is_doubleword): srcval = cast(SV.SimLiteralValue, srcval) dstval = cast(SV.SimDoubleWordValue, dstval) (cflag, result) = dstval.bitwise_shr(srcval) simstate.set(iaddr, dstop, result) if srcval.value > 0: simstate.update_flag(iaddr, 'CF', cflag == 1) if srcval.value == 1: msb = dstval.msb simstate.update_flag(iaddr, 'OF', msb == 1) else: simstate.undefine_flag(iaddr, 'OF') simstate.update_flag(iaddr, 'CF', cflag == 1) simstate.update_flag(iaddr, 'SF', result.is_negative) simstate.update_flag(iaddr, 'ZF', result.is_zero) simstate.update_flag(iaddr, 'PF', result.is_odd_parity) else: raise SU.CHBSimError( simstate, iaddr, ("ShiftRight not yet supported for " + str(dstop) + ":" + str(dstval) + ", " + str(srcop) + ":" + str(srcval)))
def simulate(self, iaddr: str, simstate: "X86SimulationState") -> None: srcop = self.src_operand dstop = self.dst_operand if (srcop.is_register and dstop.is_register and srcop.register == dstop.register): simstate.set(iaddr, dstop, SV.simZero) simstate.set_flag(iaddr, 'ZF') simstate.clear_flag(iaddr, 'PF') simstate.clear_flag(iaddr, 'CF') simstate.clear_flag(iaddr, 'OF') simstate.clear_flag(iaddr, 'SF') else: srcval = simstate.get_rhs(iaddr, srcop) dstval = simstate.get_rhs(iaddr, dstop) if dstval.is_literal: dstval = cast(SV.SimLiteralValue, dstval) result = dstval.bitwise_xor(srcval) simstate.set(iaddr, dstop, result) simstate.clear_flag(iaddr, 'OF') simstate.clear_flag(iaddr, 'CF') simstate.update_flag(iaddr, 'SF', result.is_negative) simstate.update_flag(iaddr, 'ZF', result.is_zero) simstate.update_flag(iaddr, 'PF', result.is_odd_parity) else: raise SU.CHBSimError( simstate, iaddr, ("Xor cannot be applied to " + str(dstval)))
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(self, iaddr: str, simstate: "X86SimulationState") -> None: srcop = self.src_operand shiftop = self.shift_operand dstop = self.dst_operand srcval = simstate.get_rhs(iaddr, srcop) shiftval = simstate.get_rhs(iaddr, shiftop) dstval = simstate.get_rhs(iaddr, dstop) if (shiftval.is_literal and srcval.is_literal and dstval.is_literal and dstval.is_doubleword): shiftval = cast(SV.SimLiteralValue, shiftval) dstval = cast(SV.SimDoubleWordValue, dstval) srcval = cast(SV.SimLiteralValue, srcval) (cflag, result) = dstval.bitwise_shld(srcval, shiftval) simstate.set(iaddr, dstop, result) if shiftval.value > 0: if shiftval.value == 1: msbd = dstval.msb msbr = result.msb if msbd == msbr: simstate.clear_flag(iaddr, 'OF') else: simstate.set_flag(iaddr, 'OF') else: simstate.undefine_flag(iaddr, 'OF') simstate.update_flag(iaddr, 'CF', cflag == 1) simstate.update_flag(iaddr, 'SF', result.is_negative) simstate.update_flag(iaddr, 'ZF', result.is_zero) simstate.update_flag(iaddr, 'PF', result.is_odd_parity) else: SU.CHBSimError( simstate, iaddr, ("ShiftLeftDouble not yet implemented for " + str(dstop) + ":" + str(dstval) + ", " + str(srcop) + ":" + str(srcval) + ", " + str(shiftop) + ":" + str(shiftval)))
def simulate(self, iaddr: str, simstate: "X86SimulationState") -> None: srcop = self.src_operand dstop = self.dst_operand srcval = simstate.get_rhs(iaddr, srcop) dstval = simstate.get_rhs(iaddr, dstop) if srcval.is_literal and dstval.is_literal: srcval = cast(SV.SimLiteralValue, srcval) dstval = cast(SV.SimLiteralValue, dstval) (cflag, result) = dstval.bitwise_shl(srcval) simstate.set(iaddr, dstop, result) if srcval.value > 0: simstate.update_flag(iaddr, 'CF', cflag == 1) if srcval.value == 1: msb = result.msb if not (msb == cflag): simstate.clear_flag(iaddr, 'OF') else: simstate.set_flag(iaddr, 'OF') else: simstate.undefine_flag(iaddr, 'OF') simstate.update_flag(iaddr, 'CF', cflag == 1) simstate.update_flag(iaddr, 'SF', result.is_negative) simstate.update_flag(iaddr, 'ZF', result.is_zero) simstate.update_flag(iaddr, 'PF', result.is_odd_parity) else: raise SU.CHBSimError( simstate, iaddr, ("ShiftLeft not yet implemented for " + str(dstop) + ":" + str(dstval) + ", " + str(srcop) + ":" + str(srcval)))
def simulate(self, iaddr: str, simstate: "SimulationState") -> str: dstop = self.dst_operand srcop = self.src_operand srcval = simstate.rhs(iaddr, srcop, opsize=1) if srcval.is_undefined: result = cast(SV.SimLiteralValue, SV.simUndefinedDW) simstate.add_logmsg( "warning", "lb: value undefined at " + iaddr + " from address " + str(srcop)) elif srcval.is_symbolic: raise SU.CHBSimError(simstate, iaddr, ('encountered symbolic value in lb: ' + str(srcval) + ' at address: ' + str(srcop))) elif srcval.is_literal: result = cast(SV.SimLiteralValue, srcval).sign_extend(4) else: result = SV.simUndefinedDW simstate.add_logmsg( "warning", "lb: source value at " + iaddr + " not recognized " + str(srcval)) lhs = simstate.set(iaddr, dstop, result) simstate.increment_programcounter() return SU.simassign(iaddr, simstate, lhs, result)
def simulate(self, iaddr: str, simstate: X86SimulationState) -> None: op1 = self.operand_1 op2 = self.operand_2 val1 = simstate.get_rhs(iaddr, op1) val2 = simstate.get_rhs(iaddr, op2) if val2.is_literal: val2 = cast(SV.SimLiteralValue, val2) if val2.is_byte: val2 = cast(SV.SimByteValue, val2) val2 = val2.sign_extend(op1.size) elif val2.is_word: val2 = cast(SV.SimWordValue, val2) val2 = val2.sign_extend(op1.size) if (val1.is_doubleword and val1.is_literal and val2.is_doubleword and val2.is_literal): val1 = cast(SV.SimDoubleWordValue, val1) val2 = cast(SV.SimDoubleWordValue, val2) result = val1.sub(val2) simstate.update_flag(iaddr, 'CF', val1.sub_carries(val2)) simstate.update_flag(iaddr, 'OF', val1.sub_overflows(val2)) simstate.update_flag(iaddr, 'SF', result.is_negative) simstate.update_flag(iaddr, 'ZF', result.is_zero) simstate.update_flag(iaddr, 'PF', result.is_odd_parity) else: raise SU.CHBSimError( simstate, iaddr, ("Comparison of " + str(op1) + ":" + str(val1) + " and " + str(op2) + ":" + str(val2) + " not yet supported"))
def char_string(self, iaddr: str, address: SSV.SimAddress, size: int) -> str: offset = address.offsetvalue if offset not in self._mem: raise SU.CHBSimError( self.simstate, iaddr, "Address " + str(address) + " not found in memory") if self._mem[offset].is_link: return "----" if size == 4: b1 = self.byte(iaddr, offset + 3) b2 = self.byte(iaddr, offset + 2) b3 = self.byte(iaddr, offset + 1) b4 = self.byte(iaddr, offset) result = "" if b1.value == 0 and b2.value == 0 and b3.value == 0 and b4.value == 0: return result if self.bigendian: seq = [b4, b3, b2, b1] else: seq = [b1, b2, b3, b4] for b in seq: if b.value > 10 and b.value < 127: result += chr(b.value) else: result += "?" return result else: return "?"
def byte(self, iaddr: str, offset: int) -> SV.SimByteValue: if offset in self._mem: simbyte = self._mem[offset] if simbyte.is_defined: return simbyte else: raise SU.CHBSimError(self.simstate, iaddr, (self.name + " memory location at " + hex(offset) + " is a symbolic value")) else: if self.initialized: return SV.simZerobyte else: raise SU.CHBSimError(self.simstate, iaddr, (self.name + " memory location at " + str(hex(offset)) + " not initialized"))
def get(self, iaddr: str, address: SSV.SimAddress, size: int) -> SV.SimValue: offset = address.offsetvalue if address.base.startswith("/stderr"): return cast(SV.SimValue, address) if offset not in self._mem: raise SU.CHBSimError( self.simstate, iaddr, "Address " + str(address) + " not found in memory") elif self._mem[offset].is_link: if self.bigendian: try: return self.symbolic_big_endian(iaddr, offset, size) except UF.CHBError as e: raise UF.CHBError(str(e) + ": " + str(self._mem[offset])) else: try: return self.symbolic_little_endian(iaddr, offset, size) except UF.CHBError as e: raise UF.CHBError( str(e) + ": " + str(address) + ": " + str(self._mem[offset])) elif size == 1: return self.byte(iaddr, offset) if self.bigendian: return self.big_endian(iaddr, offset, size) else: return self.little_endian(iaddr, offset, size)
def simulate(self, iaddr: str, simstate: "SimulationState") -> str: dstop = self.dst_operand src1op = self.src1_operand src2op = self.src2_operand src1val = simstate.rhs(iaddr, src1op) src2val = simstate.rhs(iaddr, src2op) expr = str(src1val) + " * " + str(src2val) if src1val.is_undefined or src2val.is_undefined: result = cast(SV.SimValue, SV.simUndefinedDW) simstate.add_logmsg("warning", "mul: some operand is undefined: " + expr) elif src1val.is_symbol or src2val.is_symbol: raise SU.CHBSymbolicExpression(simstate, iaddr, dstop, expr) elif src1val.is_literal and src2val.is_literal: result = SV.mk_simvalue(src1val.literal_value * src2val.literal_value) else: raise SU.CHBSimError( simstate, iaddr, "mul: some operand to mul not recognized: " + expr) lhs = simstate.set(iaddr, dstop, result) simstate.increment_programcounter() return SU.simassign(iaddr, simstate, lhs, result, intermediates=str(lhs) + ' := ' + expr)
def get(self, iaddr: str, address: SSV.SimAddress, size: int) -> SV.SimValue: try: for base in self.baseoffsets: if ( address.offsetvalue >= base and address.offsetvalue < base + self.buffersize): address = address.add_offset(-base) try: memval = SimMemory.get(self, iaddr, address, size) except SU.CHBSimError: memval = SV.mk_simvalue(0, size=size) return memval else: raise SU.CHBSimError( self.simstate, iaddr, "invalid shared memory address: " + str(address)) except SU.CHBSimError as e: print("Error in shared memory: " + str(e)) name = (self.name + '[' + str(address.offsetvalue) + ']' + ' (value not retrieved: ' + str(e) + ')') return SSV.SimSymbol(name)
def get_flag_value(self, iaddr: str, flag: str) -> Optional[int]: if flag in self.flags: if self.flags[flag].is_defined: return self.flags[flag].value else: return None else: raise SU.CHBSimError(self, iaddr, 'flag not recognized: ' + flag)
def simulate(self, iaddr: str, simstate: "SimulationState") -> str: tgtop = self.tgt_operand tgtval = simstate.rhs(iaddr, tgtop) simra = SSV.pc_to_return_address(simstate.programcounter.add_offset(8), simstate.function_address) simstate.increment_programcounter() simstate.registers['ra'] = simra if tgtval.is_undefined: raise SU.CHBSimError( simstate, iaddr, "jalr: target address is undefined: " + str(tgtop)) tgtaddr: Union[SSV.SimGlobalAddress, SSV.SimDynamicLinkSymbol] if tgtval.is_address: tgtval = cast(SSV.SimAddress, tgtval) if tgtval.is_global_address: tgtaddr = cast(SSV.SimGlobalAddress, tgtval) else: raise SU.CHBSimError( simstate, iaddr, "target address is not global: " + str(tgtval)) # check if literal could be an address elif tgtval.is_literal: tgtaddr = simstate.resolve_literal_address(iaddr, tgtval.literal_value) if tgtaddr.is_undefined: raise SU.CHBSimError( simstate, iaddr, "jalr: target address cannot be resolved: " + str(tgtval)) elif tgtval.is_dynamic_link_symbol: tgtaddr = cast(SSV.SimDynamicLinkSymbol, tgtval) elif tgtval.is_symbolic: raise SU.CHBSimError( simstate, iaddr, ("symbolic target address not recognized: " + str(tgtval))) else: raise SU.CHBSimCallTargetUnknownError(simstate, iaddr, tgtval, 'target = ' + str(tgtval)) simstate.simprogramcounter.set_delayed_programcounter(tgtaddr) return SU.simcall(iaddr, simstate, tgtaddr, simra)
def simulate(self, iaddr: str, simstate: "X86SimulationState") -> None: dstop = self.dst_operand srcop = self.src_operand srcval = simstate.get_rhs(iaddr, srcop) dstval = simstate.get_rhs(iaddr, dstop) raise SU.CHBSimError( simstate, iaddr, ("Rcr not yet implemented for " + str(dstop) + ":" + str(dstval) + ", " + str(srcop) + ":" + str(srcval)))
def simulate(self, iaddr: str, simstate: "X86SimulationState") -> None: op = self.operand srcval = simstate.get_rhs(iaddr, op) if srcval.is_doubleword and srcval.is_literal: srcval = cast(SV.SimDoubleWordValue, srcval) simstate.set(iaddr, op, srcval.bitwise_not()) else: raise SU.CHBSimError( simstate, iaddr, "bitwise-not not yet supported for " + str(op) + ":" + str(srcval))
def get_address_val(self, iaddr: str, op: X86Operand) -> SV.SimValue: opkind = op.opkind if opkind.is_indirect_register: opkind = cast(X86IndirectRegisterOp, opkind) reg = opkind.register offset = opkind.offset regval = self.get_regval(iaddr, reg) if regval.is_address and regval.is_defined: regval = cast(SSV.SimAddress, regval) return regval.add_offset(offset) elif regval.is_literal and regval.is_defined: regval = cast(SV.SimLiteralValue, regval) addr = self.resolve_literal_address(iaddr, regval.value) return addr.add_offset(offset) else: return SV.simUndefinedDW elif opkind.is_scaled_indirect_register: opkind = cast(X86ScaledIndirectRegisterOp, opkind) basereg = opkind.base_register indexreg = opkind.index_register scale = opkind.scale if indexreg is None and scale == 1 and basereg is not None: offset = opkind.offset regval = self.get_regval(iaddr, basereg) if regval.is_address: regval = cast(SSV.SimAddress, regval) return regval.add_offset(offset) elif regval.is_literal and regval.is_defined: regval = cast(SV.SimLiteralValue, regval) addr = self.resolve_literal_address(iaddr, regval.value) return addr.add_offset(offset) 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)) else: raise SU.CHBSimError(self, iaddr, "get-address-val: " + str(op))
def pop_value(self, iaddr: str) -> SV.SimValue: esp = self.get_regval(iaddr, "esp") if esp.is_stack_address: esp = cast(SSV.SimStackAddress, esp) newesp = esp.add_offset(4) self.registers['esp'] = newesp return self.stackmem.get(iaddr, esp, 4) else: raise SU.CHBSimError(self, iaddr, "esp is not a stack address: " + str(esp))
def push_value(self, iaddr: str, simval: SV.SimValue) -> None: esp = self.get_regval(iaddr, "esp") if esp.is_stack_address: esp = cast(SSV.SimStackAddress, esp) newesp = esp.add_offset(-4) self.registers['esp'] = newesp self.stackmem.set(iaddr, newesp, simval) else: raise SU.CHBSimError(self, iaddr, "esp is not a stack address: " + str(esp))
def memval(self, iaddr: str, address: SSV.SimAddress, size: int, signextend: bool = False) -> SV.SimValue: try: if address.is_global_address: address = cast(SSV.SimGlobalAddress, address) name = address.modulename if name in self.modulestates: return self.modulestates[name].memval(iaddr, address, size) elif name.startswith("shared:"): shmid = int(name[7:]) if shmid in self.sharedmem: return self.sharedmem[shmid].get(iaddr, address, size) else: raise SU.CHBSimError( self, iaddr, ("Shared memory with identifier " + str(shmid) + " not found")) else: raise SU.CHBSimError( self, iaddr, ("Module name not recognized: " + name + " (" + ", ".join(name for name in self.modulestates) + ")")) elif address.is_stack_address: return self.stackmem.get(iaddr, address, size) elif address.is_base_address: address = cast(SSV.SimBaseAddress, address) if address.base in self.basemem: return self.basemem[address.base].get(iaddr, address, size) else: raise SU.CHBSimError( self, iaddr, ("Base of base address: " + address.base + " not found in state's basemem")) else: raise SU.CHBSimError(self, iaddr, "Address not recognized: " + str(address)) except SU.CHBSimError as e: self.add_logmsg(iaddr, ("no value for memory address: " + str(address) + " (" + str(e) + ")")) return SV.mk_undefined_simvalue(size)
def rhs_string_char(self, iaddr: str, addr: SSV.SimStringAddress, offset: int) -> SV.SimValue: regstr = addr.stringval if offset == len(regstr): return SV.simZerobyte elif offset < len(regstr): return SV.mk_simbytevalue(ord(regstr[offset])) else: raise SU.CHBSimError( self, iaddr, ("Access of string value out of bounds. String: " + regstr + "; offset: " + str(offset)))
def lhs(self, iaddr: str, op: Operand) -> SimLocation: if op.is_register: return SimRegister(op.register) elif op.is_indirect_register: addr = self.compute_indirect_address(iaddr, op) return SimMemoryLocation(addr) elif op.is_immediate: addr = self.resolve_literal_address(iaddr, op.value) return SimMemoryLocation(addr) else: raise SU.CHBSimError(self, iaddr, "Unable to determine location for " + str(op))