Esempio n. 1
0
    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
Esempio n. 2
0
    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)
Esempio n. 3
0
    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()
Esempio n. 4
0
    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)
Esempio n. 5
0
 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")
Esempio n. 6
0
    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,)
Esempio n. 7
0
    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))
Esempio n. 8
0
    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))
Esempio n. 9
0
    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
Esempio n. 10
0
 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")
Esempio n. 11
0
    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))