Example #1
0
def is_valid(bv: bn.binaryview.BinaryView):
    sym = bv.get_symbol_by_raw_name("__elf_interp")
    if sym is None:
        return False
    else:
        var = bv.get_data_var_at(sym.address)
        return b"test_debug_info_parsing" == bv.read(sym.address,
                                                     var.type.width - 1)
Example #2
0
def restore_symbols(view: binaryninja.binaryview.BinaryView,
                    gopclntab: binaryninja.binaryview.Section) -> None:
    ptr_size = view.address_size
    """
    the .gopclntab table (starting at .gopclntab + 8) consists of
        N pc0 func0 pc1 func1 pc2 func2 ... pc(N-1) func(N-1) pcN
        
        N := no of elemements in table
        pcX := pointer to the function
        funcX := pointer to struct Func
        
        struct Func {
                uintptr entry;   // start pc
                int32 name;      // name (offset to C string)
                int32 args;      // size of arguments passed to function
                int32 frame;     // size of function frame, including saved caller PC
                int32 pcsp;      // pcsp table (offset to pcvalue table)
                int32 pcfile;    // pcfile table (offset to pcvalue table)
                int32 pcln;      // pcln table (offset to pcvalue table)
                int32 nfuncdata; // number of entries in funcdata list
                int32 npcdata;   // number of entries in pcdata list
        }; 
    src: https://docs.google.com/document/d/1lyPIbmsYbXnpNj57a261hgOYVpNRcgydurVQIyZOz_o/pub
    """
    # validate magic bytes
    magic_bytes_found = view.read(gopclntab.start, 4)
    magic_bytes_expected = b'\xfb\xff\xff\xff'
    if magic_bytes_expected != magic_bytes_found:
        log_error("Invalid .gopclntab section. Aborting!")
        return

    # get number of elements and calculate last address
    size_addr = gopclntab.start + 8  # skip first 8 bytes
    size = get_pointer_LE(view, size_addr)
    start_addr = size_addr + ptr_size
    end_addr = gopclntab.start + 8 + ptr_size + (size * ptr_size * 2)

    # iterate over the table and restore function names
    for current_addr in range(start_addr, end_addr, 2 * ptr_size):
        function_addr = get_pointer_LE(view, current_addr)
        struct_func_offset = get_pointer_LE(view, current_addr + ptr_size)
        name_str_offset = get_dword_LE(
            view, gopclntab.start + struct_func_offset + ptr_size)
        name_addr = gopclntab.start + name_str_offset
        function_name = view.get_ascii_string_at(name_addr)
        if not function_name:
            continue
        log_info(
            f'found name "{function_name}" for function starting at 0x{function_addr:x}'
        )
        function = view.get_function_at(function_addr)
        if not function:
            view.create_user_function(function_addr)
            function = view.get_function_at(function_addr)

        new_func_comment = function_name.value
        if function.comment:
            new_func_comment += "\n\n{}".format(function.comment)
        function.comment = new_func_comment
        function.name = sanitize_func_name(function_name.value)
Example #3
0
def find_segment(bv: binaryninja.binaryview.BinaryView,
                 name: str) -> List[Tuple[int, int]]:
    """
    Try to find the segment from name

    :ivar name: name of segment
    :ret: Start ant end address
    """
    result = []
    for sn in bv.sections:
        sec = bv.get_section_by_name(sn)
        if sec.name == name:
            result.append((sec.start, sec.end))
    return result
Example #4
0
def find_wevt_template(bv: binaryninja.binaryview.BinaryView, start: int,
                       end: int) -> Stream:
    """
    This function try to retrieve the WEVT_TEMPLETE resource
    This resource start with the magic CRIM

    :ivar start: start address
    :ivar end: end address
    :ret: Stream use to parse Manifest based provider or raise an exception
    :raise: ETWBreakerWevtTemplateNotFound
    """
    resource = bv.read(start, end - start)
    result = resource.find(b"CRIM")
    if result == -1:
        raise ETWBreakerWevtTemplateNotFound()

    return Stream(resource[result:])
