Exemplo n.º 1
0
    def __init__(self, interactive=False):
        if interactive:
            csv_file = OpenFileNameField("Import csv file")
            get_form_input([csv_file], "Polypyus Import Options")
            self.verbose = True
            if csv_file.result == "":
                self.csv_file = None
            else:
                self.csv_file = csv_file.result
            self.output_name = None
        return

        # headless
        descr = "Export functions from a Polypyus csv into an existing Binary Ninja database."
        parser = ArgumentParser(description=descr)
        parser.add_argument("csv",
                            type=FileType("w"),
                            help="Path to Polypyus csv.")
        parser.add_argument("bndb",
                            type=FileType("r"),
                            help="Path to Binary Ninja database.")
        args = parser.parse_args()
        self.csv_file = args.csv
        self.input_file = args.csv
        self.output_name = args.bndb
Exemplo n.º 2
0
def generate_all_platforms(bv):
    platforms = [i.name for i in list(Platform)]

    header_file = OpenFileNameField("Select Header File")
    lib_name = TextLineField("Type Library Name")
    file_name = TextLineField("File Name")
    get_form_input([header_file, lib_name, file_name], "Generate Type Library")

    try:
        for p in list(Platform):
            typelib = generate_typelib(p, header_file.result, lib_name.result)
            path = typelib_path / p.name / "{}.bntl".format(file_name.result)
            typelib.write_to_file(str(path.resolve()))
    except SyntaxError as e:
        show_message_box("Error", e.msg)
Exemplo n.º 3
0
def easypatch(bv, addr):
    """
    Shows a dialog containing all memory operands at current instruction
    and prompts for data to overwrite with. Expression is eval()ed so
    \n and \0 are valid inputs
    """
    targets = get_memory_operands_at(bv, addr)
    targets_field = interaction.ChoiceField('Patch Target:', targets)
    patch_text_field = interaction.TextLineField('Patch text:')
    valid_input = interaction.get_form_input([targets_field, patch_text_field],
                                             'easypatch')

    if valid_input:
        target = targets[targets_field.result].addr
        patch_text = eval("'%s'" % patch_text_field.result)

        if not bv.write(target, patch_text):
            if not make_valid_for_writing(bv, target, len(patch_text)):
                interaction.show_message_box(
                    'easypatch', 'Failed to make writable to %x' % target)
            elif not bv.write(target, patch_text):
                interaction.show_message_box('easypatch',
                                             'Failed to write to %x' % target)
            else:
                function = bv.get_basic_blocks_at(addr)[0].function
                function.reanalyze()
        else:
            function = bv.get_basic_blocks_at(addr)[0].function
            function.reanalyze()
Exemplo n.º 4
0
def generate_single_platform(bv):
    arch_choices = [i.name for i in list(Platform)]

    header_file = OpenFileNameField("Select Header File")
    arch = ChoiceField("Select Architecture", arch_choices)
    name = TextLineField("Type Library Name")
    save_file = SaveFileNameField("Save Type Library", ext="bntl")
    get_form_input([header_file, arch, name, save_file], "Generate Type Library")

    arch = arch_choices[arch.result]
    platform = Platform[arch]

    try:
        typelib = generate_typelib(platform, header_file.result, name.result)
        typelib.write_to_file(save_file.result)
    except SyntaxError as e:
        show_message_box("Error", e.msg.decode())
Exemplo n.º 5
0
def abi_dialog(view, addr):
    func = get_function_defined_or_referred_at(view, addr)

    def show_error(text):
        bni.show_message_box("ABI Error",
                             text,
                             icon=bne.MessageBoxIcon.ErrorIcon)

    arch = view.platform.arch
    cconvs = view.platform.calling_conventions
    cconv_names = list(map(lambda x: x.name, cconvs))
    cconv = func.calling_convention
    clobbers = set(func.clobbered_regs)
    cconv_clobbers = set([cconv.int_return_reg] + cconv.int_arg_regs +
                         cconv.caller_saved_regs)
    add_clobbers = clobbers.difference(cconv_clobbers)
    remove_clobbers = cconv_clobbers.difference(clobbers)

    cconv_field = bni.ChoiceField("Calling convention", cconv_names)
    cconv_field.result = cconvs.index(cconv)
    cconv_current_field = "(current: {})".format(cconv)

    add_clobber_field = bni.TextLineField("Additional clobbers")
    add_clobber_field.result = " ".join(list(map(str, add_clobbers)))
    add_clobber_current_field = "(current: {})".format(
        add_clobber_field.result)

    remove_clobber_field = bni.TextLineField("Excluded clobbers")
    remove_clobber_field.result = " ".join(list(map(str, remove_clobbers)))
    remove_clobber_current_field = "(current: {})".format(
        remove_clobber_field.result)

    fields = [
        "Note: it's not currently possible to pre-fill the fields,",
        "so please manually set the ones you don't want to change to current values",
        cconv_field, cconv_current_field, add_clobber_field,
        add_clobber_current_field, remove_clobber_field,
        remove_clobber_current_field
    ]
    if bni.get_form_input(fields, "Function ABI"):
        cconv = cconvs[cconv_field.result]

        add_clobbers = set(add_clobber_field.result.split())
        remove_clobbers = set(remove_clobber_field.result.split())
        for reg in add_clobbers | remove_clobbers:
            if reg not in arch.regs:
                show_error("{} is not a valid {} register.".format(
                    reg, arch.name))
                return

        func.calling_convention = cconv

        clobbers = set([cconv.int_return_reg] + cconv.int_arg_regs +
                       cconv.caller_saved_regs)
        clobbers.update(add_clobbers)
        clobbers.difference_update(remove_clobbers)
        func.clobbered_regs = list(clobbers)
