def plasma_file(filename, symbol, options): gctx = GlobalContext() gctx.color = False gctx.filename = filename gctx.entry = symbol gctx.quiet = True gctx.db_path = None for o in options: if o == "--raw x86": gctx.raw_type = "x86" elif o == "--raw x64": gctx.raw_type = "x64" elif o.startswith("--rawbase"): gctx.raw_base = int(o.split(" ")[1], 16) if not gctx.load_file(): die() gctx.api = Api(gctx, None) sio = StringIO() with redirect_stdout(sio): o = gctx.get_addr_context(gctx.entry).decompile() if o is not None: o.print() postfix = '{0}.rev'.format('' if symbol is None else '_' + symbol) with open(filename.replace('.bin', postfix)) as f: assert_equal(sio.getvalue(), f.read())
def console_entry(): gctx = GlobalContext() gctx.parse_args() if gctx.filename is None: die() if not gctx.load_file(): die() if gctx.interactive_mode: from plasma.lib.ui.console import Console gctx.is_interactive = True Console(gctx) else: gctx.api = Api(gctx, None) if gctx.list_sections: for s in gctx.dis.binary.iter_sections(): s.print_header() sys.exit(0) if gctx.syms: gctx.dis.print_symbols() sys.exit(0) ctx = gctx.get_addr_context(gctx.entry) if ctx is None: sys.exit(0) if gctx.do_dump: ctx.dump_asm(gctx.nb_lines).print() sys.exit(0) o = ctx.decompile() if gctx.graph: ctx.gph.dot_graph(gctx.dis.jmptables) if o is not None: if gctx.vim: base = os.path.basename(gctx.filename) + "_" + gctx.entry # re-assign if no colors gctx.libarch.process_ast.assign_colors(ctx, ctx.ast) gctx.color = False generate_vim_syntax(ctx, base + ".vim") sys.stdout = open(base + ".rev", "w+") o.print() if gctx.vim: print("run : vim {0}.rev -S {0}.vim".format(base), file=sys.stderr)
def __init__(self, gctx): self.gctx = gctx self.db = gctx.db gctx.vim = False self.visual_previous_idx = 0 self.visual_last_widgets = [] # A hack to allow window resizing os.environ['LINES']="blah" del os.environ['LINES'] os.environ['COLUMNS']="blah" del os.environ['COLUMNS'] self.COMMANDS = { "analyzer": Command( 0, 0, self.__exec_analyzer, None, [ "", "Analyzer status.", ] ), "push_analyze_symbols": Command( 0, 0, self.push_analyze_symbols, None, [ "", "Force to analyze the entry point, symbols and a memory scan will be done.", ] ), "help": Command( 0, 0, self.__exec_help, None, [ "", "Display this help." ] ), "history": Command( 0, 0, self.__exec_history, None, [ "", "Display the command history.", ] ), "save": Command( 0, 0, self.__exec_save, None, [ "", "Save the database.", ] ), "x": Command( 1, 0, self.__exec_x, self.__complete_x, [ "[SYMBOL|0xXXXX|EP]", "Decompile and print on stdout. By default it will be main.", "The decompilation is forced, it dosn't check if addresses", "are defined as code." ] ), "v": Command( 1, 0, self.__exec_v, self.__complete_x, [ "[SYMBOL|0xXXXX|EP|%VISUAL]", "Visual mode: if no address is given, previous visual is", "reopen. You can keep up to 3 visuals. Use %1, %2 or %3", "to select the visual.", "", "Main shortcuts:", "c create code", "b/w/d/Q create byte/word/dword/qword", "a create ascii string", "p create function", "o set [d|q]word as an offset", "* create an array", "x show xrefs", "r rename", "space highlight current word (ctrl-k to clear)", "; edit inline comment (enter/escape to validate/cancel)", "U undefine", "", "Options:", "I switch to traditional instruction string output (3 modes)", "M show/hide mangling", "B show/hide bytes", "", "Navigation:", "| split the window", "j jump to an address or a symbol", "/ binary search: if the first char is ! you can put an", " hexa string example: /!ab 13 42", " the search is case sensitive.", "n/N next/previous search occurence", "g top", "G bottom", "z set current line on the middle", "% goto next bracket", "{ } previous/next paragraph", "tab switch between dump/decompilation", "enter follow address", "escape go back", "u re-enter", "q quit", ] ), "hexdump": Command( 2, 1, self.__exec_hexdump, self.__complete_x, [ "SYMBOL|0xXXXX|EP [NB_LINES]", "Dump memory in hexa." ] ), # by default it will be gctx.nb_lines "dump": Command( 2, 1, self.__exec_dump, self.__complete_x, [ "SYMBOL|0xXXXX|EP [NB_LINES]", "Print contents at the specified address.", ] ), "sym": Command( 3, 0, self.__exec_sym, self.__complete_x, [ "[SYMBOL 0xXXXX] [| FILTER]", "Print all symbols or set a new symbol.", "You can filter symbols by searching the word FILTER.", "If FILTER starts with -, the match is inversed." ] ), "rename": Command( 2, 2, self.__exec_rename, self.__complete_x, [ "OLD_SYM NEW_SYM", "Rename a symbol." ] ), "exit": Command( 0, 0, self.__exec_exit, None, [ "", "Exit" ] ), "sections": Command( 0, 0, self.__exec_sections, None, [ "", "Print all sections.", ] ), "info": Command( 0, 0, self.__exec_info, None, [ "", "Information about the current binary." ] ), "jmptable": Command( 4, 4, self.__exec_jmptable, None, [ "INST_ADDR TABLE_ADDR NB_ENTRIES SIZE_ENTRY", "Create a jump table referenced at TABLE_ADDR and called", "from INST_ADDR." ] ), "py": Command( -1, 0, self.__exec_py, self.__complete_file, [ "[!][FILE]", "Run an interactive python shell or execute a script.", "Global variables api and args will be passed to the script.", "The character ! is an alias to the scripts directory." ] ), "mips_set_gp": Command( 1, 1, self.__exec_mips_set_gp, None, [ "ADDR", "Set the register $gp to a fixed value. Note that it will", "erase all defined memory." ] ), "functions": Command( 0, 0, self.__exec_functions, None, [ "", "Print the function list." ] ), "xrefs": Command( 1, 1, self.__exec_xrefs, self.__complete_x, [ "SYMBOL|0xXXXX|EP", "Print cross references to the specified address." ] ), "memmap": Command( 0, 0, self.__exec_memmap, None, [ "", "Open a qt window to display the memory." ] ), "frame_size": Command( 2, 2, self.__exec_frame_size, self.__complete_x, [ "[SYMBOL|0xXXXX|EP] frame_size", "Change the frame size of a function, the function will be re-analyzed." ] ), } if gctx.dis.is_x86: import plasma.lib.arch.x86.analyzer as arch_analyzer elif gctx.dis.is_mips: import plasma.lib.arch.mips.analyzer as arch_analyzer elif gctx.dis.is_arm: import plasma.lib.arch.arm.analyzer as arch_analyzer self.analyzer = Analyzer() self.analyzer.init() self.analyzer.start() self.api = Api(gctx, self.analyzer) gctx.api = self.api self.analyzer.set(gctx, arch_analyzer) self.gctx.dis.binary.api = self.api if gctx.dis.is_mips and not gctx.dis.mips_gp: if sys.stdin.isatty(): print("please run first these commands :") print("mips_set_gp 0xADDRESS") print("push_analyze_symbols") else: # If false it means that the first analysis was already done if gctx.autoanalyzer and len(self.db.mem) == 0: print("analyzer is running... check the command analyzer to see the status") self.push_analyze_symbols(None) self.comp = Completer(self) self.comp.set_history(self.db.history) while 1: self.comp.loop() if SHOULD_EXIT: break if not self.check_db_modified(): break self.analyzer.msg.put("exit")
def console_entry(): gctx = GlobalContext() gctx.parse_args() if gctx.color and plasma.lib.colors.VERSION < plasma.lib.colors.CURR_VERSION: info("There is a new version of custom_colors.py. If you did any") info("modifications you can delete it. Otherwise you can copy it") info("somewhere, run again your command then merge the file at hand.") die() if gctx.filename is None: die() if not gctx.load_file(): die() if gctx.interactive_mode: from plasma.lib.ui.console import Console gctx.is_interactive = True Console(gctx) else: gctx.api = Api(gctx, None) if gctx.list_sections: for s in gctx.dis.binary.iter_sections(): s.print_header() sys.exit(0) if gctx.syms: gctx.dis.print_symbols() sys.exit(0) ctx = gctx.get_addr_context(gctx.entry) if ctx is None: sys.exit(0) if gctx.do_dump: ctx.dump_asm(gctx.nb_lines).print() sys.exit(0) o = ctx.decompile() if gctx.graph: ctx.gph.dot_graph(gctx.dis.jmptables) if o is not None: if gctx.vim: base = os.path.basename(gctx.filename) + "_" + gctx.entry # re-assign if no colors gctx.libarch.process_ast.assign_colors(ctx, ctx.ast) gctx.color = False generate_vim_syntax(ctx, base + ".vim") sys.stdout = open(base + ".rev", "w+") o.print() if gctx.vim: print("run : vim {0}.rev -S {0}.vim".format(base), file=sys.stderr)