示例#1
0
class JumpInstruction(Instruction):
    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 optimizedWithContext(self, ctx):
        return JumpInstruction(self.name, self.target.optimizedWithContext(ctx), self.cond, self.addr, self._reads, self._writes)

    def getDependencies(self, needed):
        return (needed - self._writes) | self._reads

    def getDependencySet(self):
        return DependencySet(self._reads, self._writes)

    def hasContinue(self):
        try:
            return not self.cond.alwaysTrue()
        except AttributeError:
            return True

    def jumps(self):
        if self.targetAddr and not self.targetAddr.isAmbiguous():
            return set([self.targetAddr])
        else:
            return set()

    def allJumps(self):
        if self.targetAddr:
            return [self.targetAddr]
        else:
            return []

    def operands(self):
        if not self.cond.alwaysTrue():
            return [self.target, self.cond]
        else:
            return [self.target]
示例#2
0
class CallInstruction(Instruction):
    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 getDependencies(self, needed):
        #return flow.getProcDeps(self.targetAddr, needed)
        deps = self.getDependencySet()
        return (needed - deps.writes) | deps.reads

    def getDependencySet(self):
        reads = set(self.target_depset.reads)
        for r in joinRegisters(reads):
            if r in self.constant_params:
                reads -= splitRegister(r)
        return DependencySet(reads, self.target_depset.writes)

    def optimizeDependencies(self, needed):
        self.returns_used = needed & self.getDependencySet().writes
        return self

    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 calls(self):
        if self.targetAddr.inPhysicalMem() and not self.targetAddr.isAmbiguous():
            return set([self.targetAddr])
        else:
            return set([])

    def operands(self):
        if not self.cond.alwaysTrue():
            return [self.target, self.cond]
        else:
            return [self.target]

    def fillParamIfKnown(self, param):
        if param in self.constant_params:
            return param + '=' + str(self.constant_params[param])
        else:
            return param

    def signature(self):
        x = ''
        if not self.cond.alwaysTrue():
            x = 'CONDITIONAL'

        depset = self.getDependencySet().onlyRegisters()
        ins = joinRegisters(depset.reads - set(['mem']))
        outs = joinRegisters(self.returns_used - set(['mem']))

        ins |= set(param+'='+str(self.constant_params[param]) for param in self.constant_params)

        ins = ', '.join(sorted(ins))
        outs = ', '.join(sorted(outs))
        if ins:
            ins = ' @ (' + ins + ')'
        if not outs:
            outs = 'void'
        return x + ins + ' -> ' + outs