Пример #1
0
#! /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)
Пример #2
0
#! /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
Пример #3
0
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))
Пример #4
0
#! /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))
Пример #5
0
     '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************************'
Пример #6
0
#! /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)
Пример #7
0
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'))
Пример #8
0
#! /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)
Пример #9
0
#! /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
Пример #10
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
Пример #11
0
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
    #
Пример #12
0
#! /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]
Пример #13
0
        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])
Пример #14
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:
        # 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)
Пример #15
0
#! /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)
Пример #16
0
#! /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
Пример #17
0
#! /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)
Пример #18
0
#! /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]
Пример #19
0
#! /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)
Пример #20
0
#! /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:
Пример #22
0
#! /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)
Пример #23
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/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))
Пример #24
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/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:
Пример #25
0
#! /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)
Пример #26
0
#! /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)
Пример #27
0
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()
Пример #28
0
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))
Пример #29
0
#! /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)
Пример #30
0
#! /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
Пример #31
0
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])