#! /usr/bin/env python import os import sys from barf.barf import BARF if __name__ == "__main__": # # Open file # try: filename = os.path.abspath("../../bin/x86/branch4") barf = BARF(filename) except Exception as err: print err print "[-] Error opening file : %s" % filename sys.exit(1) # # Recover CFG # print("[+] Recovering program CFG...") cfg = barf.recover_cfg(ea_start=0x40052d, ea_end=0x400560) cfg.save(filename + "_cfg", print_ir=True)
#! /usr/bin/env python from barf.barf import BARF if __name__ == "__main__": # # Open file # barf = BARF("../../samples/bin/branch4.x86") # # Translate to REIL # print("[+] Translating: x86 -> REIL -> SMT...") for addr, asm_instr, reil_instrs in barf.translate(): print("0x{0:08x} : {1}".format(addr, asm_instr)) for reil_instr in reil_instrs: print("{0:14}{1}".format("", reil_instr)) try: # Some instructions cannot be translate to SMT, i.e, # UNKN, UNDEF, JCC. In those cases, an exception is # raised. smt_exprs = barf.smt_translator.translate(reil_instr) for smt_expr in smt_exprs: print("{0:16}{1}".format("", smt_expr)) except: pass
def main(): parser = init_parser() args = parser.parse_args() # Set default options. if not args.recover_all and not args.recover: args.recover_all = True process_start = time.time() filename = os.path.abspath(args.filename) if not os.path.isfile(filename): print("[-] File not found : {}".format(filename)) sys.exit(1) # Create an instance of BARF. try: barf = BARF(filename) except Exception: print("[-] Error opening file : {}".format(filename)) sys.exit(1) # Load symbols. print("[+] Parsing symbol table...") if args.symbol_file: symbols_by_addr = load_symbols_from_file(args.symbol_file) else: symbols_by_addr = load_symbols(filename) # Recover CFGs. print("[+] Recovering CFGs...") if args.recover_all: cfgs = recover_cfg_all(barf, symbols_by_addr) if args.recover: addresses = [int(addr, 16) for addr in args.recover.split(",")] cfgs = recover_cfg_some(barf, addresses, symbols_by_addr) print("[+] Number of CFGs recovered: {:d}".format(len(cfgs))) # Recover CG. print("[+] Recovering program CG...") cfgs_filtered = [] for cfg in cfgs: if len(cfg.basic_blocks) == 0: print("[*] Ignoring empty CFG: {}".format(cfg.name)) continue cfgs_filtered.append(cfg) cg = CallGraph(cfgs_filtered) cg.save(filename.split(os.path.sep)[-1] + "_cg", format=args.format) process_end = time.time() if args.time: process_time = process_end - process_start print("[+] Process time: {:.3f}s".format(process_time))
#! /usr/bin/env python import os import sys from barf.barf import BARF if __name__ == "__main__": # # Open file # try: filename = os.path.abspath("../../bin/x86/branch4") barf = BARF(filename) except Exception as err: print err print "[-] Error opening file : %s" % filename sys.exit(1) # # Translate to REIL # print("[+] Translating: x86 -> REIL -> SMT...") for addr, asm_instr, reil_instrs in barf.translate(): print("0x{0:08x} : {1}".format(addr, asm_instr)) for reil_instr in reil_instrs: print("{0:14}{1}".format("", reil_instr))
'no': '\x81', 'np': '\x8B', 'ns': '\x89', 'nz': '\x85', 'o': '\x80', 'p': '\x8A', 'pe': '\x8A', 'po': '\x8B', 's': '\x88', 'nop': '\x90', 'jmp': '\xE9', 'j': '\x0F' } filename = sys.argv[1] start = int(sys.argv[2], 16) barf = BARF(filename) base_addr = barf.binary.entry_point >> 12 << 12 b = angr.Project(filename, load_options={ 'auto_load_libs': False, 'main_opts': { 'custom_base_addr': 0 } }) cfg = barf.recover_cfg(start=start) blocks = cfg.basic_blocks prologue = start main_dispatcher = cfg.find_basic_block(prologue).direct_branch retn, pre_dispatcher = get_retn_predispatcher(cfg) relevant_blocks, nop_blocks = get_relevant_nop_blocks(cfg) print '*******************relevant blocks************************'
#! /usr/bin/env python from __future__ import absolute_import from __future__ import print_function from barf.barf import BARF if __name__ == "__main__": # x86 # ======================================================================= # # # Open file # barf = BARF("./samples/bin/branch4.x86") # # Translate to REIL # print("[+] Translating: x86 -> REIL -> SMT") for addr, asm_instr, reil_instrs in barf.translate(): print("0x{0:08x} : {1}".format(addr, asm_instr)) for reil_instr in reil_instrs: print("{0:14}{1}".format("", reil_instr)) try: # Some instructions cannot be translate to SMT, i.e, # UNKN, UNDEF, JCC. In those cases, an exception is # raised. smt_exprs = barf.smt_translator.translate(reil_instr)
def main(): global retn, pre_dispatcher, main_dispatcher, prologue, b, relevants, opcode if len(sys.argv) != 3: print('Usage: python deflat.py filename function_address(hex)') exit(0) opcode = {'a':'\x87', 'ae': '\x83', 'b':'\x82', 'be':'\x86', 'c':'\x82', 'e':'\x84', 'z':'\x84', 'g':'\x8F', 'ge':'\x8D', 'l':'\x8C', 'le':'\x8E', 'na':'\x86', 'nae':'\x82', 'nb':'\x83', 'nbe':'\x87', 'nc':'\x83', 'ne':'\x85', 'ng':'\x8E', 'nge':'\x8C', 'nl':'\x8D', 'nle':'\x8F', 'no':'\x81', 'np':'\x8B', 'ns':'\x89', 'nz':'\x85', 'o':'\x80', 'p':'\x8A', 'pe':'\x8A', 'po':'\x8B', 's':'\x88', 'nop':'\x90', 'jmp':'\xE9', 'j':'\x0F'} for k, v in opcode.items(): opcode[k] = ord(v) filename = sys.argv[1] start = int(sys.argv[2], 16) barf = BARF(filename) base_addr = barf.binary.entry_point >> 12 << 12 b = angr.Project(filename, load_options={'auto_load_libs': False, 'main_opts':{'custom_base_addr': 0}}) print("entry: ", b.entry) cfg = barf.recover_cfg(start=start) blocks = cfg.basic_blocks prologue = start main_dispatcher = cfg.find_basic_block(prologue).direct_branch retn, pre_dispatcher = get_retn_predispatcher(cfg) relevant_blocks, nop_blocks = get_relevant_nop_blocks(cfg) print('*******************relevant blocks************************') print('prologue:%#x' % start) print('main_dispatcher:%#x' % main_dispatcher) print('pre_dispatcher:%#x' % pre_dispatcher) print('retn:%#x' % retn) print('relevant_blocks:', [hex(addr) for addr in relevant_blocks]) print('*******************symbolic execution*********************') relevants = relevant_blocks relevants.append(prologue) relevants_without_retn = list(relevants) relevants.append(retn) flow = {} for parent in relevants: flow[parent] = [] modify_value = None patch_instrs = {} for relevant in relevants_without_retn: print('-------------------dse %#x---------------------' % relevant) block = cfg.find_basic_block(relevant) has_branches = False hook_addr = None for ins in block.instrs: if ins.mnemonic.startswith('cmov'): patch_instrs[relevant] = ins has_branches = True elif ins.mnemonic.startswith('call'): hook_addr = ins.address if has_branches: flow[relevant].append(symbolic_execution(relevant, hook_addr, claripy.BVV(1, 1), True)) flow[relevant].append(symbolic_execution(relevant, hook_addr, claripy.BVV(0, 1), True)) else: flow[relevant].append(symbolic_execution(relevant, hook_addr)) print('************************flow******************************') for (k, v) in flow.items(): print('%#x:' % k, [hex(child) for child in v]) print('************************patch*****************************') flow.pop(retn) origin = open(filename, 'rb') origin_data = list(origin.read()) origin.close() recovery = open(filename + '.recovered', 'wb') for nop_block in nop_blocks: fill_nop(origin_data, nop_block.start_address - base_addr, nop_block.end_address - base_addr + 1) for (parent, childs) in flow.items(): if len(childs) == 1: last_instr = cfg.find_basic_block(parent).instrs[-1] file_offset = last_instr.address - base_addr origin_data[file_offset] = opcode['jmp'] file_offset += 1 fill_nop(origin_data, file_offset, file_offset + last_instr.size - 1) fill_jmp_offset(origin_data, file_offset, childs[0] - last_instr.address - 5) else: instr = patch_instrs[parent] file_offset = instr.address - base_addr fill_nop(origin_data, file_offset, cfg.find_basic_block(parent).end_address - base_addr + 1) origin_data[file_offset] = opcode['j'] origin_data[file_offset + 1] = opcode[instr.mnemonic[4:]] fill_jmp_offset(origin_data, file_offset + 2, childs[0] - instr.address - 6) file_offset += 6 origin_data[file_offset] = opcode['jmp'] fill_jmp_offset(origin_data, file_offset + 1, childs[1] - (instr.address + 6) - 5) recovery.write(bytearray(origin_data)) recovery.close() print('Successful! The recovered file: %s' % (filename + '.recovered'))
#! /usr/bin/env python import os import sys from barf.barf import BARF if __name__ == "__main__": # # Open file # try: filename = os.path.abspath("../../samples/toy/x86/branch4") barf = BARF(filename) except Exception as err: print err print "[-] Error opening file : %s" % filename sys.exit(1) # # Recover CFG # print("[+] Recovering program CFG...") cfg = barf.recover_cfg() cfg.save(filename + "_cfg", print_ir=True)
#! /usr/bin/env python from barf.barf import BARF if __name__ == "__main__": # # Open file # barf = BARF("../../samples/bin/loop2.arm") # 00008390 <main>: # 8390: e52db004 push {fp} ; (str fp, [sp, #-4]!) # 8394: e28db000 add fp, sp, #0 # 8398: e24dd00c sub sp, sp, #12 # 839c: e3a03000 mov r3, #0 # 83a0: e50b3008 str r3, [fp, #-8] # 83a4: e3a0300a mov r3, #10 # 83a8: e50b300c str r3, [fp, #-12] # 83ac: ea000005 b 83c8 <main+0x38> # 83b0: e51b3008 ldr r3, [fp, #-8] # 83b4: e2833001 add r3, r3, #1 # 83b8: e50b3008 str r3, [fp, #-8] # 83bc: e51b300c ldr r3, [fp, #-12] # 83c0: e2433001 sub r3, r3, #1 # 83c4: e50b300c str r3, [fp, #-12] # 83c8: e51b300c ldr r3, [fp, #-12] # 83cc: e3530000 cmp r3, #0 # 83d0: 1afffff6 bne 83b0 <main+0x20> # 83d4: e51b3008 ldr r3, [fp, #-8] # 83d8: e1a00003 mov r0, r3 # 83dc: e28bd000 add sp, fp, #0
#! /usr/bin/env python import os import sys from barf.barf import BARF from barf.arch import ARCH_ARM_MODE_ARM if __name__ == "__main__": # # Open file # try: filename = os.path.abspath("../../bin/arm/loop2") barf = BARF(filename) except Exception, err: print "[-] Error opening file : %s" % filename sys.exit(1) # 00008390 <main>: # 8390: e52db004 push {fp} ; (str fp, [sp, #-4]!) # 8394: e28db000 add fp, sp, #0 # 8398: e24dd00c sub sp, sp, #12 # 839c: e3a03000 mov r3, #0 # 83a0: e50b3008 str r3, [fp, #-8] # 83a4: e3a0300a mov r3, #10 # 83a8: e50b300c str r3, [fp, #-12] # 83ac: ea000005 b 83c8 <main+0x38> # 83b0: e51b3008 ldr r3, [fp, #-8] # 83b4: e2833001 add r3, r3, #1
from __future__ import absolute_import from __future__ import print_function from barf.arch import ARCH_ARM_MODE_ARM from barf.arch import ARCH_ARM_MODE_THUMB from barf.barf import BARF if __name__ == "__main__": # x86 # ======================================================================= # # # Open file # filename = "./samples/bin/branch4.x86" barf = BARF(filename) # # Recover CFG # print("[+] Recovering program CFG...") cfg = barf.recover_cfg(start=0x40052d, end=0x400560) cfg.save(filename + "_cfg", print_ir=True) # ARM # ======================================================================= # # # Open file #
#! /usr/bin/env python import os import sys from barf.barf import BARF if __name__ == "__main__": # # Open file # try: filename = os.path.abspath("../../samples/toy/arm/loop2") barf = BARF(filename) except Exception, err: print "[-] Error opening file : %s" % filename sys.exit(1) # 00008390 <main>: # 8390: e52db004 push {fp} ; (str fp, [sp, #-4]!) # 8394: e28db000 add fp, sp, #0 # 8398: e24dd00c sub sp, sp, #12 # 839c: e3a03000 mov r3, #0 # 83a0: e50b3008 str r3, [fp, #-8] # 83a4: e3a0300a mov r3, #10 # 83a8: e50b300c str r3, [fp, #-12] # 83ac: ea000005 b 83c8 <main+0x38> # 83b0: e51b3008 ldr r3, [fp, #-8] # 83b4: e2833001 add r3, r3, #1 # 83b8: e50b3008 str r3, [fp, #-8]
elif len(node_list) == 2: created_edge = Edge(nodes[node_address], nodes[node_list[0]], color = 'darkgreen') dot_graph.add_edge(created_edge) created_edge = Edge(nodes[node_address], nodes[node_list[1]], color = 'red') dot_graph.add_edge(created_edge) ###End write edge dot_graph.write_png(function.name+"_unflat.png") if __name__ == '__main__': if(len(sys.argv) < 2): print("Please input the unplat binary") exit(-1) angr_proj = angr.Project(sys.argv[1], load_options={'auto_load_libs' : False}) barf_proj = BARF(sys.argv[1]) angr_cfg = angr_proj.analyses.CFGFast() unanalysis_function = ['init_proc', '__libc_start_main', '__gmon_start', '_start', 'deregister_tm_clones', 'register_tm_clones', 'register_tm_clones', '__do_global_dtors_aux', 'frame_dummy', '__libc_csu_init', 'libc_csu_fini', '_term_proc', '__libc_start_main'] function_manager = angr_proj.kb.functions print(dict(function_manager)) for k in dict(function_manager): name = function_manager[k].name if name not in unanalysis_function and name.startswith('__libc_start_main') == False: print(name) unflat(angr_proj, barf_proj, function_manager[k])
#! /usr/bin/env python import os import sys from barf.barf import BARF from barf.arch import ARCH_ARM_MODE_ARM if __name__ == "__main__": # # Open file # try: # ARM MODE filename = os.path.abspath("../../bin/arm/branch4") barf = BARF(filename) except Exception as err: print err print "[-] Error opening file : %s" % filename sys.exit(1) # # Recover CFG # print("[+] Recovering program CFG...") cfg = barf.recover_cfg(ea_start=0x000083c8, ea_end=0x00008404 + 0x4, arch_mode=ARCH_ARM_MODE_ARM) cfg.save(filename + "_cfg", print_ir=True)
#! /usr/bin/env python import os import sys from barf.barf import BARF from barf.arch import ARCH_ARM_MODE_THUMB if __name__ == "__main__": # # Open file # try: # ARM THUMB filename = os.path.abspath("../../bin/arm/branch4-thumb") barf = BARF(filename) except Exception as err: print err print "[-] Error opening file : %s" % filename sys.exit(1) # # Recover CFG # print("[+] Recovering program CFG...") cfg = barf.recover_cfg(ea_start=0x00010434, ea_end=0x0001046a + 0x2, arch_mode=ARCH_ARM_MODE_THUMB) cfg.save(filename + "_cfg", print_ir=True)
#! /usr/bin/env python from barf.analysis.graphs.callgraph import CallGraph from barf.barf import BARF from barf.core.symbols import load_symbols if __name__ == "__main__": # # Open file # filename = "./samples/bin/example1.x86_64" arg = "hello!" barf = BARF(filename) # # Recover CFGs. # print("[+] Recovering control flow graphs...") symbols_by_addr = load_symbols(filename) entries = [addr for addr in sorted(symbols_by_addr.keys())] cfgs = barf.recover_cfg_all(entries, symbols=symbols_by_addr) # # Build CG. # print("[+] Building call graph...") cfgs_filtered = [] for cfg in cfgs: if len(cfg.basic_blocks) == 0: continue
#! /usr/bin/env python import os import sys from barf.barf import BARF if __name__ == "__main__": # # Open file # try: filename = os.path.abspath("../../samples/toy/x86/branch4") barf = BARF(filename) except Exception as err: print err print "[-] Error opening file : %s" % filename sys.exit(1) # # Recover CFG # print("[+] Recovering program CFG...") cfg = barf.recover_cfg(ea_start=0x40052d, ea_end=0x400560) cfg.save(filename + "_cfg", print_ir=True)
#! /usr/bin/env python from barf.barf import BARF if __name__ == "__main__": # # Open file # barf = BARF("../../samples/bin/loop2.x86") # # REIL emulation # context_out = barf.emulate(start=0x080483ec, end=0x08048414) print "%s : %s" % ("eax", hex(context_out['registers']["eax"])) assert (context_out['registers']["eax"] == 0xa)
#! /usr/bin/env python from __future__ import absolute_import from __future__ import print_function from barf.barf import BARF if __name__ == "__main__": # x86 # ======================================================================= # # # Open file # barf = BARF("./samples/bin/loop2.x86") # 080483ec <main>: # 80483ec: 55 push ebp # 80483ed: 89 e5 mov ebp,esp # 80483ef: 83 ec 10 sub esp,0x10 # 80483f2: c7 45 f8 00 00 00 00 mov DWORD PTR [ebp-0x8],0x0 # 80483f9: c7 45 fc 0a 00 00 00 mov DWORD PTR [ebp-0x4],0xa # 8048400: eb 08 jmp 804840a <main+0x1e> # 8048402: 83 45 f8 01 add DWORD PTR [ebp-0x8],0x1 # 8048406: 83 6d fc 01 sub DWORD PTR [ebp-0x4],0x1 # 804840a: 83 7d fc 00 cmp DWORD PTR [ebp-0x4],0x0 # 804840e: 75 f2 jne 8048402 <main+0x16> # 8048410: 8b 45 f8 mov eax,DWORD PTR [ebp-0x8] # 8048413: c9 leave # 8048414: c3 ret #
from __future__ import absolute_import from __future__ import print_function from barf.analysis.graphs.callgraph import CallGraph from barf.barf import BARF from barf.core.symbols import load_symbols if __name__ == "__main__": # # Open file # filename = "./samples/bin/example1.x86_64" arg = "hello!" barf = BARF(filename) # # Recover CFGs. # print("[+] Recovering control flow graphs...") symbols_by_addr = load_symbols(filename) entries = [addr for addr in sorted(symbols_by_addr.keys())] cfgs = barf.recover_cfg_all(entries, symbols=symbols_by_addr) # # Build CG. # print("[+] Building call graph...") cfgs_filtered = [] for cfg in cfgs:
#! /usr/bin/env python import os import sys from barf.barf import BARF if __name__ == "__main__": # # Open file # try: filename = os.path.abspath("../../bin/x86/loop2") barf = BARF(filename) except Exception, err: print "[-] Error opening file : %s" % filename sys.exit(1) # # REIL emulation # context_in = {} context_out = barf.emulate_full(context_in, 0x080483ec, 0x08048414) print "%s : %s" % ("eax", hex(context_out['registers']["eax"])) assert(context_out['registers']["eax"] == 0xa)
#! /usr/bin/env python import os import sys from barf.barf import BARF from barf.arch import ARCH_ARM_MODE_ARM if __name__ == "__main__": # # Open file # try: filename = os.path.abspath("../../bin/arm/branch4") barf = BARF(filename) except Exception as err: print err print "[-] Error opening file : %s" % filename sys.exit(1) # # Translate to REIL # print("[+] Translating x86 to REIL...") for addr, asm_instr, reil_instrs in barf.translate( ea_start=0x000083c8, ea_end=0x00008404, arch_mode=ARCH_ARM_MODE_ARM): print("0x{0:08x} : {1}".format(addr, asm_instr))
#! /usr/bin/env python import os import sys from barf.barf import BARF from barf.arch import ARCH_ARM_MODE_ARM if __name__ == "__main__": # # Open file # try: filename = os.path.abspath("../../bin/arm/branch4") barf = BARF(filename) except Exception as err: print err print "[-] Error opening file : %s" % filename sys.exit(1) # # Translate to REIL # print("[+] Translating x86 to REIL...") for addr, asm_instr, reil_instrs in barf.translate(ea_start=0x000083c8, ea_end=0x00008404, arch_mode=ARCH_ARM_MODE_ARM): print("0x{0:08x} : {1}".format(addr, asm_instr)) for reil_instr in reil_instrs:
#! /usr/bin/env python from barf.barf import BARF from barf.arch import ARCH_ARM_MODE_ARM if __name__ == "__main__": # # Open file # filename = "../../samples/bin/branch4.arm" barf = BARF(filename) # # Recover CFG # print("[+] Recovering program CFG...") cfg = barf.recover_cfg(start=0x000083c8, end=0x00008404 + 0x4, arch_mode=ARCH_ARM_MODE_ARM) cfg.save(filename + "_cfg", print_ir=True)
#! /usr/bin/env python import os import sys from barf.barf import BARF if __name__ == "__main__": # # Open file # try: filename = os.path.abspath("../../samples/toy/x86/loop2") barf = BARF(filename) except Exception, err: print "[-] Error opening file : %s" % filename sys.exit(1) # # REIL emulation # context_in = {} context_out = barf.emulate_full(context_in, 0x080483ec, 0x08048414) print "%s : %s" % ("eax", hex(context_out['registers']["eax"])) assert (context_out['registers']["eax"] == 0xa)
def main(): parser = init_parser() args = parser.parse_args() find_time = 0.0 classify_time = 0.0 verify_time = 0.0 output_fd = sys.stdout filename = os.path.abspath(args.filename) if not os.path.isfile(filename): print("[-] Error opening file : %s" % filename) sys.exit(1) # create an instance of BARF try: barf = BARF(filename) address_size = barf.arch_info.address_size except Exception as err: import traceback print(err) print(traceback.format_exc()) sys.exit(1) # Open output file. if args.output: output_fd = open(args.output, "w") if args.verify: args.classify = True # Find gadgets. candidates, find_time = do_find(barf, args) print_gadgets_raw(candidates, output_fd, args.sort, args.color, "Raw Gadgets", args.show_binary) # Classify gadgets. if args.classify: classified, classify_time = do_classify(barf, candidates, args) if args.show_classification: print_gadgets_typed(classified, output_fd, address_size, "Classified Gadgets") # Verify gadgets. if args.verify: if barf.gadget_verifier: verified, verify_time, discarded, invalid = do_verify( barf, classified, args) print_gadgets_typed(verified, output_fd, address_size, "Verified Gadgets") if args.show_invalid: print_gadgets_typed( invalid, output_fd, address_size, "Invalid Gadgets (classified but didn't pass verification process)" ) # print non-verified candidates_by_addr = sort_gadgets_by_address(candidates) verified_by_addr = sort_gadgets_by_address(verified) discarded_by_addr = sort_gadgets_by_address(discarded) diff = [] for addr in candidates_by_addr.keys(): if addr not in verified_by_addr and addr not in discarded_by_addr: diff += candidates_by_addr[addr] print_gadgets_raw(diff, output_fd, args.sort, args.color, "Non-verified Gadgets", args.show_binary) else: print( "Gadget verification not available. Check the log file for more information." ) # Print processing time. if args.time: total_time = find_time + classify_time + verify_time print("Time Report", file=output_fd) print("===========", file=output_fd) print(" ", file=output_fd) print(" Find Stage : {0:8.3f}s".format(find_time), file=output_fd) print("Classification Stage : {0:8.3f}s".format(classify_time), file=output_fd) print(" Verification Stage : {0:8.3f}s".format(verify_time), file=output_fd) print(" Total : {0:8.3f}s".format(total_time), file=output_fd) if args.summary: summary_fd = open(args.summary, "a") fmt = "{gadgets:d} {classify:d} {verify:d} {size:d} " # basic stuff fmt += "{ftime:.3f} {ctime:.3f} {vtime:.3f} " # time fmt += "{no_operation} {jump} {move_register} {load_constant} {arithmetic} {load_memory} {store_memory} {arithmetic_load} {arithmetic_store} {undefined}" by_type = sort_gadgets_by_type(verified) if GadgetType.NoOperation not in by_type: by_type[GadgetType.NoOperation] = [] if GadgetType.Jump not in by_type: by_type[GadgetType.Jump] = [] if GadgetType.MoveRegister not in by_type: by_type[GadgetType.MoveRegister] = [] if GadgetType.LoadConstant not in by_type: by_type[GadgetType.LoadConstant] = [] if GadgetType.Arithmetic not in by_type: by_type[GadgetType.Arithmetic] = [] if GadgetType.LoadMemory not in by_type: by_type[GadgetType.LoadMemory] = [] if GadgetType.StoreMemory not in by_type: by_type[GadgetType.StoreMemory] = [] if GadgetType.ArithmeticLoad not in by_type: by_type[GadgetType.ArithmeticLoad] = [] if GadgetType.ArithmeticStore not in by_type: by_type[GadgetType.ArithmeticStore] = [] if GadgetType.Undefined not in by_type: by_type[GadgetType.Undefined] = [] line = fmt.format( gadgets=len(candidates), classify=len(classified), verify=len(verified), size=barf.binary.ea_end - barf.binary.ea_start, ftime=find_time, ctime=classify_time, vtime=verify_time, no_operation=len(by_type[GadgetType.NoOperation]), jump=len(by_type[GadgetType.Jump]), move_register=len(by_type[GadgetType.MoveRegister]), load_constant=len(by_type[GadgetType.LoadConstant]), arithmetic=len(by_type[GadgetType.Arithmetic]), load_memory=len(by_type[GadgetType.LoadMemory]), store_memory=len(by_type[GadgetType.StoreMemory]), arithmetic_load=len(by_type[GadgetType.ArithmeticLoad]), arithmetic_store=len(by_type[GadgetType.ArithmeticStore]), undefined=len(by_type[GadgetType.Undefined])) summary_fd.write(line + "\n") summary_fd.close() # Close output file. if args.output: output_fd.close()
def main(): parser = init_parser() args = parser.parse_args() # Set default options. if not args.recover_all and not args.recover: args.recover_all = True process_start = time.time() filename = os.path.abspath(args.filename) if not os.path.isfile(filename): print("[-] File not found : {}".format(filename)) sys.exit(1) # Create an instance of BARF. try: barf = BARF(filename) except Exception: print("[-] Error opening file : {}".format(filename)) sys.exit(1) # Load symbols. print("[+] Parsing symbol table...") if args.symbol_file: symbols_by_addr = load_symbols_from_file(args.symbol_file) else: symbols_by_addr = load_symbols(filename) # Recover CFGs. print("[+] Recovering CFGs...") output_dir = create_output_dir(args.output_dir + os.path.sep + filename.split(os.path.sep)[-1] + "_cfg") if args.recover_all: cfgs = recover_cfg_all(barf, symbols_by_addr) if args.recover: addresses = [int(addr, 16) for addr in args.recover.split(",")] cfgs = recover_cfg_some(barf, addresses, symbols_by_addr) print("[+] Number of CFGs recovered: {:d}".format(len(cfgs))) # Saving CFGs to files. print("[+] Saving CFGs...") save_cfgs(cfgs, output_dir, args.format, args.show_reil, args.brief, args.immediate_format) process_end = time.time() if args.time: process_time = process_end - process_start print("[+] Process time: {:.3f}s".format(process_time))
#! /usr/bin/env python from barf.arch import ARCH_ARM_MODE_ARM from barf.arch import ARCH_ARM_MODE_THUMB from barf.barf import BARF if __name__ == "__main__": # x86 # ======================================================================= # # # Open file # filename = "./samples/bin/branch4.x86" barf = BARF(filename) # # Recover CFG # print("[+] Recovering program CFG...") cfg = barf.recover_cfg(start=0x40052d, end=0x400560) cfg.save(filename + "_cfg", print_ir=True) # ARM # ======================================================================= # # # Open file # filename = "./samples/bin/branch4.arm" barf = BARF(filename)
#! /usr/bin/env python from barf.barf import BARF if __name__ == "__main__": # # Open file # barf = BARF("../../samples/bin/branch4.arm") # # Translate to REIL # print("[+] Translating: x86 -> REIL -> SMT...") for addr, asm_instr, reil_instrs in barf.translate(start=0x000083c8, end=0x00008404): print("0x{0:08x} : {1}".format(addr, asm_instr)) for reil_instr in reil_instrs: print("{0:14}{1}".format("", reil_instr)) try: # Some instructions cannot be translate to SMT, i.e, # UNKN, UNDEF, JCC. In those cases, an exception is # raised. smt_exprs = barf.smt_translator.translate(reil_instr) for smt_expr in smt_exprs: print("{0:16}{1}".format("", smt_expr)) except: pass
def De_CFF(CFF_file_path, CFF_start, loop, output): # def De_CFF(CFF_file_path, CFF_start, loop, end): global b, modify_value, graph, prologue, pre_dispatcher, relevants # sys.argv = ["test.py", '/Users/mark/Desktop/djbhash-obfuscated', "0x690", 5] # de_obfuscator/benchmark/binary/binarysearch-cff # reverse-cff是特殊情况 # if len(sys.argv) != 6: # usage() # functionname = 'send_magicmsg' # filename = sys.argv[1] filename = CFF_file_path # end = int(sys.argv[4], 16) # start = int(sys.argv[2], 16) # end = int(end, 16) start = int(CFF_start, 16) barf = BARF(filename) # base_addr = barf.binary.entry_point >> 12 << 12 b = angr.Project(filename, load_options={ 'auto_load_libs': False, 'main_opts': { 'custom_base_addr': 0 } }) # irsb = irsb.next # print(irsb.next) try: cfg = barf.recover_cfg(start=start) except dis.CapstoneOperandNotSupported: # return -1 print('ccccccc') # exit() # blocks = cfg.basic_blocks # prologue序言,即初始的块 prologue = start cfg_path = output if len(cfg.basic_blocks) > 3: # print ('start %s' % functionname) loop = sys.argv[3] # loop = loop hook_addr = [] jump_end_block = [] # NDK编译后的程序的序言后面接的有可能是main_dispatcher,也有可能是pre_dispatcher, # 逻辑上,先找cmp块,在cmp块中找出pre_dispatcher, # 其中,第一块是prologue,其他的都认为是组成main_dispatcher的 # 找出cmp块(flatten特征块)vvv income, cmp_blocks, flatten_flags = findFlattenBlocks(cfg) prologue_block = cfg.find_basic_block(prologue) flatten_flags[prologue] = [] for ins in prologue_block.instrs: if ins.mnemonic == u'ldr' and len(ins.operands) == 2: if hasattr(ins.operands[1], 'displacement'): if ins.operands[1].base_reg.name == u'r15' and hasattr( ins.operands[1].displacement, 'immediate'): temp = ins.operands[ 1].displacement.immediate + ins.address + 8 flatten_flags[prologue].append(temp) flatten_flags[prologue] = list(set(flatten_flags[prologue])) pre_dispatcher = [] for i in cmp_blocks: if income[i] >= 2: # !!!!!!!!!!!!!!!!!!!!!!!! pre_dispatcher.append(i) print 'flatten_blocks:', [hex(addr) for addr in cmp_blocks] # 找出pre_dispatcher(有很多个入口的cmp块) main_dispatcher = [] temp_block = 0 if cfg.find_basic_block(prologue).direct_branch: temp_block = cfg.find_basic_block(prologue).direct_branch else: for branch in cfg.find_basic_block(prologue).branches: if branch[0] in cmp_blocks: temp_block = branch[0] else: main_dispatcher.append(branch[0]) if temp_block == 0: temp_block = cfg.find_basic_block(prologue).branches[0][0] while True: # if temp_block in cmp_dispatcher and temp_block == max(blocks_income, key=income.get): if temp_block in cmp_blocks: break else: main_dispatcher.append(temp_block) if cfg.find_basic_block(temp_block).direct_branch: temp_block = cfg.find_basic_block(temp_block).direct_branch else: for branch in cfg.find_basic_block(temp_block).branches: if branch[0] != temp_block: temp_block = branch[0] main_dispatcher = set(list(main_dispatcher)) # 找出直接与pre_dispatcher相连的参与块: part_involved_blocks = [] origin_has_branches = [] retn = [] graph = {} # 计算得到一个简单的cfg_dict: block_range = {} obfuscated_opcodes = {} for block in cfg.basic_blocks: # if block.address <= end: # if block.address == 0x7f8: # print('ca') if block.address not in graph: graph[block.address] = [] for i in block.branches: graph[block.address].append(i[0]) # if block.address == 0x950: # print('xsa') obfuscated_opcodes[block.address] = [] for i in block.instrs: obfuscated_opcodes[block.address].append(i.mnemonic) # if i.mnemonic_full == u'blal' or i.mnemonic_full == u'blxal': # hook_addr.append(block.address) if len(block.branches) == 0: retn.append(block.address) elif len(block.branches) == 1: # !!!!!!!!!!!!!!!!!!!!!!!!删除指向自身的基本块 if (block.branches[0][0] in pre_dispatcher or block.branches[0][0] in main_dispatcher) and \ block.address != prologue and block.address not in main_dispatcher and \ block.address not in cmp_blocks and block.branches[0][0] != block.address: if len(block.instrs) > 1: part_involved_blocks.append(block.address) elif len(block.branches) == 2: for j in range(0, 2): if (block.branches[j][0] in pre_dispatcher or block.branches[j][0] in main_dispatcher) and \ block.address != prologue and block.address not in main_dispatcher and block.address not in \ cmp_blocks and block.branches[j][0] != block.address: part_involved_blocks.append(block.address) origin_has_branches.append(block.address) # if not retn: # print filename + functionname # return -1 print 'part_involved_blocks:', [ hex(addr) for addr in part_involved_blocks ] # 找出未与flatten特征块相连的参与块: involved_blocks, involved_control_blocks = findUndirectInvlovedBlocks( cfg, graph, part_involved_blocks, cmp_blocks) rest_part = list(graph.keys()) for i in graph.keys(): # if i == 1888: # print('vew') if i == prologue or i in cmp_blocks or i in involved_blocks or i in involved_control_blocks or i in retn: rest_part.remove(i) if len(graph[i]) == 1 and graph[i][0] == i and i in rest_part: rest_part.remove(i) # for j in rest_part: # if len(graph[j]) == 1 and graph[j][0] == i: # rest_part.remove(j) temp_part = [] if len(rest_part) > 0: for i in rest_part: for k, v in zip(graph.keys(), graph.values()): # 如果父块是混淆块 if i in v and k in cmp_blocks and len(graph[i]) == 1 and graph[i][0] not in cmp_blocks and \ len(cfg.find_basic_block(i).instrs) > 1: # 加入参与块 print hex(i) temp_part.append(i) for j in temp_part: involved_blocks.append(j) if j in rest_part: rest_part.remove(j) for p in rest_part: if graph[p][0] not in cmp_blocks and len( cfg.find_basic_block(p).instrs) > 1: involved_control_blocks.append(p) # 去掉main_dispatcher for i in main_dispatcher: if i in involved_blocks: involved_blocks.remove(i) if i in involved_control_blocks: involved_control_blocks.remove(i) print '--------------------------involved_blocks--------------------------' print 'prologue:%#x' % start print 'main_dispatcher', [hex(addr) for addr in main_dispatcher] print 'pre_dispatcher: ', [hex(addr) for addr in pre_dispatcher] print 'retn: ', [hex(addr) for addr in retn] print 'involved_blocks:', [hex(addr) for addr in involved_blocks] print 'flatten_blocks:', [hex(addr) for addr in cmp_blocks] print 'flatten_flags:', flatten_flags # 找出存在分支的参与块 has_branches = check_branches(cfg, flatten_flags, involved_blocks) if prologue not in has_branches: has_branches.append(prologue) for i in origin_has_branches: has_branches.append(i) has_branches = list(set(has_branches)) for block in cfg.basic_blocks: if block.instrs[0].mnemonic_full == u'blxal' or block.instrs[0].mnemonic_full == u'blal' and block.address \ not in involved_control_blocks: jump_end_block.append(block.address) hook_addr.append(block.address) print '-------------------------check_branch_block-------------------------' print 'has_branches_blocks:', [hex(addr) for addr in has_branches] print 'involved_control_blocks:', [ hex(addr) for addr in involved_control_blocks ] print '-------------------------symbolic_execution-------------------------' relevants = list(involved_blocks) if prologue in relevants: relevants.remove(prologue) relevants_without_retn = list(relevants) for i in retn: relevants.append(i) for i in jump_end_block: relevants.append(i) # 初始化control flow的dict flow = {} for parent in relevants: flow[parent] = [] flow[prologue] = [] modify_value = None prologue_block = cfg.find_basic_block(prologue) hook = [] hook = hook + hook_addr for ins in prologue_block.instrs: if ins.mnemonic_full == u'blal' or ins.mnemonic_full == u'blxal': hook.append(ins.address) # 初始化的符号执行,将pre_dispatcher部分的工作先完成,并保存状态 init_state = init_symbolic_execution(start, pre_dispatcher, hook, loop) print '-----------------------------dse %#x-------------------------------' % prologue addr1, state1 = symbolic_execution(prologue, None, hook, relevants, loop, claripy.BVV(1, 1), True) addr2, state2 = symbolic_execution(prologue, None, hook, relevants, loop, claripy.BVV(0, 1), True) statedict = {} already = 0 if addr1 != addr2: statedict[addr1] = state1 statedict[addr2] = state2 flow[prologue].append(addr1) flow[prologue].append(addr2) if addr1 in relevants_without_retn: index = relevants_without_retn.index(addr1) temp = relevants_without_retn[already] relevants_without_retn[index] = temp relevants_without_retn[already] = addr1 already = already + 1 if addr2 in relevants_without_retn: index = relevants_without_retn.index(addr2) temp = relevants_without_retn[already] relevants_without_retn[index] = temp relevants_without_retn[already] = addr2 already = already + 1 else: statedict[addr1] = state1 flow[prologue].append(addr1) if addr1 in relevants_without_retn: index = relevants_without_retn.index(addr1) temp = relevants_without_retn[already] relevants_without_retn[index] = temp relevants_without_retn[already] = addr1 already = already + 1 a = list(set(relevants_without_retn)) # if 0x1db8 in relevants_without_retn: # print 'cdcedvwe' size = len(relevants_without_retn) for ind in range(0, size): relevant = relevants_without_retn[ind] # if relevant == 0x1cb4: # print ind print '-----------------------------dse %#x-------------------------------' % relevant block = cfg.find_basic_block(relevant) branches = False hook = [] hook = hook + hook_addr if relevant in has_branches: branches = True back_flag = True back = relevant while back_flag: for i, ins in enumerate(block.instrs): if ins.mnemonic_full == u'blal' or ins.mnemonic_full == u'blxal': hook.append(ins.address) if graph[back][0] in involved_control_blocks: back = graph[back][0] block = cfg.find_basic_block(back) # count = count + 1 else: back_flag = False if branches: if relevant in statedict.keys(): state = statedict[relevant] else: state = init_state address, state = symbolic_execution(relevant, state, hook, relevants, loop, claripy.BVV(1, 1), True) flow[relevant].append(address) statedict[address] = state if address in relevants_without_retn: index = relevants_without_retn.index(address) # if address == 0x1cb4: # print already if index >= already: temp = relevants_without_retn[already] relevants_without_retn[index] = temp relevants_without_retn[already] = address already = already + 1 elif address not in relevants_without_retn and address not in retn: print('x2') address, state = symbolic_execution(relevant, state, hook, relevants, loop, claripy.BVV(0, 1), True) flow[relevant].append(address) statedict[address] = state if address in relevants_without_retn: index = relevants_without_retn.index(address) # if address == 0x1cb4: # print already if index >= already: temp = relevants_without_retn[already] relevants_without_retn[index] = temp relevants_without_retn[already] = address already = already + 1 elif address not in relevants_without_retn and address not in retn: print('x2') already = already + 1 else: if relevant in statedict.keys(): state = statedict[relevant] else: state = init_state address, state = symbolic_execution(relevant, state, hook, relevants, loop) flow[relevant].append(address) statedict[address] = state if address in relevants_without_retn: index = relevants_without_retn.index(address) # if address == 0x1cb4: # print already if index >= already: temp = relevants_without_retn[already] relevants_without_retn[index] = temp relevants_without_retn[already] = address already = already + 1 elif address not in relevants_without_retn and address not in retn: print('x3') already = already + 1 # 该部分确认初始块是否有分支 # 逻辑:prologue -> 保存state —> 第1个relevant块 —> 保存state -> 第2个relevant块 # |->是否有分支?—> 保存state -> 第2个relevant块 # statedict = {} # if addr1 != addr2: # statedict[addr1] = state1 # statedict[addr2] = state2 # flow[prologue].append(addr1) # flow[prologue].append(addr2) # else: # statedict[addr1] = state1 # flow[prologue].append(addr1) # # relevants_without_retn.sort() # for relevant in relevants_without_retn: # print '-----------------------------dse %#x-------------------------------' % relevant # block = cfg.find_basic_block(relevant) # branches = False # if block.address == 0x8c0: # print('xsxs') # hook = [] # hook = hook + hook_addr # # if relevant == 0x9dc: # # print('x') # if relevant in has_branches: # branches = True # back_flag = True # back = relevant # while back_flag: # for i, ins in enumerate(block.instrs): # if ins.mnemonic_full == u'blal' or ins.mnemonic_full == u'blxal': # hook.append(ins.address) # # if graph[back][0] in involved_control_blocks: # back = graph[back][0] # block = cfg.find_basic_block(back) # # count = count + 1 # else: # back_flag = False # # if branches: # if relevant in statedict.keys(): # state = statedict[relevant] # else: # state = init_state # address, state = symbolic_execution(relevant, state, hook, relevants, loop, claripy.BVV(1, 1), # True) # flow[relevant].append(address) # statedict[address] = state # address, state = symbolic_execution(relevant, state, hook, relevants, loop, claripy.BVV(0, 1), # True) # flow[relevant].append(address) # statedict[address] = state # else: # if relevant in statedict.keys(): # state = statedict[relevant] # else: # state = init_state # address, state = symbolic_execution(relevant, state, hook, relevants, loop) # flow[relevant].append(address) # statedict[address] = state print '-----------------------------flow-------------------------------' flow1 = dict(flow) for (k, v) in flow1.items(): flow1[k] = list(set(flow1[k])) print '%#x:' % k, [hex(child) for child in set(v)] print '-----------------------------GET CFG-------------------------------' # origin_filename = "/Users/mark/Desktop/djbhash-origin" # origin_start = 0x628 # G_origin = nx.DiGraph() # origin_flow = {} # origin = BARF(origin_filename) # origin_cfg = origin.recover_cfg(start=origin_start) # for block in origin_cfg.basic_blocks: # if hex(block.address) not in origin_flow: # origin_flow[hex(block.address)] = [] # for i in block.branches: # origin_flow[hex(block.address)].append(hex(i[0])) # # for i, j in origin_flow.items(): # origin_flow[i] = [] # for k in j: # origin_flow[i].append(k) # # # G_obfuscated.add_nodes_from(obfuscated_flow.keys()) # ori = angr.Project(origin_filename, load_options={'auto_load_libs': False, 'main_opts': {'custom_base_addr': 0}}) # for i in origin_flow.keys(): # block = origin_cfg.find_basic_block(int(i, 16)) # irsb = ori.factory.block(int(i, 16)).vex # ir = irsb.__str__() # size = len(block.instrs) # while size>0: # if irsb.instructions < size and irsb.jumpkind == "Ijk_Boring": # b_next = int(irsb.next.con.value) + 4 # irsb = b.factory.block(b_next).vex # ir = ir + irsb.__str__() # size = size - irsb.instructions # elif irsb.instructions < size and irsb.jumpkind == "Ijk_Call": # b_next = int(irsb.next.con.value) + 4 # irsb = b.factory.block(b_next).vex # ir = ir + irsb.__str__() # size = size - irsb.instructions # else: # break # G_origin.add_node(i, opcode=ir) # for parent in origin_flow.keys(): # origin_flow[parent] = list(set(origin_flow[parent])) # for child in origin_flow[parent]: # G_origin.add_edge(parent, child) # path = cfg_path + str(origin_start) + "_origin.dot" # nx.drawing.nx_agraph.write_dot(G_origin, path) G_obfuscated = nx.DiGraph() obfuscated_flow = {} obfuscated = BARF(filename) obfuscated_cfg = obfuscated.recover_cfg(start=start) for block in obfuscated_cfg.basic_blocks: if hex(block.address) not in obfuscated_flow: obfuscated_flow[hex(block.address)] = [] for i in block.branches: obfuscated_flow[hex(block.address)].append(hex(i[0])) for i, j in obfuscated_flow.items(): obfuscated_flow[i] = [] for k in j: obfuscated_flow[i].append(k) # G_obfuscated.add_nodes_from(obfuscated_flow.keys()) for i in obfuscated_flow.keys(): # irsb = b.factory.block(int(i)).vex G_obfuscated.add_node(i, opcode=obfuscated_opcodes[int(i, 16)]) for parent in obfuscated_flow.keys(): obfuscated_flow[parent] = list(set(obfuscated_flow[parent])) for child in obfuscated_flow[parent]: G_obfuscated.add_edge(parent, child) path = cfg_path + str(start) + "_obfuscated.dot" nx.drawing.nx_agraph.write_dot(G_obfuscated, path) G_recover = nx.DiGraph() flow_hex = {} for i, j in flow.items(): flow_hex[hex(i)] = [] for k in j: flow_hex[hex(i)].append(hex(k)) for i in flow_hex.keys(): block = obfuscated_cfg.find_basic_block(int(i, 16)) size = len(block.instrs) irsb = b.factory.block(int(i, 16)).vex ir = irsb.__str__() while size > 0: if irsb.instructions < size and irsb.jumpkind == "Ijk_Boring": b_next = int(irsb.next.con.value) + 4 irsb = b.factory.block(b_next).vex ir = ir + irsb.__str__() size = size - irsb.instructions elif irsb.instructions < size and irsb.jumpkind == "Ijk_Call": b_next = int(irsb.next.con.value) + 4 irsb = b.factory.block(b_next).vex ir = ir + irsb.__str__() size = size - irsb.instructions else: break # if irsb.instructions < size and irsb.jumpkind == "Ijk_Boring": # b_next = irsb.next + 4 # irsb = b.factory.block(b_next).vex # irsb.pp() # size = size - irsb.instructions # if irsb.instructions < size and irsb.jumpkind == "Ijk_Call": # b_next = int(irsb.next) + 4 # irsb = b.factory.block(b_next).vex # irsb.pp() # size = size - irsb.instructions # if irsb.instructions < size and irsb.jumpkind == "Ijk_Call": # b_next = int(irsb.next) + 4 # irsb = b.factory.block(b_next).vex # irsb.pp() # size = size - irsb.instructions G_recover.add_node(i, opcode=ir) # G_recover.add_nodes_from(flow_hex.keys()) for parent in flow_hex.keys(): flow_hex[parent] = list(set(flow_hex[parent])) for child in flow_hex[parent]: if child.endswith('L'): child = child.replace('L', '') if child in G_recover.nodes: G_recover.add_edge(parent, child) else: if len(retn) >= 1: G_recover.add_edge(parent, hex(retn[0])) else: G_recover.add_node(child, opcode=obfuscated_opcodes[int( child, 16)]) G_recover.add_edge(parent, child) path = cfg_path + str(start) + "_recovered.dot" nx.drawing.nx_agraph.write_dot(G_recover, path) else: print('skip %s' % filename.split('/')[-2])