def is_gopclntab_section(view: binaryninja.binaryview.BinaryView,
                         section: binaryninja.binaryview.Section) -> bool:
    if section.name == ".gopclntab":
        return True
    # validate magic bytes
    magic_bytes_found = view.read(section.start, 4)
    magic_bytes_expected = b'\xfb\xff\xff\xff'
    if magic_bytes_expected != magic_bytes_found:
        return False
    ptr_size = view.address_size
    first_entry = section.start + 8 + ptr_size
    first_fun_addr = get_pointer_LE(view, first_entry)
    first_entry_struct_func_offset = get_pointer_LE(view, first_entry + 8)
    fun_addr_struct_func = get_pointer_LE(
        view, section.start + first_entry_struct_func_offset)
    if first_fun_addr != fun_addr_struct_func:
        return False
    return True
Example #6
0
def parse_info(debug_info: bn.debuginfo.DebugInfo,
               bv: bn.binaryview.BinaryView):
    print("Adding types")
    types = []
    for name, t in bv.parse_types_from_string("""
  struct test_type_1 {
    int a;
    char b[4];
    uint64_t c;
    bool d;
  };

  struct test_type_2 {
    struct test_type_1 a;
    struct test_type_1* b;
    struct test_type_2* c;
  };""").types.items():
        print(
            f"  Adding type \"{name}\" `{t}` : {debug_info.add_type(str(name), t)}"
        )
        types.append(t)

    print("Adding data variables")
    pretty_print_add_data_variable(debug_info, 0x4030, types[0], "test_var_1")
    pretty_print_add_data_variable(debug_info, 0x4010,
                                   bn.types.Type.int(4, True), "test_var_2")
    # Names are optional
    pretty_print_add_data_variable(debug_info, 0x4014,
                                   bn.types.Type.int(4, True))

    t = bn.types.Type.int(4, True)
    t.const = True
    pretty_print_add_data_variable(debug_info, 0x2004, t, "test_var_3")

    print("Adding functions")
    char_star = bv.parse_type_string("char*")[0]
    pretty_print_add_function(debug_info, 0x1129,
                              "no_return_type_no_parameters", None, None,
                              bn.types.Type.void(), None)
    pretty_print_add_function(debug_info, 0x1134, "used_parameter", None, None,
                              bn.types.Type.bool(),
                              [("value", bn.types.Type.bool())])
    pretty_print_add_function(debug_info, 0x1155, "unused_parameters", None,
                              None, bn.types.Type.int(4, True),
                              [("value_1", bn.types.Type.bool()),
                               ("value_2", bn.types.Type.int(4, True)),
                               ("value_3", char_star)])
    pretty_print_add_function(debug_info, 0x1170,
                              "used_and_unused_parameters_1", None, None,
                              bn.types.Type.int(4, True),
                              [("value_1", bn.types.Type.int(4, True)),
                               ("value_2", bn.types.Type.int(4, True)),
                               ("value_3", char_star),
                               ("value_4", bn.types.Type.bool())])
    pretty_print_add_function(debug_info, 0x1191,
                              "used_and_unused_parameters_2", None, None,
                              bn.types.Type.int(1, False),
                              [("value_1", bn.types.Type.bool()),
                               ("value_2", bn.types.Type.int(1, False)),
                               ("value_3", char_star),
                               ("value_4", bn.types.Type.int(1, False)),
                               ("value_5", bn.types.Type.char())])
    pretty_print_add_function(debug_info, 0x11c0, "local_parameters", None,
                              None, bn.types.Type.void(),
                              [("value_1", bn.types.Type.bool()),
                               ("value_2", bn.types.Type.int(1, False)),
                               ("value_3", char_star),
                               ("value_4", bn.types.Type.int(1, False)),
                               ("value_5", bn.types.Type.char())])
def get_dword_LE(view: binaryninja.binaryview.BinaryView, addr: int) -> bytes:
    return struct.unpack("<I", view.read(addr, 4))[0]
def get_pointer_LE(view: binaryninja.binaryview.BinaryView,
                   addr: int) -> bytes:
    addr_size = view.address_size
    return struct.unpack("<L" if addr_size == 4 else "<Q",
                         view.read(addr, addr_size))[0]