Пример #1
0
def graph_connect (dbg, buff_addr, size, realloc=False):
    global count, graph
    count += 1

    eip = dbg.context.Eip

    allocator = pgraph.node(eip)
    allocated = pgraph.node(buff_addr)

    allocator.label = "%08x" % eip
    allocated.label = "%d" % size
    allocated.size  = size

    allocator.color = 0xFFAC59

    if realloc:
        allocated.color = 0x46FF46
    else:
        allocated.color = 0x59ACFF

    graph.add_node(allocator)
    graph.add_node(allocated)

    edge = pgraph.edge(allocator.id, allocated.id)
    edge.label = "%d" % count

    graph.add_edge(edge)
Пример #2
0
def graph_connect(dbg, buff_addr, size, realloc=False):
    global count, graph
    count += 1

    eip = dbg.context.Eip

    allocator = pgraph.node(eip)
    allocated = pgraph.node(buff_addr)

    allocator.label = "%08x" % eip
    allocated.label = "%d" % size
    allocated.size = size

    allocator.color = 0xFFAC59

    if realloc:
        allocated.color = 0x46FF46
    else:
        allocated.color = 0x59ACFF

    graph.add_node(allocator)
    graph.add_node(allocated)

    edge = pgraph.edge(allocator.id, allocated.id)
    edge.label = "%d" % count

    graph.add_edge(edge)
Пример #3
0
    def __init_basic_blocks__(self):
        '''
        Enumerate the basic block boundaries for the current function and store them in a graph structure.
        
        '''
        import copy
        self.chunks = self.__init_collect_function_chunks__()
        contained_heads = sum([[ea for ea in Heads(chunk_start, chunk_end)]
                               for (chunk_start, chunk_end) in self.chunks],
                              list())
        blocks = []
        edges = []

        for (chunk_start, chunk_end) in self.chunks:

            curr_start = chunk_start
            # enumerate the nodes.
            for ea in Heads(chunk_start, chunk_end):
                # ignore data heads.
                if not isCode(GetFlags(ea)):
                    curr_start = NextNotTail(ea)
                    continue

                next_ea = NextNotTail(ea)
                branches_to_next = self._branches_to(next_ea)
                branches_from = self._branches_from(ea)
                is_retn = idaapi.is_ret_insn(ea)

                if is_retn or not isCode(GetFlags(next_ea)):
                    blocks.append((curr_start, ea))
                    curr_start = next_ea  #this will be handled if still not code

                elif len(branches_from) > 0:
                    blocks.append((curr_start, ea))
                    curr_start = next_ea

                    for branch in branches_from:
                        if branch not in contained_heads:
                            continue
                        if len(branches_from) == 1: color = 0x0000FF
                        elif branch == next_ea: color = 0xFF0000
                        else: color = 0x00FF00
                        edges.append((curr_start, branch, color))

                elif len(branches_to_next) > 0:
                    blocks.append((curr_start, ea))
                    curr_start = next_ea
                    # draw an "implicit" branch.
                    edges.append((ea, next_ea, 0x0000FF))

        basicBlocks = [basic_block(bs,be,self.depth, self.analysis, self)\
                        for (bs,be) in blocks]
        map(self.add_node, basicBlocks)

        for (src, dst, color) in edges:
            edge = pgraph.edge(src, dst)
            edge.color = color
            self.add_edge(edge)
Пример #4
0
    def __init_basic_blocks__ (self):
        '''
        Enumerate the basic block boundaries for the current function and store them in a graph structure.
        
        '''
        import copy
        self.chunks = self.__init_collect_function_chunks__()
        contained_heads = sum([[ea for ea in Heads(chunk_start, chunk_end)] for (chunk_start, chunk_end) in self.chunks],list())
        blocks = []        
        edges = []
        
        for (chunk_start, chunk_end) in self.chunks:

            curr_start = chunk_start
            # enumerate the nodes.
            for ea in Heads(chunk_start, chunk_end):
                # ignore data heads.
                if not isCode(GetFlags(ea)):
                    curr_start = NextNotTail(ea)
                    continue

                next_ea       = NextNotTail(ea)
                branches_to_next = self._branches_to(next_ea)       
                branches_from = self._branches_from(ea)
                is_retn = idaapi.is_ret_insn(ea)
                
                if is_retn or not isCode(GetFlags(next_ea)):
                    blocks.append((curr_start,ea))
                    curr_start = next_ea  #this will be handled if still not code
                    
        
                elif len(branches_from) > 0:
                    blocks.append((curr_start,ea))
                    curr_start = next_ea
                    
                    for branch in branches_from:
                        if branch not in contained_heads:
                            continue
                        if len(branches_from) == 1:  color = 0x0000FF
                        elif branch == next_ea:      color = 0xFF0000
                        else:                        color = 0x00FF00
                        edges.append((curr_start, branch, color))
                 
                elif len(branches_to_next)> 0:
                    blocks.append((curr_start,ea))
                    curr_start = next_ea
                    # draw an "implicit" branch.
                    edges.append((ea, next_ea, 0x0000FF))
                    
        basicBlocks = [basic_block(bs,be,self.depth, self.analysis, self)\
                        for (bs,be) in blocks]
        map(self.add_node,basicBlocks)
        
        for (src, dst, color) in edges:
            edge = pgraph.edge(src, dst)
            edge.color = color
            self.add_edge(edge)