Exemplo n.º 6
0
def save_svg(bv, function):
    sym = bv.get_symbol_at(function.start)
    if sym:
        offset = sym.name
    else:
        offset = "%x" % function.start
    path = Path(os.path.dirname(bv.file.filename))
    origname = os.path.basename(bv.file.filename)
    filename = path / f'binaryninja-{origname}-{offset}.html'

    functionChoice = TextLineField("Blank to accept default")
    # TODO: implement linear disassembly settings and output
    modeChoices = ["Graph"]
    modeChoiceField = ChoiceField("Mode", modeChoices)
    if Settings().get_bool('ui.debugMode'):
        formChoices = [
            "Assembly", "Lifted IL", "LLIL", "LLIL SSA", "Mapped Medium",
            "Mapped Medium SSA", "MLIL", "MLIL SSA", "HLIL", "HLIL SSA"
        ]
        formChoiceField = ChoiceField("Form", formChoices)
    else:
        formChoices = ["Assembly", "LLIL", "MLIL", "HLIL"]
        formChoiceField = ChoiceField("Form", formChoices)

    showOpcodes = ChoiceField("Show Opcodes", ["Yes", "No"])
    showAddresses = ChoiceField("Show Addresses", ["Yes", "No"])

    saveFileChoices = SaveFileNameField("Output file", 'HTML files (*.html)',
                                        str(filename))
    if not get_form_input([
            f'Current Function: {offset}', functionChoice, formChoiceField,
            modeChoiceField, showOpcodes, showAddresses, saveFileChoices
    ], "SVG Export") or saveFileChoices.result is None:
        return
    if saveFileChoices.result == '':
        outputfile = filename
    else:
        outputfile = saveFileChoices.result
    content = render_svg(function, offset, modeChoices[modeChoiceField.result],
                         formChoices[formChoiceField.result],
                         showOpcodes.result == 0, showAddresses.result == 0,
                         origname)
    output = open(outputfile, 'w')
    output.write(content)
    output.close()
    result = show_message_box("Open SVG",
                              "Would you like to view the exported SVG?",
                              buttons=MessageBoxButtonSet.YesNoButtonSet,
                              icon=MessageBoxIcon.QuestionIcon)
    if result == MessageBoxButtonResult.YesButton:
        # might need more testing, latest py3 on windows seems.... broken with these APIs relative to other platforms
        if sys.platform == 'win32':
            webbrowser.open(outputfile)
        else:
            webbrowser.open('file://' + str(outputfile))
Exemplo n.º 7
0
Arquivo: ief.py Projeto: etke/ief
def ief_find_library(binview):
    """ run `ief <path> -l <partial library name>` """
    name = TextLineField("Library name (can be partial)")
    directory = DirectoryNameField(
        "Directory to search", dirname(binview.file.filename))
    get_form_input([name, None, directory],
                   "Find binaries that import library")
    if not directory.result:
        directory.result = dirname(binview.file.filename)
    if name.result is None:
        return
    # Assumes `~/.cargo/bin` already exists in PATH
    result = run(["ief", directory.result, "-l",
                  name.result], capture_output=True)
    directory = directory.result
    markdown = f"# Results - binaries in '[{directory}]({directory})'" \
        f"with imported library name containing '_{name.result}_'\n\n"
    for line in result.stdout.split(b"\n")[1:-1]:
        npath = normpath(line.decode('utf-8'))
        markdown += f"* [{npath}]({npath})\n"
    show_markdown_report(f"IEF - {name.result}",
                         markdown, result.stdout.decode('utf-8'))
Exemplo n.º 8
0
def run_plugin(bv):
    patch_text_field = interaction.MultilineTextField(
        "Instruction(s) to convert to nop's (e.g. int3)")
    res = interaction.get_form_input([patch_text_field], 'Find And Nop')

    if res == False:
        return

    lines = patch_text_field.result.split("\n")

    special_characters = ",[]-+*:"
    pattern = []
    for line in lines:
        temp = line
        for char in special_characters:
            temp = temp.replace(char, " " + char + " ")
        # remove double spaces
        temp = ' '.join(temp.split())
        temp = temp.split()
        pattern.append(temp)

    pattern_len = len(pattern)
    for func in bv.functions:
        func_instr_list = list(func.instructions)
        for idx, inst in enumerate(func_instr_list):
            if (idx + pattern_len) > len(func_instr_list):
                # pattern too long for this function set, check next function
                break
            if check_pattern(pattern, func_instr_list[idx:idx + pattern_len],
                             bv):
                for i in range(pattern_len):
                    # original code as comment
                    comment(func, inst[1], "FaN: " + str(pattern))
                    bv.convert_to_nop(func_instr_list[idx + i][1])

    interaction.show_message_box(
        "Possible Reload Required",
        "Maybe you have to save and reload the binary because the functions aren't updated. E.g. if you have replaced int3 instructions the code flow will change."
    )
