Ejemplo n.º 1
0
def build_function_cfg(functions, insns, bbs, header, file_data):
    g = networkx.DiGraph()
    bb_entries = [ bb["first_insn"] for bb in bbs ]
    for e in bb_entries:
        g.add_node(e)
    for bb in bbs:
        bb_end = bb["last_insn"]
        last_insn = None
        targets = []
        for c, i in enumerate(insns):
            if i["addr"] == bb_end:
                last_insn = c
                break
        if last_insn:
            if insns[last_insn]["group"] in ("exec"): #and insns[last_insn]["mnem"] not in ("call", "callcc"):
                target = re_lib.resolve_target_operand(insns[last_insn], header, file_data, functions)
                if target:
                    targets.append(target)
                if insns[last_insn]["mnem"] not in ("jmp", "ret", "retn") and last_insn < len(insns) - 1:
                    targets.append(insns[last_insn+1]["addr"])
            elif insns[last_insn]["mnem"] not in ("ret", "retn") and last_insn < len(insns) - 1:
                    targets.append(insns[last_insn+1]["addr"])
                
        for t in targets:
            if t in bb_entries:
                g.add_edge(bb["first_insn"], t)
    if g.size() == 0:
        g = None
    return g
Ejemplo n.º 2
0
def find_function_call_targets( insns, header, file_data ):
    targets = set()
    for a in insns:
        if a["mnem"] in ("call", "callcc"):
            target = re_lib.resolve_target_operand( a, header, file_data )
            if target: targets.add(target)
    return targets
Ejemplo n.º 3
0
def find_targets(insns, header, file_data, functions):
    targets = set()
    for a in insns:
        if a["group"] in ("exec"):
            target = re_lib.resolve_target_operand(a, header, file_data, functions)
            if target: targets.add(target)
    return targets
Ejemplo n.º 4
0
def find_jump_targets( insns, header, file_data ):
    targets = set()
    for a in insns[:-1]:
        if a["group"] in ("exec") and a["mnem"] not in ("call", "callcc", "ret", "retn"):
            target = re_lib.resolve_target_operand( a, header, file_data )
            if target: targets.add(target)
    return targets
Ejemplo n.º 5
0
def process(oid, opts):
    logger.debug("process()")
    header = api.get_field("object_header", oid, "header")
    if not header:
        return False
    
    disasm = api.get_field("disassembly", oid, "insns")
    if not disasm:
        return False

    file_data = api.get_field(api.source(oid), oid, "data")
    if not file_data:
        return False

    internal_functions = api.retrieve("function_extract", oid)
    mapping = {}
    imps = {}
    ord_map = api.load_reference("ordinal_map")

    src_type = api.get_field("src_type", oid, "type")    
    if src_type == "PE":    
        imports = header.symbol_table
        
        for i in imports:
            if isinstance(imports[i]['name'], str): # we have a name
                imps[i] = imports[i]['name']
            else:   # we have an ordinal
                dll_name = imports[i]["dll"].lower()
                if dll_name in ord_map:
                    if imports[i]['name'] in ord_map[dll_name]:
                        imps[i] = ord_map[dll_name][imports[i]['name']]
                if i not in imps:
                    imps[i] = dll_name + ":Ordinal " + str(imports[i]['name'])
            
    data = { "system_calls":{},
             "internal_functions":{},
             "unresolved_calls":{}
           }
    
    # Find location of jump table.  Calls in program will call these stubs which then
    # jump to external functions.
    for i in disasm:
        insn = disasm[i]
        if insn["mnem"] in ("jmp"):
            target_op = insn.get("d_op", None)
            if not target_op:
                continue
            if isinstance(target_op["data"], int):
                target = target_op["data"]
            elif "disp" in target_op["data"]: 
                target = target_op["data"]["disp"]
            else:
                continue
            if target in imps:
                mapping[insn["addr"]] = imps[target]
                data["system_calls"][i] = imps[target]
    
    for i in disasm:
        insn = disasm[i]
        target = 0
        if insn["mnem"] in ("call", "callcc"):
            if insn['d_op']['type'] == 'eff_addr' and not insn['d_op']['data']['base']:
                target = insn['d_op']['data']['disp']
            else: 
                target = re_lib.resolve_target_operand(insn, header, file_data, internal_functions)
            if target in mapping: 
                data["system_calls"][i] = mapping[target] 
            elif target in imps: 
                data["system_calls"][i] = imps[target] 
            elif target in internal_functions: 
                data["internal_functions"][i] = internal_functions[target]["name"]
            else:
                data["unresolved_calls"][i] = target
            
                    
    api.store(name, oid, data, opts)
    return True