Пример #5
0
    def __init_enumerate_imports__ (self):
        '''
        Enumerate and add nodes / edges for each import within the module. This routine will pass through the entire
        module structure.
        '''

        for func in self.nodes.values():
            for bb in func.nodes.values():
                for instruction in bb.instructions.values():
                    if instruction.refs_api:
                        (address, api) = instruction.refs_api

                        node = function(address, module=self)
                        node.color = 0xB4B4DA
                        self.add_node(node)

                        edge = pgraph.edge(func.ea_start, address)
                        self.add_edge(edge)
Пример #6
0
    def __init_enumerate_imports__(self):
        '''
        Enumerate and add nodes / edges for each import within the module. This routine will pass through the entire
        module structure.
        '''

        for func in self.nodes.values():
            for bb in func.nodes.values():
                for instruction in bb.instructions.values():
                    if instruction.refs_api:
                        (address, api) = instruction.refs_api

                        node = function(address, module=self)
                        node.color = 0xB4B4DA
                        self.add_node(node)

                        edge = pgraph.edge(func.ea_start, address)
                        self.add_edge(edge)
Пример #7
0
    print "[%d] %s" % (len(crashes), synopsis)
    print "\t",

    for crash in crashes:
        if graph:
            last = crash_node.id
            for entry in crash.stack_unwind:
                address = long(entry.split(":")[1], 16)
                n = graph.find_node("id", address)

                if not n:
                    n = pgraph.node(address)
                    n.count = 1
                    n.label = "[%d] %s" % (n.count, entry)
                    graph.add_node(n)
                else:
                    n.count += 1
                    n.label = "[%d] %s" % (n.count, entry)

                edge = pgraph.edge(n.id, last)
                graph.add_edge(edge)
                last = n.id
        print "%s," % crash.extra,

    print "\n"

if graph:
    fh = open("%s.udg" % graph_name, "w+")
    fh.write(graph.render_graph_udraw())
    fh.close()
Пример #8
0
    def __init__ (self, name="", signature=None, depth=DEPTH_FULL, analysis=ANALYSIS_NONE):
        '''
        Analysis of an IDA database requires the instantiation of this class and will handle, depending on the requested
        depth, the analysis of all functions, basic blocks, instructions and more specifically which analysis techniques
        to apply. For the full list of ananylsis options see defines.py. Specifying ANALYSIS_IMPORTS will require an
        extra one-time scan through the entire structure to propogate functions (nodes) and cross references (edges) for
        each reference API call. Specifying ANALYSIS_RPC will require an extra one-time scan through the entire IDA
        database and will propogate additional function level attributes.

        The signature attribute was added for use in the PaiMei process stalker module, for ensuring that a loaded
        DLL is equivalent to the PIDA file with matching name. Setting breakpoints in a non-matching module is
        obviously no good.

        @see: defines.py

        @type  name:      String
        @param name:      (Optional) Module name
        @type  signature: String
        @param signature: (Optional) Unique file signature to associate with module
        @type  depth:     Integer
        @param depth:     (Optional, Def=DEPTH_FULL) How deep to analyze the module
        @type  analysis:  Integer
        @param analysis:  (Optional, Def=ANALYSIS_NONE) Which extra analysis options to enable
        '''

        # run the parent classes initialization routine first.
        super(module, self).__init__(name)

        self.name      = name
        self.base      = MinEA() - 0x1000      # XXX - cheap hack
        self.depth     = depth
        self.analysis  = analysis
        self.signature = signature
        self.ext       = {}
        self.log       = True

        # convenience alias.
        self.functions = self.nodes

        # enumerate and add the functions within the module.
        if self.log:
            print "Analyzing functions..."

        for ea in Functions(MinEA(), MaxEA()):
            func = function(ea, self.depth, self.analysis, self)
            func.shape = "ellipse"
            self.add_node(func)

        # enumerate and add nodes for each import within the module.
        if self.depth & DEPTH_INSTRUCTIONS and self.analysis & ANALYSIS_IMPORTS:
            if self.log:
                print"Enumerating imports..."

            self.__init_enumerate_imports__()

        # enumerate and propogate attributes for any discovered RPC interfaces.
        if self.analysis & ANALYSIS_RPC:
            if self.log:
                print "Enumerating RPC interfaces..."

            self.__init_enumerate_rpc__()

        # enumerate and add the intramodular cross references.
        if self.log:
            print "Enumerating intramodular cross references..."

        for func in self.nodes.values():
            xrefs = list(CodeRefsTo(func.ea_start, 0))
            xrefs.extend(list(DataRefsTo(func.ea_start)))

            for ref in xrefs:
                from_func = get_func(ref)

                if from_func:
                    # GHETTO - add the actual source EA to the function.
                    if not self.nodes[from_func.startEA].outbound_eas.has_key(ref):
                        self.nodes[from_func.startEA].outbound_eas[ref] = []

                    self.nodes[from_func.startEA].outbound_eas[ref].append(func.ea_start)

                    edge = pgraph.edge(from_func.startEA, func.ea_start)

                    self.add_edge(edge)
