Forked from psifertex/1_Snippet_Instructions.txt
Last active
September 28, 2022 18:17
-
-
Save galenbwill/553626eb0db8e45d1b5b55edd03a2dd7 to your computer and use it in GitHub Desktop.
Revisions
-
galenbwill revised this gist
Sep 28, 2022 . 1 changed file with 111 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,111 @@ import time # 1. IL dests def find_calls_by_mlil(): start = time.time() calls = {} for f in bv.functions: for c in f.call_sites: call_mlil = c.mlil if call_mlil is None: print(f'DBG: No MLIL @ {hex(c.address)}') continue try: call_dest_addr = call_mlil.dest.value.value except: print(f'Exception @ {hex(c.address)} : {c.mlil}') continue if call_dest_addr is None: #print(f'DBG: No IL value @ {hex(c.address)} : {c.mlil}') continue funcs = bv.get_function_at(call_dest_addr) if not funcs: #print(f'DBG: No funcs @ dest {hex(call_dest_addr)}: {hex(c.address)} : {c.mlil}') continue call_dest = funcs[0] calls[c.address] = (f, call_dest) duration = time.time() - start print(f'[*] 1. MLIL dest: Found {len(calls)} in {duration:.02f} seconds') return calls def find_calls_by_llil(): start = time.time() calls = {} for f in bv.functions: for c in f.call_sites: call_llil = c.llil if call_llil is None: #print(f'DBG: No llil @ {hex(c.address)}') continue try: call_dest_addr = call_llil.dest.value.value except: #print(f'Exception @ {hex(c.address)} : {c.llil}') continue if call_dest_addr is None: #print(f'DBG: No IL value @ {hex(c.address)} : {c.mlil}') continue funcs = bv.get_function_at(call_dest_addr) if not funcs: #print(f'DBG: No funcs @ dest {hex(call_dest_addr)}: {hex(c.address)} : {c.mlil}') continue call_dest = funcs[0] calls[c.address] = (f, call_dest) duration = time.time() - start print(f'[*] 1.5. LLIL dest: Found {len(calls)} in {duration:.02f} seconds') return calls # 2. code refs def find_calls_by_xref(): start = time.time() calls = {} for f in bv.functions: for c in f.call_sites: xrefs = bv.get_code_refs_from(c.address) if not xrefs: #print(f'DBG: No xrefs @ {hex(c.address)} : {c.mlil}') continue call_dest_addr = xrefs[0] funcs = bv.get_function_at(call_dest_addr) if not funcs: #print(f'DBG: No funcs @ dest {hex(call_dest_addr)}: {hex(c.address)} : {c.mlil}') continue call_dest = funcs[0] calls[c.address] = (f, call_dest) duration = time.time() - start print(f'[*] 2. code refs: Found {len(calls)} in {duration:.02f} seconds') return calls # 3. Intersection of call_sites and caller_sites def find_calls_by_caller_sites(): start = time.time() calls = {} for f in bv.functions: call_destinations = {} for callee in f.callees: calls_to_callee = {c.address: callee for c in callee.caller_sites if c.function == f} call_destinations.update(calls_to_callee) for c in f.call_sites: call_dest = call_destinations.get(c.address) if not call_dest: #print(f'DBG: {hex(c.address)} not in caller_sites') continue calls[c.address] = (f, call_dest) duration = time.time() - start print(f'[*] 3. Intersection: Found {len(calls)} in {duration:.02f} seconds') return calls mlil_calls = find_calls_by_mlil() llil_calls = find_calls_by_llil() xref_calls = find_calls_by_xref() caller_calls = find_calls_by_caller_sites() for k, v in caller_calls.items(): if k not in llil_calls: print(f'{hex(k)} -> {v} not in llil_calls') for k, v in llil_calls.items(): if k not in xref_calls: print(f'{hex(k)} -> {v} not in xref_calls') -
galenbwill revised this gist
Sep 22, 2022 . No changes.There are no files selected for viewing
-
galenbwill revised this gist
Sep 22, 2022 . 1 changed file with 67 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,67 @@ # dump IL # # Dump the current function's IL in a verbose and structured text representation. Kinda what I want repr to do for # HLIL AST's, but also works on other ILs. Also supports SSA forms. Edit the last couple lines to control which ILs # get dumped. Needs some improvement. def dump_hlil(hlil, indent=0, op_num=None, name=None, kind='hlil', ssa=False, offset=0): if kind.endswith('_ssa'): ssa = True kind = kind[:-4] llil = hlil if hasattr(llil, 'mlil'): llil = llil.mlil if hasattr(llil, 'llil'): llil = llil.llil if hasattr(llil, 'address'): offset = llil.address def _print(msg): idx = f'[{op_num}] ' if op_num is not None else '' n = f'{name}: ' if name is not None else '' _ = print(f'{kind}:0x{offset:08x}:{" "*indent}{idx}{n}{msg}') if type(hlil) in [list, HighLevelILFunction, LowLevelILFunction, MediumLevelILFunction]: if hasattr(hlil, 'instructions'): if ssa: hlil = hlil.ssa_form hlil = hlil.instructions for i, h in enumerate(hlil): dump_hlil(h, indent, op_num=i, kind=kind, ssa=ssa, offset=offset) return if hasattr(hlil, kind): dump_hlil(getattr(hlil, kind), indent=indent, kind=kind, ssa=ssa, offset=offset) return if hasattr(hlil, 'operation'): try: rendered = str(hlil) if hlil.operation.name.endswith('_PTR'): value = hlil.constant symbols = bv.get_symbols(value) if symbols: rendered = f'{symbols[0].name} @ 0x{value:08x}' _ = _print(f'<{type(hlil).__name__.split(".")[-1]}:{hlil.operation.name}> {rendered!r}') except Exception as e: _ = _print(e) else: _ = _print(f'<{type(hlil).__name__.split(".")[-1]}> {hlil}') if hasattr(hlil, 'operands'): if hasattr(hlil, 'operation'): instruction_type = { 'hlil': HighLevelILInstruction, 'mlil': MediumLevelILInstruction, 'llil': LowLevelILInstruction, }[kind] op_names = instruction_type.ILOperations[hlil.operation] else: op_names = [] for i, op in enumerate(hlil.operands): if True or op is not None: n = None if len(op_names) > i: n = op_names[i][0] dump_hlil(op, indent+4, i, n, kind, ssa=ssa, offset=offset) #dump_hlil(current_function, kind='llil') print(' ') dump_hlil(current_function, kind='mlil_ssa') print(' ') dump_hlil(current_function, kind='hlil_ssa') -
galenbwill revised this gist
Sep 22, 2022 . 1 changed file with 158 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,158 @@ # # Paste this def into the console, then run it, and then paste the output into the_types down below: # def dump_types(clip=True, void=True, verbose=False): def make_call_type(name, type): return f'{type.return_value} {name}({",".join(map(str,type.parameters))})' _print = print if not verbose: _print = lambda *a, **kw: None fun_dump = [] for f in bv.functions: adjustments = [] # for ref in f.caller_sites: for ref in sorted(f.call_sites,key=lambda ref:ref.address): # _print(f'{f = } {ref = }') adjustment = ref.function.get_call_type_adjustment(ref.address) if adjustment is not None: #adjustments.append((str(ref.hlil.dest), ref.function.name, str(adjustment))) dest = str(ref.hlil.dest) adjustments.append((dest, ref.function.name, make_call_type(dest, adjustment))) # _print(f'{adjustments = !r}') tag = f'{bv.arch.name}:{f.start:08X}' fun_dump.append(f'{tag!r}:(0x{f.start:08X},{bv.arch.name!r},"fun",({bv.get_sections_at(f.start)[0].name!r},{f.name!r},{str(f)!r},{str(f.clobbered_regs.regs)},{str(f.return_regs.regs)},{adjustments})),') _ = _print(fun_dump[-1]) _ = _print() for v in bv.data_vars: f = bv.get_data_var_at(v) if f.type.type_class == TypeClass.FunctionTypeClass: sections = bv.get_sections_at(f.address) if not sections: sec_name = '' else: sec_name = sections[0].name #t = f'{f.type.return_value} {f.name}({",".join(map(str,f.type.parameters))})' t = make_call_type(f.name, f.type) tag = f'{bv.arch.name}:{f.address:08X}' fun_dump.append(f'{tag!r}:(0x{f.address:08X},{bv.arch.name!r},"var",({sec_name!r},{f.name!r},{t!r})),') _ = _print(fun_dump[-1]) _ = _print() if clip: clipboard.text = '\n\t' + '\n\t'.join(fun_dump) if not void: return fun_dump the_types = { } bv.begin_undo_actions() for item in the_types.items(): tag, (address, arch_name, fun_var, rest) = item print(f'0x{address:08x}:{item[1]}') if arch_name != bv.arch.name: continue sec_name, name, type_str = rest[:3] the_type = bv.parse_type_string(type_str) if not the_type: log_warn(f'failed to parse function type for {name} found 0x{address:08x}: {type_str!r}') continue is_fun = fun_var == "fun" if not is_fun: v = None v = bv.get_data_var_at(address) if v and sec_name: s = bv.get_sections_at(v.address) if s and s[0].name != sec_name: v = None if not v: for symbol in bv.get_symbols_by_name(name): s = bv.get_sections_at(symbol.address) log_warn(f'0x{symbol.address:08x} {symbol.name} {symbol.type.name} {s}') if s and s[0].name != sec_name: continue if symbol.type in [SymbolType.FunctionSymbol, SymbolType.ExternalSymbol, SymbolType.ImportedFunctionSymbol, SymbolType.DataSymbol]: v = bv.get_data_var_at(symbol.address) if v: log_warn(f'0x{v.address:08X}:({bv.arch.name!r},"var",{v.name!r},{str(v.type)!r},[],[]),') break if v is not None: print(f'0x{v.address:08X}:({bv.arch.name!r},"var",{v.name!r},{str(v.type)!r},[],[]),') v.name = name v.type = the_type[0] v = bv.get_data_var_at(v.address) print(f'0x{v.address:08X}:({bv.arch.name!r},"var",{v.name!r},{str(v.type)!r},[],[]),') else: log_warn(f'no appropriate var {name} found at 0x{address:08x} or in section {sec_name}') continue clobbered_regs, return_regs, adjustments = rest[3:] f = bv.get_function_at(address) if not f or f.name != name: fs = bv.get_functions_by_name(name) if fs: f = fs[0] if not f: log_warn(f'no function {name} found at 0x{address:08x}') continue if the_type: f.set_user_type(the_type[0]) else: log_warn(f'failed to parse function type for {name} found 0x{address:08x}: {type_str!r}') continue if clobbered_regs: f.clobbered_regs = RegisterSet(clobbered_regs, 255) if return_regs: f.return_regs = RegisterSet(return_regs, 255) if f.name != name: f.name = name bv.update_analysis_and_wait() if adjustments: call_sites = sorted(f.call_sites,key=lambda ref:ref.address) for target, source, adjustment in adjustments: while call_sites: call_site = call_sites.pop(0) hlil = call_site.hlil if hlil.operation != HighLevelILOperation.HLIL_CALL: log_warn(f'0x{call_site.address:08x}: call site {hlil} is not HLIL_CALL') for op in hlil.operands: if hasattr(op, 'operation') and op.operation == HighLevelILOperation.HLIL_CALL: hlil = op break else: log_warn(f'0x{call_site.address:08x}: operand {op} is not HLIL_CALL') if hlil.operation != HighLevelILOperation.HLIL_CALL: log_warn(f'0x{call_site.address:08x}: call {hlil} is not a call') dest = str(hlil.dest) print(f'0x{call_site.address:08x}: call {dest!r} init: {(target,source,adjustment)}') if dest == target: f.set_call_type_adjustment(call_site.address, adjustment) #adjustment_type = bv.parse_type_string(adjustment) #if adjustment_type: # f.set_call_type_adjustment(call_site.address, adjustment) adjustment = f.get_call_type_adjustment(call_site.address) print(f'0x{call_site.address:08x}: call {str(call_site.hlil.dest)!r} set: {adjustment}') break for call_site in sorted(f.call_sites,key=lambda ref:ref.address): adjustment = f.get_call_type_adjustment(call_site.address) print(f'0x{call_site.address:08x}: call {str(call_site.hlil.dest)!r} final: {adjustment}') f = bv.get_function_at(f.start) print(f'0x{f.start:08X}:({f.name!r},{str(f)!r},{str(f.clobbered_regs.regs)},{str(f.return_regs.regs)}),') bv.commit_undo_actions() -
psifertex revised this gist
Sep 20, 2022 . 1 changed file with 18 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,18 @@ # highlight dangerous calls # # Highlight with theme-aware colors any "dangerous" functions: # Note that prefixed versions like "_system" will not be highlighted using this sample code. dangerous = ["strcpy", "gets"] sus = ["printf", "system", "exec"] for fnname in dangerous + sus: if fnname in dangerous: color = HighlightStandardColor.RedHighlightColor if fname in sus: color = HighlightStandardColor.OrangeHighlightColor for sym in bv.get_symbols_by_name(fnname): for ref in bv.get_code_refs(sym.address): ref.function.set_user_instr_highlight(ref.address, color) -
psifertex revised this gist
Jul 20, 2022 . 1 changed file with 0 additions and 32 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,32 +0,0 @@ -
psifertex revised this gist
Jul 20, 2022 . 1 changed file with 20 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,20 @@ # unimplemented instructions # # Create a report showing unimplemented instructions from collections import defaultdict insts = defaultdict(lambda:0) addrs = {} for ins in bv.llil_instructions: if ins.operation == LowLevelILOperation.LLIL_UNIMPL: mnem = bv.get_disassembly(ins.address, ins.il_basic_block.arch).split()[0] insts[mnem + '-' + ins.il_basic_block.arch.name] = insts[mnem + '-' + ins.il_basic_block.arch.name] + 1 addrs[mnem + '-' + ins.il_basic_block.arch.name] = ins.address lines = list(insts.items()) lines = sorted(lines, key=lambda x: x[1], reverse=True) contents = "| Memonic-Arch | Count | Example Address |\n|---|---|---|\n" for mnem, count in lines: contents += f"|{mnem}|{count}|[{hex(addrs[mnem])}](binaryninja://?expr={hex(addrs[mnem])})|\n" bv.show_markdown_report("Unimplemented counts", contents, contents) -
psifertex revised this gist
Jul 2, 2022 . 1 changed file with 12 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,12 @@ # show file modifications # # Use the get_modification API to show all places where bytes were modified in the file for offset in range(bv.start, len(bv) + bv.start): mod = bv.get_modification(offset,1)[0] if mod != ModificationStatus.Original: b = "0x" + bv.read(offset, 1).hex() if mod == ModificationStatus.Inserted: print(f"Looks like {b} was inserted at {hex(offset)}") else: print(f"Looks like {b} was written at {hex(offset)}") -
psifertex revised this gist
May 28, 2022 . 1 changed file with 16 additions and 10 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,15 +2,21 @@ # # Save search results to a specified file targets = [FunctionGraphType.NormalFunctionGraph, FunctionGraphType.LowLevelILFunctionGraph, FunctionGraphType.MediumLevelILFunctionGraph, FunctionGraphType.HighLevelILFunctionGraph, FunctionGraphType.HighLevelLanguageRepresentationFunctionGraph] search_text = TextLineField("Search text") search_target = ChoiceField("Search target?", ["Assembly", "LLIL", "MLIL", "HLIL", "Pseudo C"]) search_addresses = ChoiceField("Include addresses in output?", ["No", "Yes"]) output_file = SaveFileNameField("Output filename: ", default_name=bv.file.filename + ".txt") choices = get_form_input(["Saved Search Plugin", search_text, search_target, output_file, search_addresses], "Saved Search") if choices and search_text.result and search_target.result and output_file.result: with open(output_file.result, 'wb') as f: target = targets[search_target.result] for result in bv.find_all_text(bv.start, bv.end, search_text.result, graph_type=target): if search_addresses.result and search_addresses.result == 1: addr = bytes(hex(result[0]) + "\t", 'utf8') else: addr = b"" f.write(addr + bytes(str(result[2]), 'utf8') + b"\n") log_info(f"Search results saved to {output_file.result}") else: log_warn("Search not saved, dialog cancelled or missing selection.") -
psifertex revised this gist
May 27, 2022 . 1 changed file with 16 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,16 @@ # save search # # Save search results to a specified file # Currently hard-coded to HLIL, TODO: use an interaction API to let the user select from a drop-down. # Can just copy from export_to_text snippet search = interaction.get_text_line_input('Search test', 'Search text') output = interaction.get_save_filename_input("Output filename: ", "txt", "results.txt") if search and output: with open(output, 'wb') as f: for result in bv.find_all_text(bv.start, bv.end, search.decode('utf8'), graph_type=FunctionGraphType.HighLevelILFunctionGraph): addr = bytes(hex(result[0]) + "\t", 'utf8') f.write(addr + bytes(str(result[2]), 'utf8') + b"\n") else: log_warn("Either search or filename not given.") -
psifertex revised this gist
Apr 8, 2022 . 1 changed file with 2 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,5 +3,6 @@ # Log interesting components like the function and basic blocks with most incoming or outgoing edges log_info("Most connected function: " + repr(max(bv.functions, key=lambda x: len(x.callees) + len(x.callers)))) log_info("Most incoming callers: " + repr(max(bv.functions, key=lambda x: len(x.callers)))) log_info("Most connected bblock: " + repr(max(bv.basic_blocks, key=lambda x: len(x.incoming_edges) + len(x.outgoing_edges)))) log_info("Highest xrefs: " + repr(max(bv.functions, key=lambda x: len(x.callers)))) -
psifertex revised this gist
Mar 17, 2022 . 1 changed file with 0 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,8 +2,6 @@ # # Will append a file's raw contents to the existing view (useful for working with firmware or memory dumps). Thanks to @mariomain for the snippet. def load_file(infilename): f = open(infilename, "rb") g = f.read() -
psifertex revised this gist
Mar 17, 2022 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,6 @@ # append file contents to view # # Will append a file's raw contents to the existing view (useful for working with firmware or memory dumps). Thanks to @mariomain for the snippet. # by default the convention is that files are named with their respctive address. -
psifertex revised this gist
Mar 17, 2022 . 1 changed file with 68 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,68 @@ # append file contents to view # # Will append a file's raw contents to the existing view (useful for working with firmware or memory dumps) # by default the convention is that files are named with their respctive address. def load_file(infilename): f = open(infilename, "rb") g = f.read() f.close() faddr = None while (faddr is not None): faddr = interaction.get_int_input("Load address", "Load address") fsize = len(g) return g, faddr, fsize def overlap(reg1, reg1sz, reg2, reg2sz): if ((reg1 >= reg2) and (reg1 < (reg2 + reg2sz))): return True if (((reg1 + reg1sz) > reg2) and ((reg1 + reg1sz) < (reg2 + reg2sz))): return True if ((reg1 < reg2) and ((reg1 + reg1sz) >= (reg2 + reg2sz))): return True return False def add_some_file_sec(file_name): rv = bv.get_view_of_type("Raw") fblob, faddr, fsize = load_file(file_name) prev_sec = bv.get_segment_at(bv.start) succ_sec = None new_succ_blob = None new_succ_blob_addr = 0 if (overlap(faddr, fsize, prev_sec.start, len(prev_sec)) == False) and (faddr < prev_sec.start): succ_sec = prev_sec else: for i in bv.sections: i = bv.get_section_by_name(i) if overlap(faddr, fsize, i.start, len(i)) == True: log_info("overlapping with region {}".format(hex(i.start))) return False if prev_sec.start != i.start: if (faddr >= (prev_sec.start + len(prev_sec))) and (faddr < i.start): succ_sec = i break prev_sec = i if succ_sec != None: follow_seg = bv.get_segment_at(succ_sec.start) the_rest = rv.read(follow_seg.data_offset, rv.length - follow_seg.data_offset) new_succ_blob = fblob + the_rest new_succ_blob_addr = follow_seg.data_offset else: new_succ_blob = fblob new_succ_blob_addr = rv.length rv.write(new_succ_blob_addr, new_succ_blob) if succ_sec != None: for i in bv.segments: if i.start > faddr: temp_start = i.start temp_off = i.data_offset temp_len = i.data_length bv.remove_auto_segment(i.start, len(i)) temp_off += fsize bv.add_auto_segment(start=temp_start, length=temp_len, data_offset=temp_off, data_length=temp_len, flags=(SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)) bv.add_auto_section(os.path.basename(file_name), start=faddr, length=fsize, semantics=SectionSemantics.ReadOnlyCodeSectionSemantics) bv.add_auto_segment(start=faddr, length=fsize, data_offset=new_succ_blob_addr, data_length=fsize, flags=(SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)) -
psifertex revised this gist
Mar 16, 2022 . 1 changed file with 0 additions and 59 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,59 +0,0 @@ -
psifertex revised this gist
Mar 16, 2022 . 1 changed file with 59 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,59 @@ # make code from raw bytes # # Only a snippeettt for now due to some inconsistencies around removing the symbol versus the renderer and some performance reasons from binaryninja import * from PySide6.QtGui import QKeySequence from binaryninjaui import UIActionHandler, UIAction, UIActionContext class CodeDataRenderer(DataRenderer): def __init__(self): DataRenderer.__init__(self) def perform_is_valid_for_data(self, _, bv: BinaryView, addr: int, type: Type, context: List[str]) -> bool: sym = bv.get_symbol_at(addr) return sym is not None and sym.name.startswith("CODE_") and type.type_class == TypeClass.ArrayTypeClass def perform_get_lines_for_data(self, _, bv: BinaryView, addr: int, type: Type, prefix: List[InstructionTextToken], width: int, context: List[str]) -> List[DisassemblyTextLine]: end = addr + len(type) result: List[DisassemblyTextLine] = [] for tokens, size in bv.disassembly_tokens(addr, bv.arch): if addr + size > end: break result.append(DisassemblyTextLine([*tokens], addr, color=HighlightStandardColor.RedHighlightColor)) addr += size return result def __del__(self): pass def make_code(bv: BinaryView, start: int, end: int) -> None: bv.begin_undo_actions() if bv.get_basic_blocks_at(start): return if end - start <= 1: # find the next basic block, data variable, or segment/section end data_var = bv.get_next_data_var_after(start) if data_var is not None: end = data_var.address else: end = bv.end end = min(bv.get_next_basic_block_start_after(start), end) seg = bv.get_segment_at(start) if seg is not None: end = min(seg.end, end) section_ends = [s.end for s in bv.get_sections_at(start)] end = min(*section_ends, end) bv.define_data_var(start, Type.array(Type.int(1, False), end-start), f"CODE_{start:08x}") bv.commit_undo_actions() def make_code_helper(ctx: UIActionContext): log_info(f"Making code region {ctx.address:08x}, {ctx.address + ctx.length:08x}") make_code(ctx.binaryView, ctx.address, ctx.address + ctx.length) def register(): CodeDataRenderer().register_type_specific() UIAction.registerAction("Make Code", QKeySequence("C")) UIActionHandler.globalActions().bindAction("Make Code", UIAction(make_code_helper)) register() -
psifertex revised this gist
Mar 16, 2022 . 1 changed file with 2 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -5,6 +5,7 @@ import os USER="myusername" PASS="mypassword" #change to an interactive popup for more security but be aware os.system may leave history DOMAIN="mydomain" globalArea=uicontext.context.globalArea() @@ -20,7 +21,7 @@ unc = lineSplit[0] pdbPath = lineSplit[1] unc = unc.replace("\\","\/") os.system(f"smbget -U {USER}%{PASS} -w {DOMAIN} -o {pdbPath} {unc}") else: log_warn("Invalid PTR log message.") else: -
psifertex revised this gist
Mar 16, 2022 . 1 changed file with 29 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,29 @@ # PDB PTR Downloader # # Can be adapted to work together with the built in PDB support to fetch UNC paths from debug server file.ptr files. Also a good example of how to access GlobalArea widgets. import binaryninjaui import os USER="myusername" DOMAIN="mydomain" globalArea=uicontext.context.globalArea() logWidget=globalArea.widget("Log") for child in logWidget.children(): if isinstance(child, binaryninjaui.LogListModel): if child.hasSelectedItems(): items = child.getSelectedItems() if items: lastLine = items[0].text lineSplit = lastLine.split(" -> ") if len(lineSplit) == 2: unc = lineSplit[0] pdbPath = lineSplit[1] unc = unc.replace("\\","\/") os.system(f"smbget -U {USER} -w {DOMAIN} -o {pdbPath} {unc}") else: log_warn("Invalid PTR log message.") else: log_info("No selected PTR log message.") else: log_info("No selected PTR log message.") -
psifertex revised this gist
Mar 14, 2022 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -9,8 +9,8 @@ #TODO: Merge remote with local description or hotkey changes (AKA: if filename matches, skip the first two lines, truncate, re-write the rest) domain = b'https://gist.github.com' path = b'/psifertex/6fbc7532f536775194edd26290892ef7' # Feel free to adapt to your own setup subfolder = 'default' # Change to save the snippets to a different sub-folder tab2space = False width = 4 -
psifertex revised this gist
Mar 14, 2022 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -15,6 +15,7 @@ width = 4 def download(url): # Can also use 'CoreDownloadProvider' or 'PythonDownloadProvider' as keys here provider = DownloadProvider[Settings().get_string('network.downloadProviderName')].create_instance() code, data = provider.get_response(url) if code == 0: -
psifertex revised this gist
Mar 14, 2022 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -15,7 +15,7 @@ width = 4 def download(url): provider = DownloadProvider[Settings().get_string('network.downloadProviderName')].create_instance() code, data = provider.get_response(url) if code == 0: return data -
psifertex revised this gist
Mar 8, 2022 . 1 changed file with 4 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,7 @@ # print current function to pseudo c # # Adapt as necessary to save to file for example, though File / Export will also work def c_source(bv, func): lines = '' settings = DisassemblySettings() -
psifertex revised this gist
Mar 8, 2022 . 2 changed files with 54 additions and 54 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,31 +2,31 @@ # # Especially useful when building a new architecture and wanting to see what disassembly you're running into with real binaries to prioritize from binaryninja.lowlevelil import LowLevelILInstruction def visit(unimp, expr): for field in LowLevelILInstruction.ILOperations[expr.operation]: if field[1] == "expr": visit(unimp, getattr(expr, field[0])) if expr.operation in [LowLevelILOperation.LLIL_UNIMPL, LowLevelILOperation.LLIL_UNIMPL_MEM]: if hasattr(expr, "expr_index"): index = expr.expr_index else: index = 0 dis = bv.get_disassembly(expr.address) mnemonic = dis.split(" ")[0] if mnemonic in unimp.keys(): unimp[mnemonic].append([expr.address, index]) else: unimp[mnemonic] = [[expr.address, index]] unimp = {} for llili in bv.llil_instructions: visit(unimp, llili) log_info(f"Found {len(unimp)} total unimplemented mnemonics") for k, v in sorted(unimp.items(), key=len): log_info(f"Unimplemented mnemonic: {k}:") for x in v: log_info(f" {hex(x[0])} / {x[1]}") This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -8,49 +8,49 @@ #TODO: Merge remote with local description or hotkey changes (AKA: if filename matches, skip the first two lines, truncate, re-write the rest) domain = b'https://gist.github.com' path = b'/psifertex/6fbc7532f536775194edd26290892ef7' # Feel free to adapt to your own setup subfolder = 'default' # Change to save the snippets to a different sub-folder tab2space = False width = 4 def download(url): provider = next(iter(DownloadProvider)).create_instance() code, data = provider.get_response(url) if code == 0: return data else: raise ConnectionError("Unsuccessful download of %s" % url) def update_snippets(): if not interaction.show_message_box('Warning', "Use at your own risk. Do you want to automatically overwrite local snippets from gist?", buttons=MessageBoxButtonSet.YesNoButtonSet): return snippetPath = os.path.realpath(os.path.join(user_plugin_path(), '..', 'snippets', subfolder)) if not os.path.isdir(snippetPath): os.makedirs(snippetPath) url = domain + path log_info("Downloading from: %s" % url) source = download(url) zipPath = [s for s in source.split(b'\"') if s.endswith(b'.zip')] if len(zipPath) != 1: log_error("Update failed.") return url = domain + zipPath[0] log_info("Downloading from: %s" % url) zip = download(url) with TemporaryFile() as f: f.write(zip) with ZipFile(f, 'r') as zip: for item in zip.infolist(): if item.filename[-1] == '/': continue basename = os.path.basename(item.filename) with open(os.path.join(snippetPath, basename), 'wb') as f: if tab2space: f.write(zip.read(item).replace(b'\t', b' ' * width)) else: f.write(zip.read(item)) log_info("Extracting %s" % item.filename) update_snippets() -
psifertex revised this gist
Mar 8, 2022 . 20 changed files with 328 additions and 309 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,43 +1,44 @@ # create common tags for function attributes like leaf, loop, stub, etc # # Snippet replaced with a plugin, will be removed in the future: https://github.com/psifertex/tagteam large = 40 complex = 40 def init_tags(): for tagType in tags: if tagType['name'] not in bv.tag_types.keys(): bv.create_tag_type(tagType['name'], tagType['emoji']) def cc(fn): nodes = len(fn.basic_blocks) edges = sum(len(x.outgoing_edges) for x in fn.basic_blocks) connected = 1 #always 1 for binary control flow graphs, kinda the whole point return edges - nodes + 2 * connected def iscomplex(fn): return cc(fn) > complex def isleaf(fn): return len(fn.callees) == 0 def islarge(fn): return len(fn.basic_blocks) >= large def isstub(fn): """Returns true if a function is likely only a stub""" if len(fn.basic_blocks) > 1 or len(fn.llil.basic_blocks) > 1: return False if fn.llil.basic_blocks[0].has_undetermined_outgoing_edges or len(fn.callees) == 1: return True return False def hasloop(fn): """Returns true if a function has a 'strange loop' (ignore this, inside joke)""" for bb in fn.basic_blocks: if bb in bb.dominance_frontier: return True return False tags = [ \ {'emoji': '🍃', 'name': 'Leaf Function', 'description': 'Leaf function (does not call anything else)', 'fn': isleaf}, @@ -51,6 +52,6 @@ def hasloop(fn): init_tags() for fn in bv.functions: for tagType in tags: if tagType['fn'](fn): fn.create_user_function_tag(bv.tag_types[tagType['name']], '', unique=True) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,14 +4,14 @@ count = 0 for s in bv.strings: bv.define_user_data_var(s.start, Type.array(Type.char(), s.length)) if bv.get_symbol_at(s.start) is None: sym = Symbol(types.SymbolType.DataSymbol, s.start, "str_{}".format(s.value)) bv.define_user_symbol(sym) count += 1 interaction.show_message_box( "Auto-Rename strings", f"Completed renaming variables based {count} strings!" ) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,27 +7,27 @@ from binaryninja.highlevelil import HighLevelILInstruction def visit(illest, expr, operations): for field in operations[expr.operation]: if field[1] == "expr": visit(illest, getattr(expr, field[0]), operations) illest.add(expr.operation) llillest = set(()) mlillest = set(()) hlillest = set(()) if current_llil: fnname = current_function.name for ins in current_llil.instructions: visit(llillest, ins, LowLevelILInstruction.ILOperations) if current_mlil: for ins in current_mlil.instructions: visit(mlillest, ins, MediumLevelILInstruction.ILOperations) if current_hlil: for ins in current_hlil.instructions: visit(hlillest, ins, HighLevelILInstruction.ILOperations) log_info("%s LLIL (%d): " % (fnname, len(llillest))) log_info(str(llillest)) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,4 +4,4 @@ sym_name = get_text_line_input("Symbol name:", "Symbol Name") if sym_name not in [None, b'']: bv.define_user_symbol(Symbol(SymbolType.DataSymbol, here, sym_name)) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,13 +3,13 @@ # Will attempt to demangle GNU mangled C++ names in a PE file since that is not automatically done for func_sym in bv.get_symbols_of_type(SymbolType.FunctionSymbol): log_debug(f"Attempting to demangle {func_sym}") symtype, symname = demangle_gnu3(Architecture['x86'], func_sym.name) if symname != func_sym.name: log_info(f"Successfully demangled {func_sym.name}") if type(symname) == str: full_name = symname else: full_name = '::'.join(map(str, symname)) new_sym = binaryninja.types.Symbol(SymbolType.FunctionSymbol, func_sym.address, short_name=symname[-1], full_name=full_name, raw_name=func_sym.name) bv.define_user_symbol(new_sym) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -13,32 +13,32 @@ allscope = set(["SettingsProjectScope", "SettingsUserScope", "SettingsResourceScope"]) for category in settings: for setting in settings[category]['settings']: title = settings[category]['settings'][setting]['title'] description = settings[category]['settings'][setting]['description'] typ = settings[category]['settings'][setting]['type'] key = settings[category]['settings'][setting]['key'] default = settings[category]['settings'][setting]['default'] if isinstance(default, list): default = "[" + ', '.join(["`%s`" % x for x in default]) + "]" else: default = f"`{str(default)}`" if default == "``": default = " "; print(settings[category]['settings'][setting]) if 'ignore' in settings[category]['settings'][setting].keys(): scope = allscope - set(settings[category]['settings'][setting]['ignore']) else: scope = allscope scope = "[" + ', '.join(["`%s`" % x for x in scope]) + "]" table += f"|{category}|{title}|{description}|`{typ}`|{default}|{scope}|<a id='{key}'>{key}</a>|\n" if settings[category]['settings'][setting].get("enum") and key not in excludeEnum: for idx, enum in enumerate(settings[category]['settings'][setting]["enum"]): if settings[category]['settings'][setting].get("enumDescriptions"): description = " enum: " + settings[category]['settings'][setting]["enumDescriptions"][idx] else: description = " " table += f"| | |{description}|`enum`|`{enum}`| | |\n" show_markdown_report("Settings Documentation", "Below table added to the clipboard:\n\n"+table) log_info("Saving result to the clipboard.") This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -6,64 +6,64 @@ import io def valid_filename(s): s = s.strip().replace(' ', '_') return re.sub(r'(?u)[^-\w.]', '', s) def filtername(name): return "".join(x for x in name if x.isalnum() or x in ["_", "-"]) def fnsource(fn, form): if form == "HLIL": return ''.join(["\t" + x + "\n" for x in map(str, fn.hlil.root.lines)]) if form == "MLIL": return ''.join(["\t" + x + "\n" for x in map(str, fn.mlil.instructions)]) if form == "LLIL": return ''.join(["\t" + x + "\n" for x in map(str, fn.llil.instructions)]) if form == "Assembly": return ''.join(["\t" + "".join(map(str, x[0])) + "\n" for x in fn.instructions]) if form == "Assembly with offset": return ''.join([f'\t{x[1]:#04x}: {"".join(map(str, x[0]))}\n' for x in fn.instructions]) def overwrite(fname): if show_message_box("File exists", "File exists, delete and overwrite?", buttons=MessageBoxButtonSet.YesNoButtonSet) == MessageBoxButtonResult.YesButton: os.unlink(fname) return True else: return False def main(): #Maybe eventually add "Whole Binary" to include data from linear view all_or_func = ChoiceField("Scope?", ["All functions", "Current function"]) asm_or_il = ChoiceField("Which form?", ["Assembly with offset", "Assembly", "LLIL", "MLIL", "HLIL"]) folder = DirectoryNameField("Folder to save result", default_name=os.path.dirname(bv.file.filename)) choices = get_form_input(["Which would you like to export?\n\nNote that \"whole binary\" will only dump IL contained in functions when IL is selected", all_or_func, asm_or_il, folder], "Export to text") if choices: current_only = all_or_func.result == 1 form = asm_or_il.choices[asm_or_il.result] fname = os.path.splitext(os.path.basename(bv.file.filename))[0] if folder.result: if current_only: outputname = f"{os.path.join(folder.result, fname)}.{valid_filename(current_function.name)}.txt" if os.path.isfile(outputname): if not overwrite(outputname): log_warn("Stopping export to text due to existing file.") return log_info(f"Dumping {current_function.name} to {outputname}") with io.open(outputname, mode='w', encoding="utf-8") as f: f.write(fnsource(current_function, form)) else: outputname = f"{os.path.join(folder.result, fname)}.txt" if os.path.isfile(outputname): if not overwrite(outputname): log_warn("Stopping export to text due to existing file.") return with io.open(outputname, mode='w', encoding="utf-8") as f: for fn in bv.functions: log_info(f"Writing {fn.name}") f.write(f"\n{fn.name}: \n") f.write(fnsource(fn, form)) log_info(f"Done dumping whole binary to {outputname}") main() This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,10 +2,10 @@ # if uicontext.token.localVarValid: log_info("Found a localvar") varname = uicontext.token.token.text log_info(str(dir(uicontext))) log_info("-----\n") instrIndex = 0 else: log_warn("No variable selected") This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,4 +4,4 @@ newcomment = get_text_line_input("Current value: " + current_function.comment, "Function plate comment") if (newcomment): current_function.comment = newcomment This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,7 +3,7 @@ # Produce an HTML report showing how to use a sortable HTML table to make a slightly more useful UI. Appologies for the awful intermixing of code and HTMl, think it's actually more readable this way. from binaryninjaui import getThemeColor, ThemeColor r = RepositoryManager() repos = ["community", "official"] html = '''<html> @@ -14,7 +14,7 @@ <script>''' for repo in repos: html += f'''$(document).ready( function () {{ $('#{repo}').DataTable({{ "paging": false, "info": false, @@ -43,7 +43,7 @@ ''' for repo in ["community", "official"]: html += f'''<h3>{repo.capitalize()} Plugins</h3> <table id="{repo}" class="sortable" cellspacing="0" width="100%"> <thead> <tr> @@ -55,17 +55,17 @@ </thead> <tbody> ''' for plugin in r.plugins[repo]: if plugin.update_available: status = "Update Available" elif plugin.installed and not plugin.enabled: status = "Disabled" elif plugin.installed: status = "Enabled" else: continue html += f'<tr data-state="{status}"><td>{plugin.name}</td><td>{plugin.version}</td><td>{status}</td><td>{plugin.description}</td></tr>' html += f'''</tbody> </table> <hr /> ''' This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -8,11 +8,11 @@ #Load symbols from a MAP file mapfile = get_open_filename_input("filename:", "All Files (*)") if mapfile is not None and os.access(mapfile, os.R_OK): with open(mapfile, "r+", encoding="utf-8") as f: data = f.readlines() else: log_error("Unable to parse specified map file.") data = [] mylog = log_debug #uncomment to enable debugging even if BN debugging is off @@ -21,66 +21,66 @@ segments = {} symcount = 0 for line in data: line = line.strip() if line.startswith("0"): index = line.split(":")[0] if index in segments.keys(): #this is a record for a segment we know about offset = int(line.split(" ")[0].split(":")[1], 16) addr = offset + segments[index][0] symbol = line.split(" ")[-1] symtype=SymbolType.DataSymbol if symbol.endswith("()"): symbol = symbol[0:-2] if symbol.startswith("<-"): symbol = symbol[2:] symtype=SymbolType.FunctionSymbol contain = bv.get_functions_containing(addr) makenew = True for fn in contain: if fn.start == addr: #there should not be other functions around this makenew = False else: mylog(f'Removed bogus prior function at {hex(fn.start)}') bv.remove_user_function(fn) if makenew: mylog(f'Created function at {hex(addr)}') bv.create_user_function(addr) if symbol.startswith("->:"): #call to a function, name destination symbol = symbol[3:] symtype=SymbolType.FunctionSymbol dest = bv.get_callees(addr) if len(dest) == 0: #current function hasn't been analyzed yet, extract destination from disasssembly and create destination function and symbol destaddr = int(bv.get_disassembly(addr).split(' ')[-1], 16) bv.create_user_function(destaddr) bv.define_user_symbol(Symbol(symtype, destaddr, symbol)) mylog(f'Created function at {hex(destaddr)}') continue else: destfn = bv.get_function_at(dest[0]) destfn.name = symbol mylog(f'Renamed function {symbol} as destination of call at {hex(addr)}') if symbol.startswith("->"): symbol = symbol[2:] continue #just a pointer to an import, skip if symbol.startswith("*"): symbol = symbol[1:] bv.define_user_symbol(Symbol(symtype, addr, symbol)) mylog(f'Creating symbol {symbol} at {hex(addr)}') symcount += 1 else: #new memory segment records = re.split('\s+', line[5:]) base = int(records[0], 16) size = int(records[1][:-1], 16) try: name = records[2] except IndexError: name = 'name' try: cls = records[3] except IndexError: cls = 'class' if name.endswith("END") or name.endswith("END_"): continue segments[index] = [ base, size, name, cls ] log_info(f'Updated {symcount} total symbols') This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,11 +3,11 @@ # Takes a file offset, converts it to a virtual address and navigates there. Note that the relative checkbox wont work but we use this dialog to get calculation feature while True: offset=get_address_input("File offset: ", "Offset") if not offset: break if offset_to_vaddr(offset): vaddr = bv.get_address_for_data_offset(offset) log_info("Navigating to file offset %x" % vaddr) bv.navigate(bv.view, vaddr) break This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -6,12 +6,12 @@ from binaryninjaui import UIContext def get_selected_data(): #remove when snippets implements this first-class return bv.read(current_selection[0], current_selection[1]-current_selection[0]) def openFile(filename): ctx = UIContext.activeContext() ctx.openFilename(filename) temp = tempfile.NamedTemporaryFile(delete=False) buf = get_selected_data() This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,18 @@ def c_source(bv, func): lines = '' settings = DisassemblySettings() settings.set_option(DisassemblyOption.ShowAddress, False) obj = lineardisassembly.LinearViewObject.language_representation(bv, settings) cursor_end = lineardisassembly.LinearViewCursor(obj) cursor_end.seek_to_address(func.highest_address) body = bv.get_next_linear_disassembly_lines(cursor_end) cursor_end.seek_to_address(func.highest_address) header= bv.get_previous_linear_disassembly_lines(cursor_end) for line in header: lines += str(line) + '\n' for line in body: lines += str(line) + '\n' return lines for line in c_source(bv, current_function): print(line) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,6 +4,6 @@ filename = get_open_filename_input("Python File:") if filename: exec(open(filename).read()) else: show_message_box("Invalid python file", "Invalid python file selected.", MessageBoxButtonSet.OKButtonSet, MessageBoxIcon.ErrorIcon) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,37 +3,37 @@ # DEPRECATED IN FAVOR OF "export to text" snippet def filtername(name): return "".join(x for x in name if x.isalnum() or x in ["_", "-"]) choice = get_choice_input("Save all functions or just current?", "choices", ["All", "Current"]) if (choice == 0): import os fname = os.path.splitext(os.path.basename(bv.file.filename))[0] folder = get_directory_name_input("Where to save decompilation:").decode('utf-8') for fn in bv.functions: source = '\n'.join(map(str, fn.hlil.root.lines)) output = os.path.join(folder, filtername(fn.name) + ".txt") try: with open(output, 'w') as f: f.write(source) log_info(f"Dumped {fn.name} to {output}") except: log_error(f"Unable to save {output}") if (choice == 1): source = '\n'.join(map(str, current_function.hlil.root.lines)) while True: output = get_save_filename_input("Source filename:", "txt", "%s.txt" % filtername(current_function.name)) if output == None: msg = "No file specified." interaction.show_message_box(msg, msg) break try: with open(output, "w") as f: f.write(source) except: msg = "Save failed. Try again?" if not interaction.show_message_box(msg, msg, buttons=MessageBoxButtonSet.YesNoButtonSet): break This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,46 +4,46 @@ from PySide2 import QtWidgets, QtGui, QtWidgets, QtCore def basic(): popout = QtWidgets.QDialog() popout.setWindowTitle("test popout1") popout.exec_() def qpixmap(): pixmap = QtGui.QPixmap("play-and-pause-button.png") mask = pixmap.createMaskFromColor(QtGui.QColor('black'), QtGui.Qt.MaskOutColor) pixmap.fill((QtGui.QColor('red'))) pixmap.setMask(mask) window = QtWidgets.QDialog() window.setWindowTitle("View Image") label = QtWidgets.QLabel(window) label.setPixmap(pixmap) label.setGeometry(QtCore.QRect(10, 40, pixmap.width(), pixmap.height())) window.resize(pixmap.width()+20, pixmap.height()+100) window.exec_() def qpixmap2(): icon = QtGui.QIcon("play-and-pause-button.svg") button = QtWidgets.QPushButton(icon) msg_box = QtWidgets.QMessageBox() msg_box.setWindowTitle("Testing Icons") msg_box.exec_() def colorize(img, color): pixmap = QtGui.QPixmap(img) mask = pixmap.createMaskFromColor(QtGui.QColor('black'), QtGui.Qt.MaskOutColor) pixmap.fill(color) pixmap.setMask(mask) return pixmap def qicon(): ico = QtGui.QIcon("play-and-pause-button.svg") ico2 = QtGui.QIcon(colorize(ico.pixmap(ico.actualSize(QtCore.QSize(1024, 1024))), QtGui.QColor('red'))) msg_box = QtWidgets.QMessageBox() msg_box.setWindowTitle("Show Icon") button = QtWidgets.QPushButton(msg_box) button.setIcon(ico2) button.setText("PlayPause") msg_box.exec_() #qpixmap2() #qpixmap() This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,14 +2,14 @@ # annotation="" for instruction in current_basic_block.get_disassembly_text(): if instruction.address >= current_selection[0] and instruction.address < current_selection[1]: address = instruction.address value = instruction.tokens[-1].value operand = instruction.tokens[-1].operand type = IntegerDisplayType.CharacterConstantDisplayType current_function.set_int_display_type(address, value, operand, type) while (value > 0): annotation += chr(value % 256) value = value >> 8 log_info("Adding comment for string: %s" % annotation) current_function.set_comment_at(current_selection[0], annotation) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,10 +3,10 @@ import subprocess result = subprocess.run(['/usr/bin/xcrun', '--find', 'swift-demangle'], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) if result.returncode == 0: demangle_str = result.stdout.decode('utf-8') for f in bv.functions: result = subprocess.run([demangle_str, '-simplified', '-compact', symbol], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) if result.returncode == 0: f.name = demangle(f.name) else: log_error('Unable to find swift-demangle.') This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,8 +7,8 @@ from binaryninjaui import UIActionHandler, DockHandler def triggerAction(action): handler = UIActionHandler().actionHandlerFromWidget(DockHandler.getActiveDockHandler().parent()) handler.executeAction(action) action="About..." execute_on_main_thread_and_wait(lambda: triggerAction(action)) -
psifertex revised this gist
Feb 11, 2022 . 1 changed file with 3 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -8,6 +8,8 @@ operand = instruction.tokens[-1].operand type = IntegerDisplayType.CharacterConstantDisplayType current_function.set_int_display_type(address, value, operand, type) while (value > 0): annotation += chr(value % 256) value = value >> 8 log_info("Adding comment for string: %s" % annotation) current_function.set_comment_at(current_selection[0], annotation) -
psifertex renamed this gist
Jan 14, 2022 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
psifertex renamed this gist
Jan 14, 2022 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
psifertex revised this gist
Jan 14, 2022 . 1 changed file with 9 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,9 @@ # run python file # # Run a file from disk with the current python context filename = get_open_filename_input("Python File:") if filename: exec(open(filename).read()) else: show_message_box("Invalid python file", "Invalid python file selected.", MessageBoxButtonSet.OKButtonSet, MessageBoxIcon.ErrorIcon) -
psifertex revised this gist
Dec 9, 2021 . 1 changed file with 7 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -11,9 +11,11 @@ domain = b'https://gist.github.com' path = b'/psifertex/6fbc7532f536775194edd26290892ef7' # Feel free to adapt to your own setup subfolder = 'default' # Change to save the snippets to a different sub-folder tab2space = False width = 4 def download(url): provider = next(iter(DownloadProvider)).create_instance() code, data = provider.get_response(url) if code == 0: return data @@ -45,7 +47,10 @@ def update_snippets(): continue basename = os.path.basename(item.filename) with open(os.path.join(snippetPath, basename), 'wb') as f: if tab2space: f.write(zip.read(item).replace(b'\t', b' ' * width)) else: f.write(zip.read(item)) log_info("Extracting %s" % item.filename) update_snippets() -
psifertex revised this gist
Oct 6, 2021 . 1 changed file with 17 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,17 @@ # get action context # # Useful for quering what is selected from a snippet or plugin instead of using various register_for APIs def get_current_context() -> Optional[Any]: ctx = UIContext.activeContext() if not ctx: ctx = UIContext.allContexts()[0] if not ctx: binaryninja.log_warn(f'No UI Context available') return None handler = ctx.contentActionHandler() if not handler: binaryninja.log_warn(f'No Action Context available') return None return handler.actionContext()
NewerOlder