Exemplo n.º 9
0
def show_delphi_modal(bv: BinaryView):
    global _version_mapping
    global _arch_mapping

    arch_mapping = copy.copy(_arch_mapping)

    if bv.arch is not None and bv.arch.address_size == 8:
        arch_mapping.reverse()

    version_field = interaction.ChoiceField('Delphi version',
                                            [x for x, _ in _version_mapping])

    arch_field = interaction.ChoiceField('Architecture (ptr size)',
                                         [x for x, _ in arch_mapping])

    normalize_section_name = lambda x: f'{x.name} {{0x{x.start:x}-0x{x.end:x}}}'
    normalize_section_tuple = lambda x: (normalize_section_name(x),
                                         (x.start, x.end))

    sections = sorted(bv.sections.values(), key=lambda x: x.start)
    range_mapping = [('Whole binary', (bv.start, bv.end))
                     ] + [normalize_section_tuple(x) for x in sections]
    range_field = interaction.ChoiceField('Search area',
                                          [x for x, _ in range_mapping])

    result = interaction.get_form_input(
        [version_field, arch_field, range_field], "Search options")

    if not result:
        return None

    return {
        'delphi_version': _version_mapping[version_field.result][1],
        'offset_ptr_size': arch_mapping[arch_field.result][1],
        'start': range_mapping[range_field.result][1][0],
        'end': range_mapping[range_field.result][1][1],
    }
Exemplo n.º 10
0
    def __init__(self, interactive=False):
        if interactive:
            import_strings_choice = ChoiceField("Import Strings", ["Yes", "No"])
            import_string_name_choice = ChoiceField("Import String Names", ["Yes", "No"])
            import_function_choice = ChoiceField("Import Functions", ["Yes", "No"])
            import_comment_choice = ChoiceField("Import Comments", ["Yes", "No"])
            json_file = OpenFileNameField("Import json file")
            get_form_input([json_file, import_strings_choice, import_string_name_choice, import_function_choice, 
                import_comment_choice], "IDA Import Options")

            self.import_strings = import_strings_choice.result == 0
            self.import_strings_names = import_string_name_choice.result == 0
            self.import_functions = import_function_choice.result == 0
            self.import_comments = import_comment_choice.result == 0
            self.verbose = True
            if json_file.result == '':
                self.json_file = None
            else:
                self.json_file = json_file.result
            self.output_name = None
        else:
            usage = "usage: %prog [options] <ida_export.json> <file|bndb>"
            parser = OptionParser(usage=usage)

            parser.add_option("-q", "--quiet",
                dest="verbose",
                action="store_false",
                default=True,
                help="Don't display automatic actions")
            parser.add_option("-s", "--no-strings",
                dest="import_strings",
                action="store_false",
                default=True,
                help="Don't import string data")
            parser.add_option("-n", "--no-string-names",
                dest="import_strings_names",
                action="store_false",
                default=True,
                help="Don't import string names")
            parser.add_option("-o", "--output-name",
                dest="output_name",
                action="store",
                default=None,
                help="Specify output name of bndb. Defaults to <file_name>.bndb")
            parser.add_option("-f", "--no-functions",
                dest="import_functions",
                action="store_false",
                default=True,
                help="Don't import function starts")
            parser.add_option("-c", "--no-comments",
                dest="import_comments",
                action="store_false",
                default=True,
                help="Don't import comments")

            (options, args) = parser.parse_args()
            self.import_strings = options.import_strings
            self.import_strings_names = options.import_strings_names
            self.import_functions = options.import_functions
            self.import_comments = options.import_comments
            self.verbose = options.verbose
            self.json_file = args[0]
            self.input_file = args[0]
            self.output_name = options.output_name
            if self.output_name is None:
                self.output_name = self.input_file + ".bndb"
            self.usage = parser.get_usage()
Exemplo n.º 11
0
    config = {"host": host, "port": port, "nick": nick, "password": password}
    with open(os.path.join(path, "config.json"), "w") as f:
        config = f.write(json.dumps(config))


try:
    import binaryninja
    import binaryninja.interaction as bi
    try:
        import config
    except ImportError:
        host_f = bi.TextLineField("host")
        port_f = bi.IntegerField("port")
        nick_f = bi.TextLineField("nick")
        password_f = bi.TextLineField("password")
        success = bi.get_form_input([None, host_f, port_f, nick_f, password_f],
                                    "Configure Revsync")
        if not success:
            binaryninja.interaction.show_message_box(
                title="Revsync error", text="Failed to configure revsync")
            raise

        write_config(host_f.result, port_f.result, nick_f.result,
                     password_f.result)
        import config
    import binja_frontend
    #import binja_coverage
    good = True
except ImportError:
    pass

try:
 def _display_menu(self, items, title):
     form_menu = get_form_input(items, title)
     return form_menu