Пример #1
0
    def perform_get_instruction_info(self, data, addr):
        nfo = binaryninja.InstructionInfo()
        ins = self._get_instruction(data, addr)
        if not ins:
            # Failsafe: Assume 2 bytes if we couldn't decode the instruction.
            binaryninja.log.log_warn(
                "Could not get instruction @ 0x{:X}, assuming len=2".format(
                    addr))
            nfo.length = 2
            return nfo

        nfo.length = ins.length()

        if self._is_conditional_branch(ins):
            v = addr + ins.operands[0].immediate_value
            if v >= self.chip.ROM_SIZE:
                v -= self.chip.ROM_SIZE
            elif v < 0:
                v += self.chip.ROM_SIZE

            nfo.add_branch(BranchType.TrueBranch, v)
            nfo.add_branch(BranchType.FalseBranch, addr + 2)
        elif ins.__class__ in [
                instructions.Instruction_CPSE,
                instructions.Instruction_SBRC,
                instructions.Instruction_SBRS,
                instructions.Instruction_SBIC,
                instructions.Instruction_SBIS,
        ]:
            # TODO: This should skip a whole instruction but we don't know how
            # big the next instruction is (2 or 4 bytes).
            # Assume two bytes for now as it is pretty much always followed by a
            # rjmp
            nfo.add_branch(BranchType.TrueBranch, addr + 4)
            nfo.add_branch(BranchType.FalseBranch, addr + 2)
        elif isinstance(ins, instructions.Instruction_JMP):
            nfo.add_branch(BranchType.UnconditionalBranch,
                           ins.operands[0].immediate_value)
        elif isinstance(ins, instructions.Instruction_CALL):
            nfo.add_branch(BranchType.CallDestination,
                           ins.operands[0].immediate_value)
        elif (isinstance(ins, instructions.Instruction_RET)
              or isinstance(ins, instructions.Instruction_RETI)):
            nfo.add_branch(BranchType.FunctionReturn)
        elif (isinstance(ins, instructions.Instruction_RCALL)):
            v = addr + ins.operands[0].immediate_value
            if v >= self.chip.ROM_SIZE:
                v -= self.chip.ROM_SIZE
            elif v < 0:
                v += self.chip.ROM_SIZE

            nfo.add_branch(BranchType.CallDestination, v)
        elif (isinstance(ins, instructions.Instruction_RJMP)):
            v = addr + ins.operands[0].immediate_value
            if v >= self.chip.ROM_SIZE:
                v -= self.chip.ROM_SIZE
            elif v < 0:
                v += self.chip.ROM_SIZE

            nfo.add_branch(BranchType.UnconditionalBranch, v)
        elif (isinstance(ins, instructions.Instruction_ICALL)
              or isinstance(ins, instructions.Instruction_EICALL)
              or isinstance(ins, instructions.Instruction_IJMP)
              or isinstance(ins, instructions.Instruction_EIJMP)):
            nfo.add_branch(BranchType.IndirectBranch)
        else:
            # TODO: Doublecheck that there are no more controlflow modifying
            # operations.
            pass

        return nfo
Пример #2
0
 def info(self):
     ii = bn.InstructionInfo()
     if self.delay:
         ii.branch_delay = True
     ii.length = len(self)
     return ii
Пример #3
0
 def get_instruction_info(self, data, addr):
     instr = WasmDisasm.disasm(data, addr)
     ins_info = binaryninja.InstructionInfo()
     ins_info.length = instr.size
     return ins_info