Пример #9
0
    def __init__(self,
                 name="",
                 signature=None,
                 depth=DEPTH_FULL,
                 analysis=ANALYSIS_NONE):
        '''
        Analysis of an IDA database requires the instantiation of this class and will handle, depending on the requested
        depth, the analysis of all functions, basic blocks, instructions and more specifically which analysis techniques
        to apply. For the full list of ananylsis options see defines.py. Specifying ANALYSIS_IMPORTS will require an
        extra one-time scan through the entire structure to propogate functions (nodes) and cross references (edges) for
        each reference API call. Specifying ANALYSIS_RPC will require an extra one-time scan through the entire IDA
        database and will propogate additional function level attributes.

        The signature attribute was added for use in the PaiMei process stalker module, for ensuring that a loaded
        DLL is equivalent to the PIDA file with matching name. Setting breakpoints in a non-matching module is
        obviously no good.

        @see: defines.py

        @type  name:      String
        @param name:      (Optional) Module name
        @type  signature: String
        @param signature: (Optional) Unique file signature to associate with module
        @type  depth:     Integer
        @param depth:     (Optional, Def=DEPTH_FULL) How deep to analyze the module
        @type  analysis:  Integer
        @param analysis:  (Optional, Def=ANALYSIS_NONE) Which extra analysis options to enable
        '''

        # run the parent classes initialization routine first.
        super(module, self).__init__(name)

        self.name = name
        self.base = MinEA() - 0x1000  # XXX - cheap hack
        self.depth = depth
        self.analysis = analysis
        self.signature = signature
        self.ext = {}
        self.log = True

        # convenience alias.
        self.functions = self.nodes

        # enumerate and add the functions within the module.
        if self.log:
            print "Analyzing functions..."

        for ea in Functions(MinEA(), MaxEA()):
            func = function(ea, self.depth, self.analysis, self)
            func.shape = "ellipse"
            self.add_node(func)

        # enumerate and add nodes for each import within the module.
        if self.depth & DEPTH_INSTRUCTIONS and self.analysis & ANALYSIS_IMPORTS:
            if self.log:
                print "Enumerating imports..."

            self.__init_enumerate_imports__()

        # enumerate and propogate attributes for any discovered RPC interfaces.
        if self.analysis & ANALYSIS_RPC:
            if self.log:
                print "Enumerating RPC interfaces..."

            self.__init_enumerate_rpc__()

        # enumerate and add the intramodular cross references.
        if self.log:
            print "Enumerating intramodular cross references..."

        for func in self.nodes.values():
            xrefs = list(CodeRefsTo(func.ea_start, 0))
            xrefs.extend(list(DataRefsTo(func.ea_start)))

            for ref in xrefs:
                from_func = get_func(ref)

                if from_func:
                    # GHETTO - add the actual source EA to the function.
                    if not self.nodes[from_func.startEA].outbound_eas.has_key(
                            ref):
                        self.nodes[from_func.startEA].outbound_eas[ref] = []

                    self.nodes[from_func.startEA].outbound_eas[ref].append(
                        func.ea_start)

                    edge = pgraph.edge(from_func.startEA, func.ea_start)

                    self.add_edge(edge)
Пример #10
0
    print "[%d] %s" % (len(crashes), synopsis)
    print "\t",

    for crash in crashes:
        if graph:
            last = crash_node.id
            for entry in crash.stack_unwind:
                address = long(entry.split(":")[1], 16)
                n = graph.find_node("id", address)

                if not n:
                    n       = pgraph.node(address)
                    n.count = 1
                    n.label = "[%d] %s" % (n.count, entry)
                    graph.add_node(n)
                else:
                    n.count += 1
                    n.label = "[%d] %s" % (n.count, entry)

                edge = pgraph.edge(n.id, last)
                graph.add_edge(edge)
                last = n.id
        print "%d," % crash.extra,

    print "\n"

if graph:
    fh = open("%s.udg" % graph_name, "w+")
    fh.write(graph.render_graph_udraw())
    fh.close()