Example #1
0
def get_code_and_blocks(ea):
    """Extracts the control flow graph for the function at the given address.
  Returns a dictionary with the instructions (ea->insn.Instruction) and a list
  of the basic blocs (bbl.BasicBlock)."""

    code = {}
    blocks = {}
    ida_blocks = set(idaapi.FlowChart(idaapi.get_func(ea)))

    for bb in ida_blocks:

        # XXX: it seems that it's not a bug but inter-function jumps!
        if bb.startEA == bb.endEA:  # skip that .. it's IDA's bug
            #print "skipping block %x : %x in func %x"%(bb.startEA, bb.endEA, ea)
            continue

        blocks[bb.startEA] = bbl.BasicBlock(bb.startEA, bb.endEA, {})

        for head in idautils.Heads(bb.startEA, bb.endEA):
            ibytes = idc.GetManyBytes(head, idc.ItemEnd(head) - head)
            spd = idc.GetSpd(head)
            code[head] = insn.Instruction(head, ibytes, spd)
            blocks[bb.startEA].instrs.append(code[head])
            next_head = idc.NextHead(head, bb.endEA)

            if idaapi.isFlow(idc.GetFlags(next_head)):
                code[head].succ.add(next_head)

        for suc_bb in (s for s in bb.succs() if s.startEA != s.endEA):
            #assume head is the last instruction of the block
            code[head].succ.add(suc_bb.startEA)

    for bb in (b for b in ida_blocks if b.startEA != b.endEA):
        for suc_bb in (s for s in bb.succs() if s.startEA != s.endEA):
            # a jump with zero offset (like, jz 0) gives two succs to the same bb
            if blocks[suc_bb.startEA] not in blocks[bb.startEA].successors:
                blocks[bb.startEA].successors.append(blocks[suc_bb.startEA])
        blocks[bb.startEA].successors.sort(key=lambda x: x.begin, reverse=True)

    #FIXME: find a better way ..
    for block in blocks.itervalues():
        if block.instrs[0].addr == ea:
            #print "found the entry!:", block.instrs
            block.instrs[0].f_entry = True
            block.type |= bbl.BasicBlock.ENTRY
            break
    else:
        print "BUG: could not find function entry in instrs!!"
    #print "blocks:", blocks

    return code, blocks.values()
Example #2
0
def get_code_and_blocks(ea):
    """Extracts the control flow graph for the function at the given address.
    Returns a dictionary with the instructions (ea->insn.Instruction) and a list
    of the basic blocs (bbl.BasicBlock)."""
    code = {}
    blocks = {}
    ida_blocks = set(idaapi.FlowChart(idaapi.get_func(ea)))

    for bb in ida_blocks:
        
        # XXX: it seems that it's not a bug but inter-function jumps!
        if bb.startEA == bb.endEA: # skip that .. it's IDA's bug
            #print "skipping block %x : %x in func %x"%(bb.startEA, bb.endEA, ea)
            continue

        blocks[bb.startEA] = bbl.BasicBlock(bb.startEA, bb.endEA, {})
        
        for head in idautils.Heads(bb.startEA, bb.endEA):
            ibytes = idc.GetManyBytes(head, idc.ItemEnd(head) - head)
            spd = idc.GetSpd(head)
            code[head] = insn.Instruction(head, ibytes, spd)
            blocks[bb.startEA].instrs.append(code[head])
            next_head = idc.NextHead(head, bb.endEA)

            if idaapi.isFlow(idc.GetFlags(next_head)):
                code[head].succ.add(next_head)
        
        for suc_bb in (s for s in bb.succs() if s.startEA != s.endEA):
            #assume head is the last instruction of the block
            code[head].succ.add(suc_bb.startEA)
    
    for bb in (b for b in ida_blocks if b.startEA != b.endEA):
        for suc_bb in (s for s in bb.succs() if s.startEA != s.endEA):
            # a jump with zero offset (like, jz 0) gives two succs to the same bb
            if blocks[suc_bb.startEA] not in blocks[bb.startEA].successors:
                blocks[bb.startEA].successors.append(blocks[suc_bb.startEA])
        blocks[bb.startEA].successors.sort(key=lambda x: x.begin, reverse=True)

    #FIXME: find a better way ..
    for block in blocks.itervalues():
        if block.instrs[0].addr == ea:
            #print "found the entry!:", block.instrs
            block.instrs[0].f_entry = True
            block.type |= bbl.BasicBlock.ENTRY
            break
    else:
        print "BUG: could not find function entry in instrs!!"
    #print "blocks:", blocks

    return code, blocks.values()
Example #3
0
    def run(self, arg):
        idaapi.msg("[%s] Syncing with WS Server\n" % (self.wanted_name,))
        self.addr = idaapi.get_screen_ea()
        if self.old_addr != self.addr:
            # check against idc.BADADDR and None before going
            if (self.addr is not None) and (self.addr != idc.BADADDR):
                # Code Address
                if idaapi.isCode(idaapi.getFlags(self.addr)):
                    # don't set the address if it's already the qira_address
                    if self.addr != self.qira_address:
                        # debugging
                        if DEBUG:
                            idaapi.msg(
                                "[%s] Qira Address 0x%x \n" %
                                (self.wanted_name, self.addr,))
                        # Instruction Address
                        self.set_qira_address(self.addr)
                        self.update_address("iaddr", self.addr)
                # Data Address
                elif idaapi.isData(idaapi.getFlags(self.addr)):
                    self.update_address("daddr", self.addr)
                # Tail Address
                elif idaapi.isTail(idaapi.getFlags(self.addr)):
                    self.update_address("taddr", self.addr)
                # Unknown Address
                elif idaapi.isUnknown(idaapi.getFlags(self.addr)):
                    self.update_address("uaddr", self.addr)
                # Head Address
                elif idaapi.isHead(idaapi.getFlags(self.addr)):
                    self.update_address("haddr", self.addr)
                # Flow Address
                elif idaapi.isFlow(idaapi.getFlags(self.addr)):
                    self.update_address("faddr", self.addr)
                # Var Address
                elif idaapi.isVar(idaapi.getFlags(self.addr)):
                    self.update_address("vaddr", self.addr)
                # Data Address
                else:
                    self.update_address("daddr", self.addr)

        self.old_addr = self.addr
Example #4
0
    def __init__(self, functionName):
        import idautils
        import idc
        import idaapi
        super(FunctionGraph, self).__init__()

        start_addr = 0
        if type(functionName) == type('str'):
          start_addr = idc.LocByName(functionName)
        else:
          start_addr = idaapi.get_func(functionName).startEA
          print 'using 0x%x as function start' % (start_addr)

        self.start_addr = start_addr

        end_addr = idc.FindFuncEnd(start_addr)

        self.start_addr = start_addr
        self.end_addr = end_addr

        self.name = functionName

        for h in idautils.Heads(start_addr, end_addr):
            if h == idc.BADADDR:
                continue
            if not idc.isCode(idc.GetFlags(h)):
                continue


            self.add_node(h)
            refs = set(filter(lambda x: x <= end_addr and x >= start_addr, idautils.CodeRefsFrom(h,1)))
            nh = idc.NextHead(h, end_addr)
            if nh != idc.BADADDR and \
              (idaapi.isFlow(idaapi.get_flags_ex(nh,0)) or idaapi.is_call_insn(h)):
                refs.add(nh)

            for r in refs:
                self.connect(h, r)