def load_file(ctx): if not os.path.exists(ctx.filename): error("file {ctx.filename} doesn't exist".format(ctx=ctx)) if ctx.interactive: return False die() if not os.path.isfile(ctx.filename): error("this is not a file".format(ctx=ctx)) if ctx.interactive: return False die() dirname = os.path.dirname(ctx.filename) db_path = dirname + "/" if dirname != "" else "" db_path += "." + os.path.basename(ctx.filename) + ".db" db_exists = os.path.exists(db_path) ctx.db_path = db_path try: dis = Disassembler(ctx.filename, ctx.raw_type, ctx.raw_base, ctx.raw_big_endian, load_symbols=not db_exists) except ExcArch as e: error("arch %s is not supported" % e.arch) if ctx.interactive: return False die() except ExcFileFormat: error("the file is not PE or ELF binary") if ctx.interactive: return False die() except ExcPEFail as e: error(str(e.e)) error("It seems that pefile.parse_data_directories is bugged.") error("Maybe you should Retry") if ctx.interactive: return False die() # Load symbols in the database if db_exists: info("open database %s" % db_path) fd = open(db_path, "r") db = json.loads(fd.read()) ctx.db = db sym = dis.binary.symbols rev_sym = dis.binary.reverse_symbols for name, addr in db["symbols"].items(): sym[name] = addr rev_sym[addr] = name fd.close() ctx.dis = dis ctx.libarch = dis.load_arch_module() return True
def disasm(ctx): ctx.gph = ctx.dis.get_graph(ctx.entry_addr) if ctx.gph == None: error("capstone can't disassemble here") return ctx.gph.graph_init(ctx) if ctx.graph: ctx.gph.html_graph(ctx.dis.jmptables) try: ast = generate_ast(ctx) except ExcIfelse as e: error("can't have a ifelse here %x" % e.addr) if ctx.interactive: return die() if ctx.vim: base = os.path.basename(ctx.filename) + "_" + ctx.entry # re-assign if no colors ctx.libarch.process_ast.assign_colors(ctx, ast) ctx.color = False generate_vim_syntax(ctx, base + ".vim") sys.stdout = open(base + ".rev", "w+") o = ctx.libarch.output.Output(ctx) o.print_ast(ctx.entry_addr, ast) if ctx.vim: print("Run : vim {0}.rev -S {0}.vim".format(base), file=sys.stderr)
def reverse(ctx): if not load_file(ctx): die() if ctx.list_sections: for name, start, end in ctx.dis.binary.iter_sections(): ctx.dis.print_section_meta(name, start, end) return if ctx.syms: ctx.dis.print_symbols(ctx.sectionsname) return init_entry_addr(ctx) if ctx.calls_in_section is not None: ctx.dis.print_calls(ctx) return if ctx.dump: if ctx.vim: base = os.path.basename(ctx.filename) + "_" + ctx.entry ctx.color = False sys.stdout = open(base + ".rev", "w+") if ctx.dump: ctx.dis.dump_asm(ctx, ctx.lines) if ctx.vim: generate_vim_syntax(ctx, base + ".vim") print("Run : vim {0}.rev -S {0}.vim".format(base), file=sys.stderr) return disasm(ctx)
def init_entry_addr(ctx): if ctx.entry == "EP": entry_addr = ctx.dis.binary.get_entry_point() else: try: entry_addr = ctx.dis.get_addr_from_string(ctx.entry, ctx.raw_type != None) # An exception is raised if the symbol was not found if ctx.entry is None: ctx.entry = "main" except ExcSymNotFound as e: error("symbol %s not found" % e.symname) if ctx.interactive_mode: return False error("You can see all symbols with -s (if resolution is done).") error("Note: --dump need the option -x.") die() s = ctx.dis.binary.get_section(entry_addr) if s is None: error("the address 0x%x was not found" % entry_addr) if ctx.interactive_mode: return False die() ctx.entry_addr = entry_addr return True
def reverse(ctx): if not load_file(ctx): die() if ctx.syms: ctx.dis.print_symbols(ctx.sectionsname) return init_addr(ctx) if ctx.calls: ctx.dis.print_calls(ctx) return if ctx.dump: if ctx.vim: base = os.path.basename(ctx.filename) ctx.color = False sys.stdout = open(base + ".rev", "w+") ctx.dis.dump(ctx, ctx.lines) if ctx.vim: generate_vim_syntax(ctx, base + ".vim") print("Run : vim {0}.rev -S {0}.vim".format(base), file=sys.stderr) return disasm(ctx)
def reverse(ctx): if not load_file(ctx): die() if ctx.list_sections: for s in ctx.dis.binary.iter_sections(): s.print_header() return if ctx.syms: ctx.dis.print_symbols(ctx.sectionsname) return init_entry_addr(ctx) if ctx.calls_in_section is not None: ctx.dis.print_calls(ctx) return if ctx.dump: if ctx.dump: ctx.dis.dump_asm(ctx, ctx.lines).print() return o = disasm(ctx) if o is not None: o.print()
def disasm(ctx): ctx.gph = ctx.dis.get_graph(ctx.entry_addr) if ctx.gph == None: error("capstone can't disassemble here") return ctx.gph.graph_init(ctx) if ctx.graph: ctx.gph.html_graph() try: ast = generate_ast(ctx) except ExcIfelse as e: error("can't have a ifelse here %x" % e.addr) if ctx.interactive: return die() if ctx.vim: base = os.path.basename(ctx.filename) + "_" + ctx.entry # re-assign if no colors ctx.libarch.process_ast.assign_colors(ctx, ast) ctx.color = False generate_vim_syntax(ctx, base + ".vim") sys.stdout = open(base + ".rev", "w+") o = ctx.libarch.output.Output(ctx) o.print_ast(ctx.entry_addr, ast) if ctx.vim: print("Run : vim {0}.rev -S {0}.vim".format(base), file=sys.stderr)
def decompile(self): self.is_dump = False self.gph, pe_nb_new_syms = self.gctx.dis.get_graph(self.entry) if self.gph is None: error("capstone can't disassemble here") return None self.gph.simplify() if self.gctx.db.loaded and pe_nb_new_syms: self.gctx.db.modified = True try: self.gph.loop_detection(self.entry) ast, correctly_ended = generate_ast(self) if not correctly_ended: debug__("Second try...") self.gph.loop_detection(self.entry, True) ast, _ = generate_ast(self) self.ast = ast except ExcIfelse as e: error("can't have a ifelse here %x" % e.addr) if self.gctx.interactive_mode: return None die() o = self.gctx.libarch.output.Output(self) o._ast(self.entry, ast) self.output = o return o
def __init__(self, filename, raw_bits=0): self.code = {} self.code_idx = [] self.binary = Binary(filename, raw_bits) arch = self.binary.get_arch() if arch == ARCH_x86: self.bits = 32 elif arch == ARCH_x64: self.bits = 64 else: die("only x86 and x64 are supported")
def main(base_url, test_modules): try: for module in test_modules: url = "%sLists/%s/AllItems.aspx" %(base_url, module) actions.tryingURL(url, RUNNING_MODE) url = "%sLists/%s/DispForm.aspx" %(base_url, module) actions.bruteID(url, RUNNING_MODE) if actions.tryingURL(url, RUNNING_MODE) < 300 else None except KeyboardInterrupt: utils.die("Stopped by user", "KeyboardInterrupt") except Exception as RuntimeErr: utils.die("Runtime error", RuntimeErr)
def main(base_url): try: for path in wordlist.listDefault().replace("\t", "").split("\n"): url = base_url + path actions.tryingURL(url, RUNNING_MODE) for line in wordlist.listSub().replace("\t", "").split("\n"): path, param = line.split("?") url = base_url + path actions.bruteID( url, RUNNING_MODE, param) if actions.tryingURL(url, RUNNING_MODE) < 300 else None except KeyboardInterrupt: utils.die("Stopped by user", "KeyboardInterrupt") except Exception as RuntimeErr: utils.die("Runtime error", RuntimeErr)
def load_file(self, filename=None): if filename is None: filename = self.filename if not os.path.exists(filename): error("file {self.filename} doesn't exist".format(self=self)) if self.interactive_mode: return False die() if not os.path.isfile(filename): error("this is not a file".format(self=self)) if self.interactive_mode: return False die() self.db = Database() self.db.load(filename) try: dis = Disassembler(filename, self.raw_type, self.raw_base, self.raw_big_endian, self.db) except ExcArch as e: error("arch %s is not supported" % e.arch) if self.interactive_mode: return False die() except ExcFileFormat: error("the file is not PE or ELF binary") if self.interactive_mode: return False die() except ExcPEFail as e: error(str(e.e)) error("it seems that there is a random bug in pefile, you shoul retry.") error("please report here https://github.com/joelpx/reverse/issues/16") if self.interactive_mode: return False die() self.dis = dis self.libarch = dis.load_arch_module() return True
def disasm(self, addr): (data, virtual_addr, flags) = self.binary.get_section(addr) if not flags["exec"]: die("the address 0x%x is not in an executable section" % addr) mode = CS_MODE_64 if self.bits == 64 else CS_MODE_32 md = Cs(CS_ARCH_X86, mode) md.detail = True for i in md.disasm(data, virtual_addr): self.code[i.address] = i self.code_idx.append(i.address) # Now load imported symbols for PE. This cannot be done before, # because we need the code for a better resolution. if self.binary.get_type() == T_BIN_PE: self.binary.load_import_symbols(self.code)
def __init__(self, filename, raw_bits=0): self.__binary = None self.reverse_symbols = {} self.symbols = {} if raw_bits != 0: self.__binary = lib.fileformat.raw.Raw(filename, raw_bits) else: try: self.__binary = lib.fileformat.elf.ELF(self, filename) except Exception: try: self.__binary = lib.fileformat.pe.PE(self, filename) except Exception: die("the file is not PE or ELF binary") self.__binary.load_static_sym() self.__binary.load_dyn_sym() self.__binary.load_data_sections()
def disasm(ctx): ctx.gph, pe_nb_new_syms = ctx.dis.get_graph(ctx.entry_addr) if ctx.gph == None: error("capstone can't disassemble here") return None ctx.gph.simplify() if ctx.db.loaded and pe_nb_new_syms: ctx.db.modified = True try: ctx.gph.loop_detection(ctx, ctx.entry_addr) ast, correctly_ended = generate_ast(ctx) if not correctly_ended: debug__("Second try...") ctx.gph.loop_detection(ctx, ctx.entry_addr, True) ast, _ = generate_ast(ctx) except ExcIfelse as e: error("can't have a ifelse here %x" % e.addr) if ctx.interactive_mode: return None die() if ctx.graph: ctx.gph.dot_graph(ctx.dis.jmptables) if ctx.vim: base = os.path.basename(ctx.filename) + "_" + ctx.entry # re-assign if no colors ctx.libarch.process_ast.assign_colors(ctx, ast) ctx.color = False generate_vim_syntax(ctx, base + ".vim") sys.stdout = open(base + ".rev", "w+") o = ctx.libarch.output.Output(ctx) o._ast(ctx.entry_addr, ast) if ctx.vim: print("Run : vim {0}.rev -S {0}.vim".format(base), file=sys.stderr) return o
def get_ast_ifgoto(paths, curr_loop_idx, inst): nxt = gph.link_out[inst.address] c1 = paths.loop_contains(curr_loop_idx, nxt[BRANCH_NEXT]) c2 = paths.loop_contains(curr_loop_idx, nxt[BRANCH_NEXT_JUMP]) if c1 and c2: die("can't have a ifelse here %x" % inst.address) # If the address of the jump is inside the loop, we # invert the conditions. example : # # jmp conditions # loop: # code ... # conditions: # cmp ... # jg endloop # cmp ... # jne loop # endloop: # # Here the last jump point inside the loop. We want to # replace by this : # # loop { # cmp ... # jg endloop # cmp ... # je endloop # code ... # } # here there is an implicit jmp to loop # endloop: # cond_id = inst.id br = nxt[BRANCH_NEXT_JUMP] if c2: cond_id = invert_cond(cond_id) br = nxt[BRANCH_NEXT] return Ast_IfGoto(inst, cond_id, br)
def load_file(ctx): if not os.path.exists(ctx.filename): error("file {ctx.filename} doesn't exists".format(ctx=ctx)) if ctx.interactive: return False die() if not os.path.isfile(ctx.filename): error("this is not a file".format(ctx=ctx)) if ctx.interactive: return False die() try: dis = Disassembler(ctx.filename, ctx.raw_type, ctx.raw_base, ctx.raw_big_endian) except ExcArch as e: error("arch %s is not supported" % e.arch) if ctx.interactive: return False die() except ExcFileFormat: error("the file is not PE or ELF binary") if ctx.interactive: return False die() except ExcPEFail as e: error(str(e.e)) error("It seems that pefile.parse_data_directories is bugged.") error("Maybe you should Retry") if ctx.interactive: return False die() ctx.dis = dis ctx.libarch = dis.load_arch_module() if ctx.symfile: dis.load_user_sym_file(ctx.symfile) return True
def init_addr(ctx): if ctx.entry == "EP": addr = ctx.dis.binary.get_entry_point() else: try: addr = ctx.dis.get_addr_from_string(ctx.entry, ctx.raw_type != None) except ExcSymNotFound as e: error("symbol %s not found" % e.symname) if ctx.interactive: return False error("Try with --sym to see all symbols.") error( "If you have set the option --dump or --calls you need to set") error("the option -x (see --help).") die() try: ctx.dis.check_addr(addr) except ExcNotExec as e: error("the address 0x%x is not in an executable section" % e.addr) if ctx.interactive: return False die() except ExcNotAddr as e: error("the address 0x%x cannot be found" % e.addr) if ctx.interactive: return False die() ctx.addr = addr return True
def init_addr(ctx): if ctx.entry == "EP": addr = ctx.dis.binary.get_entry_point() else: try: addr = ctx.dis.get_addr_from_string(ctx.entry, ctx.raw_type != None) except ExcSymNotFound as e: error("symbol %s not found" % e.symname) if ctx.interactive: return False error("Try with --sym to see all symbols.") die() try: ctx.dis.check_addr(addr) except ExcNotExec as e: error("the address 0x%x is not in an executable section" % e.addr) if ctx.interactive: return False die() except ExcNotAddr as e: error("the address 0x%x cannot be found" % e.addr) if ctx.interactive: return False die() ctx.addr = addr return True
def get_addr_from_string(self, opt_addr, raw=False): if opt_addr is None: if raw: return 0 search = ["main", "_main"] else: search = [opt_addr] found = False for s in search: if s.startswith("0x"): a = int(opt_addr, 16) else: a = self.binary.symbols.get(s, -1) if a != -1: found = True break if not found: error("symbol %s not found" % search[0]) die("Try with --sym to see all symbols.") return a
def init_entry_addr(ctx): if ctx.calls_in_section is not None: try: entry_addr = ctx.dis.binary.section_start(ctx.calls_in_section) except ExcSectionNotFound as e: error("section %s not found" % e.section) if ctx.interactive: return False die() elif ctx.entry == "EP": entry_addr = ctx.dis.binary.get_entry_point() else: try: entry_addr = ctx.dis.get_addr_from_string(ctx.entry, ctx.raw_type != None) # An exception is raised if the symbol was not found if ctx.entry is None: ctx.entry = "main" except ExcSymNotFound as e: error("symbol %s not found" % e.symname) if ctx.interactive: return False error("You can see all symbols with -s (if resolution is done).") error("Note: --dump need the option -x.") die() try: ctx.dis.check_addr(ctx, entry_addr) except ExcNotExec as e: error("the address 0x%x is not in an executable section" % e.addr) if ctx.interactive: return False die() except ExcNotAddr as e: error("the address 0x%x cannot be found" % e.addr) if ctx.interactive: return False die() ctx.entry_addr = entry_addr return True
def init_addr(ctx): if ctx.calls_in_section is not None: try: addr = ctx.dis.binary.section_start(ctx.calls_in_section) except ExcSectionNotFound as e: error("section %s not found" % e.section) if ctx.interactive: return False die() elif ctx.entry == "EP": addr = ctx.dis.binary.get_entry_point() else: try: addr = ctx.dis.get_addr_from_string(ctx.entry, ctx.raw_type != None) except ExcSymNotFound as e: error("symbol %s not found" % e.symname) if ctx.interactive: return False error("Try with -s to see all symbols.") error("If you have set the option --dump or --calls you need to set") error("the option -x (see --help).") die() try: ctx.dis.check_addr(addr) except ExcNotExec as e: error("the address 0x%x is not in an executable section" % e.addr) if ctx.interactive: return False die() except ExcNotAddr as e: error("the address 0x%x cannot be found" % e.addr) if ctx.interactive: return False die() ctx.addr = addr return True
def init_address(self, entry): if isinstance(entry, int): self.entry = entry return True if entry == "EP": self.entry = self.gctx.dis.binary.get_entry_point() return True if entry is None: if self.gctx.raw_type is not None: self.entry = 0 return True self.entry = self.gctx.dis.binary.symbols.get("main", None) or \ self.gctx.dis.binary.symbols.get("_main", None) if self.entry is None: error("symbol main or _main not found") if self.gctx.interactive_mode: return False die() return True is_hexa = entry.startswith("0x") if not is_hexa and entry[:4] in RESERVED_PREFIX: entry = entry[4:] is_hexa = True if is_hexa: try: self.entry = int(entry, 16) except: error("bad hexa string %s" % entry) if self.gctx.interactive_mode: return False die() return True self.entry = self.gctx.dis.binary.symbols.get(entry, None) or \ self.gctx.dis.binary.section_names.get(entry, None) if self.entry is None: error("symbol %s not found" % entry) if self.gctx.interactive_mode: return False die() return True
def init_entry_addr(ctx): if ctx.calls_in_section is not None: s = ctx.dis.binary.get_section_by_name(ctx.calls_in_section) if s is None: error("section %s not found" % ctx.calls_in_section) if ctx.interactive: return False die() entry_addr = s.start elif ctx.entry == "EP": entry_addr = ctx.dis.binary.get_entry_point() else: try: entry_addr = ctx.dis.get_addr_from_string(ctx.entry, ctx.raw_type != None) # An exception is raised if the symbol was not found if ctx.entry is None: ctx.entry = "main" except ExcSymNotFound as e: error("symbol %s not found" % e.symname) if ctx.interactive: return False error("You can see all symbols with -s (if resolution is done).") error("Note: --dump need the option -x.") die() s = ctx.dis.binary.get_section(entry_addr) if s is None: error("the address 0x%x was not found" % entry_addr) if ctx.interactive: return False die() if not s.is_exec: warning("the address 0x%x is not in an executable section" % entry_addr) ctx.entry_addr = entry_addr return True
def parse_args(self): parser = ArgumentParser(description= 'Reverse engineering for x86/ARM/MIPS binaries. Generation of pseudo-C. ' 'Supported formats : ELF, PE. More commands available in the interactive' ' mode. https://github.com/joelpx/reverse') parser.add_argument('filename', nargs='?', metavar='FILENAME') parser.add_argument('-nc', '--nocolor', action='store_true') parser.add_argument('-g', '--graph', action='store_true', help='Generate a file graph.dot.') parser.add_argument('--noandif', action='store_true', help="Print normal 'if' instead of 'andif'") parser.add_argument('--datasize', type=int, default=30, metavar='N', help='default 30, maximum of chars to display for strings or bytes array.') parser.add_argument('-x', '--entry', metavar='SYMBOLNAME|0xXXXXX|EP', help='Pseudo-decompilation, default is main. EP stands for entry point.') parser.add_argument('--vim', action='store_true', help='Generate syntax colors for vim') parser.add_argument('-s', '--symbols', action='store_true', help='Print all symbols') parser.add_argument('--sections', action='store_true', help='Print all sections') parser.add_argument('--dump', action='store_true', help='Dump asm without decompilation') parser.add_argument('-l', '--lines', type=int, default=30, metavar='N', help='Max lines used with --dump') parser.add_argument('--bytes', action='store_true', help='Print instruction bytes') parser.add_argument('-i', '--interactive', action='store_true', help='Interactive mode') parser.add_argument('-d', '--opt_debug', action='store_true') parser.add_argument('-ns', '--nosectionsname', action='store_true') parser.add_argument('--raw', metavar='x86|x64|arm|mips|mips64', help='Consider the input file as a raw binary') parser.add_argument('--rawbase', metavar='0xXXXXX', help='Set base address of a raw file (default=0)') parser.add_argument('--rawbe', action='store_true', help='If not set it\'s in little endian') args = parser.parse_args() self.debug = args.opt_debug self.print_andif = not args.noandif self.color = not args.nocolor self.sectionsname = not args.nosectionsname self.max_data_size = args.datasize self.filename = args.filename self.raw_type = args.raw self.raw_base = args.rawbase self.syms = args.symbols self.entry = args.entry self.do_dump = args.dump self.vim = args.vim self.interactive_mode = args.interactive self.nb_lines = args.lines self.graph = args.graph self.raw_big_endian = args.rawbe self.list_sections = args.sections self.print_bytes = args.bytes if self.raw_base is not None: try: self.raw_base = int(self.raw_base, 16) except: error("--rawbase must be in hex format") die() else: self.raw_base = 0
# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # from lib import reverse, parse_args from lib.utils import info, die # Generates the file custom_colors.py at the beginning import lib.colors if __name__ == '__main__': ctx = parse_args() if ctx.color and lib.colors.VERSION < 1.3: info("There is a new version of custom_colors.py. If it's wasn't") info("modified you can delete it. Otherwise you can copy it") info("somewhere, run again your command then merge the file at hand.") die() if ctx.interactive_mode: from lib.ui.console import Console i = Console(ctx) elif ctx.filename is not None: reverse(ctx)
def parse_args(): # Parse arguments parser = ArgumentParser( description= 'Reverse engineering for x86/ARM/MIPS binaries. Generation of pseudo-C. ' 'Supported formats : ELF, PE. More commands available in the interactive' ' mode. https://github.com/joelpx/reverse') parser.add_argument('filename', nargs='?', metavar='FILENAME') parser.add_argument('-nc', '--nocolor', action='store_true') parser.add_argument('-g', '--graph', action='store_true', help='Generate an html flow graph. See d3/index.html.') parser.add_argument('--nocomment', action='store_true', help="Don't print comments") parser.add_argument('--noandif', action='store_true', help="Print normal 'if' instead of 'andif'") parser.add_argument( '--datasize', type=int, default=30, metavar='N', help= 'default 30, maximum of chars to display for strings or bytes array.') parser.add_argument( '-x', '--entry', metavar='SYMBOLNAME|0xXXXXX|EP', help='Pseudo-decompilation, default is main. EP stands for entry point.' ) parser.add_argument('--vim', action='store_true', help='Generate syntax colors for vim') parser.add_argument('-s', '--symbols', action='store_true', help='Print all symbols') parser.add_argument('-c', '--calls', metavar='SECTION_NAME', type=str, help='Print all calls which are in the given section') parser.add_argument('--sections', action='store_true', help='Print all sections') parser.add_argument('--dump', action='store_true', help='Dump asm without decompilation') parser.add_argument('-l', '--lines', type=int, default=30, metavar='N', help='Max lines used with --dump') parser.add_argument('--bytes', action='store_true', help='Print instruction bytes') parser.add_argument('-i', '--interactive', action='store_true', help='Interactive mode') parser.add_argument('-d', '--opt_debug', action='store_true') parser.add_argument('-ns', '--nosectionsname', action='store_true') parser.add_argument('--raw', metavar='x86|x64|arm|mips|mips64', help='Consider the input file as a raw binary') parser.add_argument('--rawbase', metavar='0xXXXXX', help='Set base address of a raw file (default=0)') parser.add_argument('--rawbe', action='store_true', help='If not set it\'s in little endian') args = parser.parse_args() ctx = Context() ctx.debug = args.opt_debug ctx.print_andif = not args.noandif ctx.color = not args.nocolor ctx.comments = not args.nocomment ctx.sectionsname = not args.nosectionsname ctx.max_data_size = args.datasize ctx.filename = args.filename ctx.raw_type = args.raw ctx.raw_base = args.rawbase ctx.syms = args.symbols ctx.calls_in_section = args.calls ctx.entry = args.entry ctx.dump = args.dump ctx.vim = args.vim ctx.interactive = args.interactive ctx.lines = args.lines ctx.graph = args.graph ctx.raw_big_endian = args.rawbe ctx.list_sections = args.sections ctx.print_bytes = args.bytes if ctx.raw_base is not None: if ctx.raw_base.startswith("0x"): ctx.raw_base = int(ctx.raw_base, 16) else: error("--rawbase must in hex format") die() else: ctx.raw_base = 0 return ctx
def load_file(ctx): if not os.path.exists(ctx.filename): error("file {ctx.filename} doesn't exist".format(ctx=ctx)) if ctx.interactive: return False die() if not os.path.isfile(ctx.filename): error("this is not a file".format(ctx=ctx)) if ctx.interactive: return False die() dirname = os.path.dirname(ctx.filename) db_path = dirname + "/" if dirname != "" else "" db_path += "." + os.path.basename(ctx.filename) + ".db" db_exists = os.path.exists(db_path) ctx.db_path = db_path jmptables = {} inline_comments = {} previous_comments = {} sym = {} rev_sym = {} mips_gp = -1 # Open the database if db_exists: info("open database %s" % db_path) fd = open(db_path, "r") db = json.loads(fd.read()) ctx.db = db # Saved symbols sym = db["symbols"] for name, addr in db["symbols"].items(): rev_sym[addr] = name try: # Saved comments for ad, comm in db["inline_comments"].items(): inline_comments[int(ad)] = comm for ad, comm in db["previous_comments"].items(): previous_comments[int(ad)] = comm # Saved jmptables for j in db["jmptables"]: jmptables[j["inst_addr"]] = \ Jmptable(j["inst_addr"], j["table_addr"], j["table"], j["name"]) except: # Not available in previous versions, this try will be # removed in the future pass try: mips_gp = db["mips_gp"] except: # Not available in previous versions, this try will be # removed in the future pass fd.close() try: dis = Disassembler(ctx.filename, ctx.raw_type, ctx.raw_base, ctx.raw_big_endian, sym, rev_sym, jmptables, inline_comments, previous_comments, load_symbols=not db_exists, mips_gp=mips_gp) except ExcArch as e: error("arch %s is not supported" % e.arch) if ctx.interactive: return False die() except ExcFileFormat: error("the file is not PE or ELF binary") if ctx.interactive: return False die() except ExcPEFail as e: error(str(e.e)) error("it seems that there is a random bug in pefile, you shoul retry.") error("please report here https://github.com/joelpx/reverse/issues/16") if ctx.interactive: return False die() ctx.dis = dis ctx.libarch = dis.load_arch_module() return True
def __error_jmp_reg(self, i): error("failed on 0x%x: %s %s" % (i.address, i.mnemonic, i.op_str)) error("Sorry, I can't generate the flow graph.") die("Try with --dump or with --forcejmp")
def load_file(ctx): if not os.path.exists(ctx.filename): error("file {ctx.filename} doesn't exist".format(ctx=ctx)) if ctx.interactive: return False die() if not os.path.isfile(ctx.filename): error("this is not a file".format(ctx=ctx)) if ctx.interactive: return False die() dirname = os.path.dirname(ctx.filename) db_path = dirname + "/" if dirname != "" else "" db_path += "." + os.path.basename(ctx.filename) + ".db" db_exists = os.path.exists(db_path) ctx.db_path = db_path jmptables = {} inline_comments = {} previous_comments = {} sym = {} rev_sym = {} mips_gp = -1 # Open the database if db_exists: info("open database %s" % db_path) fd = open(db_path, "r") db = json.loads(fd.read()) ctx.db = db # Saved symbols sym = db["symbols"] for name, addr in db["symbols"].items(): rev_sym[addr] = name try: # Saved comments for ad, comm in db["inline_comments"].items(): inline_comments[int(ad)] = comm for ad, comm in db["previous_comments"].items(): previous_comments[int(ad)] = comm # Saved jmptables for j in db["jmptables"]: jmptables[j["inst_addr"]] = \ Jmptable(j["inst_addr"], j["table_addr"], j["table"], j["name"]) except: # Not available in previous versions, this try will be # removed in the future pass try: mips_gp = db["mips_gp"] except: # Not available in previous versions, this try will be # removed in the future pass fd.close() try: dis = Disassembler(ctx.filename, ctx.raw_type, ctx.raw_base, ctx.raw_big_endian, sym, rev_sym, jmptables, inline_comments, previous_comments, load_symbols=not db_exists, mips_gp=mips_gp) except ExcArch as e: error("arch %s is not supported" % e.arch) if ctx.interactive: return False die() except ExcFileFormat: error("the file is not PE or ELF binary") if ctx.interactive: return False die() except ExcPEFail as e: error(str(e.e)) error( "it seems that there is a random bug in pefile, you shoul retry.") error("please report here https://github.com/joelpx/reverse/issues/16") if ctx.interactive: return False die() ctx.dis = dis ctx.libarch = dis.load_arch_module() return True
def main(base_url, test_modules): try: for module in test_modules: url = "%sLists/%s/AllItems.aspx" %(base_url, module) actions.tryingURL(url, RUNNING_MODE) url = "%sLists/%s/DispForm.aspx" %(base_url, module) actions.bruteID(url, RUNNING_MODE) if actions.tryingURL(url, RUNNING_MODE) < 300 else None except KeyboardInterrupt: utils.die("Stopped by user", "KeyboardInterrupt") except Exception as RuntimeErr: utils.die("Runtime error", RuntimeErr) if __name__ == "__main__": if len(sys.argv) == 2 and sys.argv[1] == "help": utils.printf(help(), "good") elif len(sys.argv) == 3: target = sys.argv[1] module = sys.argv[2].split(",") if "," in sys.argv[2] else sys.argv[2].split() else: utils.die("Invalid option", help()) if "http" not in target: target = "http://%s" %(target) if target[-1] != "/": target += "/" main(target, module)
def parse_args(): # Parse arguments parser = ArgumentParser(description= 'Reverse engineering for x86/ARM/MIPS binaries. Generation of pseudo-C. ' 'Supported formats : ELF, PE. More commands available in the interactive' ' mode. https://github.com/joelpx/reverse') parser.add_argument('filename', nargs='?', metavar='FILENAME') parser.add_argument('-nc', '--nocolor', action='store_true') parser.add_argument('-g', '--graph', action='store_true', help='Generate an html flow graph. See d3/index.html.') parser.add_argument('--nocomment', action='store_true', help="Don't print comments") parser.add_argument('--noandif', action='store_true', help="Print normal 'if' instead of 'andif'") parser.add_argument('--datasize', type=int, default=30, metavar='N', help='default 30, maximum of chars to display for strings or bytes array.') parser.add_argument('-x', '--entry', metavar='SYMBOLNAME|0xXXXXX|EP', help='Pseudo-decompilation, default is main. EP stands for entry point.') parser.add_argument('--vim', action='store_true', help='Generate syntax colors for vim') parser.add_argument('-s', '--symbols', action='store_true', help='Print all symbols') parser.add_argument('-c', '--calls', metavar='SECTION_NAME', type=str, help='Print all calls which are in the given section') parser.add_argument('--sections', action='store_true', help='Print all sections') parser.add_argument('--dump', action='store_true', help='Dump asm without decompilation') parser.add_argument('-l', '--lines', type=int, default=30, metavar='N', help='Max lines used with --dump') parser.add_argument('--bytes', action='store_true', help='Print instruction bytes') parser.add_argument('-i', '--interactive', action='store_true', help='Interactive mode') parser.add_argument('--symfile', metavar='FILENAME', type=FileType('r'), help=('Add user symbols for better readability of the analysis. ' 'Line format: ADDRESS_HEXA SYMBOL_NAME')) parser.add_argument('-d', '--opt_debug', action='store_true') parser.add_argument('-ns', '--nosectionsname', action='store_true') parser.add_argument('--raw', metavar='x86|x64|arm|mips|mips64', help='Consider the input file as a raw binary') parser.add_argument('--rawbase', metavar='0xXXXXX', help='Set base address of a raw file (default=0)') parser.add_argument('--rawbe', action='store_true', help='If not set it\'s in little endian') args = parser.parse_args() ctx = Context() ctx.debug = args.opt_debug ctx.print_andif = not args.noandif ctx.color = not args.nocolor ctx.comments = not args.nocomment ctx.sectionsname = not args.nosectionsname ctx.max_data_size = args.datasize ctx.filename = args.filename ctx.raw_type = args.raw ctx.raw_base = args.rawbase ctx.symfile = args.symfile ctx.syms = args.symbols ctx.calls_in_section = args.calls ctx.entry = args.entry ctx.dump = args.dump ctx.vim = args.vim ctx.interactive = args.interactive ctx.lines = args.lines ctx.graph = args.graph ctx.raw_big_endian = args.rawbe ctx.list_sections = args.sections ctx.print_bytes = args.bytes if ctx.raw_base is not None: if ctx.raw_base.startswith("0x"): ctx.raw_base = int(ctx.raw_base, 16) else: error("--rawbase must in hex format") die() else: ctx.raw_base = 0 return ctx
url = base_url + path actions.bruteID( url, RUNNING_MODE, param) if actions.tryingURL(url, RUNNING_MODE) < 300 else None except KeyboardInterrupt: utils.die("Stopped by user", "KeyboardInterrupt") except Exception as RuntimeErr: utils.die("Runtime error", RuntimeErr) if __name__ == "__main__": if len(sys.argv) == 2: option = sys.argv[1] elif len(sys.argv) == 3: option = sys.argv[1] RUNNING_MODE = sys.argv[2] if sys.argv[2] in ( "silent", "verbose") else utils.die("Invalid option", "Unknow mode") else: utils.die("Invalid option", help()) if option == "help": utils.printf(help(), "good") else: if "http" not in option: option = "http://%s" % (option) if option[-1] != "/": option += "/" main(option)