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 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))
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
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))
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())
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')
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())
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
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())
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)
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())
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))
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)
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)
def mk_stack_address(offset): # integer return SimStackAddress(SV.mk_simvalue(offset))
def mk_global_address(offset): # integer return SimGlobalAddress(SV.mk_simvalue(offset))
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 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))