def optimizedWithContext(self, ctx): self.target = self.target.optimizedWithContext(ctx) if hasattr(self.target, 'getAddress'): self.targetAddr = self.target.getAddress() elif hasattr(self.target, 'value') and self.target.value is not None: self.targetAddr = address.fromVirtualAndCurrent(self.target.value, self.addr) self.target = ProcAddress(self.targetAddr) else: pass # XXX deps = self.getDependencySet() ins = joinRegisters(deps.reads - set(['mem'])) for param in ins: if ctx.hasConstantValue(param): self.constant_params[param] = ctx.getValue(param) for w in deps.writes: ctx.setValueComplex(w) # TODO: XXX if self.targetAddr.virtual() == 0x07B9: if 'A' in self.constant_params: ctx.setValue('ROMBANK', self.constant_params['A']) return self
def tryExpandJumptable(self, proj, jumptable_addr): manual_limit = manualJumptableLimit(jumptable_addr) if manual_limit and self.jumptable_sizes[jumptable_addr] >= manual_limit: print("INFO: manual jumptable limit", jumptable_addr) self.suspicious_switch = True return next_target_addr = jumptable_addr.offset(self.jumptable_sizes[jumptable_addr] * 2) if not manual_limit and not self.isAvailableAddr(next_target_addr): return next_target = address.fromVirtualAndCurrent(proj.rom.get_word(next_target_addr), self.start_addr) if not manual_limit: if not next_target.inPhysicalMem() or next_target.virtual() <= 0x4A: print('WARN: jumptable at', str(jumptable_addr), 'bounded by bad addr', str(next_target)) self.suspicious_switch = True return self.log.append('=== expand jumptable === ' + str(next_target)) # everything ok, expand jumptable self.jumptable_sizes[jumptable_addr] += 1 self.ownByteRange(next_target_addr, 2) self.jumptable_queue.add(jumptable_addr) self.queue.add(next_target) self.labels.add(next_target) self.block_starts.add(next_target)
def __init__(self, proj, name, target, cond, addr): super(CallInstruction, self).__init__(name, addr) # XXX: IDIOM [CALL HL] if hasattr(target, 'value') and target.value == 0x00A0: target = placeholders.HL # XXX: IDIOM [CALL BC] if hasattr(target, 'value') and target.value == 0x0CDA: target = placeholders.BC # XXX: IDIOM [CALL LONG E:HL] if hasattr(target, 'value') and target.value == 0x008A: target = ComputedProcAddress(placeholders.E, placeholders.HL) self.cond = cond if hasattr(target, 'getAddress'): self.targetAddr = target.getAddress() self.target = ProcAddress(self.targetAddr) elif hasattr(target, 'value') and target.value is not None: self.targetAddr = address.fromVirtualAndCurrent(target.value, addr) self.target = ProcAddress(self.targetAddr) else: self.targetAddr = address.fromVirtual(0x4000) # XXX: ambiguous address self.target = target self.target_depset = proj.database.procInfo(self.targetAddr).depset self.returns_used = ALL_REGS self.constant_params = dict()
def tryExpandJumptable(self, proj, jumptable_addr): manual_limit = manualJumptableLimit(proj, jumptable_addr) if manual_limit and self.jumptable_sizes[ jumptable_addr] >= manual_limit: print("INFO: manual jumptable limit", jumptable_addr) self.suspicious_switch = True return next_target_addr = jumptable_addr.offset( self.jumptable_sizes[jumptable_addr] * 2) if not manual_limit and not self.isAvailableAddr(next_target_addr): return next_target = address.fromVirtualAndCurrent( proj.rom.get_word(next_target_addr), self.start_addr) if not manual_limit: if not next_target.inPhysicalMem( ) or next_target.virtual() <= 0x4A: print('WARN: jumptable at', str(jumptable_addr), 'bounded by bad addr', str(next_target)) self.suspicious_switch = True return self.log.append('=== expand jumptable === ' + str(next_target)) # everything ok, expand jumptable self.jumptable_sizes[jumptable_addr] += 1 self.ownByteRange(next_target_addr, 2) self.jumptable_queue.add(jumptable_addr) self.queue.add(next_target) self.labels.add(next_target) self.block_starts.add(next_target)
def testFromVirtualAndCurrent(self): current1 = address.fromPhysical(0x4000) current4 = address.fromPhysical(0x10000) self.assertEquals(str(address.fromVirtualAndCurrent(0x0000, current1)), "0000:0000") self.assertEquals(str(address.fromVirtualAndCurrent(0x0000, current4)), "0000:0000") self.assertEquals(str(address.fromVirtualAndCurrent(0x4000, current1)), "0001:4000") self.assertEquals(str(address.fromVirtualAndCurrent(0x4000, current4)), "0004:4000") self.assertEquals(str(address.fromVirtualAndCurrent(0x7FFF, current1)), "0001:7FFF") self.assertEquals(str(address.fromVirtualAndCurrent(0x7FFF, current4)), "0004:7FFF") self.assertEquals(str(address.fromVirtualAndCurrent(0x8000, current1)), "VRAM:8000") self.assertEquals(str(address.fromVirtualAndCurrent(0xFFFF, current4)), "IO:FFFF")
def __init__(self, target, addr=None): self.addr = addr if hasattr(target, "getAddress"): self.target = target elif target.value is not None: if addr is not None: self.target = DataAddress(address.fromVirtualAndCurrent(target.value, addr)) else: self.target = DataAddress(address.fromVirtual(target.value)) else: self.target = target self.childs = (self.target,)
def __init__(self, proj, addr): self.addr = addr self.targets = [] for i in range(256): a = addr.offset(i*2) lo = proj.rom.get(a) hi = proj.rom.get(a.offset(1)) value = address.fromVirtualAndCurrent((hi<<8) | lo, addr) if not value.inPhysicalMem(): break self.targets.append(ProcAddress(value))
def __init__(self, proj, addr): self.addr = addr self.targets = [] for i in range(256): a = addr.offset(i * 2) lo = proj.rom.get(a) hi = proj.rom.get(a.offset(1)) value = address.fromVirtualAndCurrent((hi << 8) | lo, addr) if not value.inPhysicalMem(): break self.targets.append(ProcAddress(value))
def __init__(self, name, target, cond, addr, reads, writes): super(JumpInstruction, self).__init__(name, addr) self._reads = reads self._writes = writes self.cond = cond if hasattr(target, 'getAddress'): self.targetAddr = target.getAddress() self.target = target elif target.value is not None: self.targetAddr = address.fromVirtualAndCurrent(target.value, addr) self.target = ProcAddress(self.targetAddr) else: self.targetAddr = None self.target = target
def __init__(self, proj, addr): self.addr = addr self.targets = [] romconfig = Config(proj.filename, rom=True) jumptables = romconfig.get(["Analysis", "Jumptable-List"]) try: size = jumptables[str(addr)] except KeyError: size = 256 for i in range(size): a = addr.offset(i * 2) lo = proj.rom.get(a) hi = proj.rom.get(a.offset(1)) value = address.fromVirtualAndCurrent((hi << 8) | lo, addr) if not value.inPhysicalMem(): print "breaking" break self.targets.append(ProcAddress(value))