Exemple #1
0
def TstBarf(file_path):
	barf = BARF(file_path)

	# Recover CFG.

	sys.stdout.write("dir=%s\n"%str(dir(barf)))
	cfg = barf.recover_cfg()
	basna = os.path.basename(file_path)

	# Save CFG to a .dot file.
	cfg.save(basna)
Exemple #2
0
def De_IS(filename, start):
    # sys.argv = ["test.py", "/Users/mark/Desktop/de_obfuscator/IS/New-test/total/inssub", "0x694"]
    # if len(sys.argv) != 3:
    #     print 'Usage: python DeInsSub.py filename function_address(hex)'
    #     exit(0)

    # filename = sys.argv[1]
    start = int(start, 16)
    filename = filename
    # start = int(start, 16)
    barf = BARF(filename)
    base_addr = barf.binary.entry_point >> 12 << 12

    cfg = barf.recover_cfg(start)
    blocks = cfg.basic_blocks

    print('The function has %d blocks. ' % len(blocks))

    origin = open(filename, 'rb')
    data = list(origin.read())

    for block in blocks:
        opposite = []
        #查找所用的MOV指令,然后记录所用寄存器值相反的对
        # for ins in block.instrs:
        #     if ins.mnemonic_full.startswith(u'mvn'):
        #         if ins.operands[0].name not in opposite:
        #             opposite[ins.operands[0].name] = ins.operands[1].name

        block_size = len(block.instrs)
        ADDHex, ADDnop = check_add(block, block_size)
        data = fix_substitution(data, ADDHex, ADDnop, base_addr)
        SUBHex, SUBnop = check_sub(block, block_size)
        data = fix_substitution(data, SUBHex, SUBnop, base_addr)
        XORHex, XORnop = check_xor(block, block_size)
        data = fix_substitution(data, XORHex, XORnop, base_addr)
        ANDHex, ANDnop = check_and(block, block_size)
        data = fix_substitution(data, ANDHex, ANDnop, base_addr)
        ORHex, ORnop = check_or(block, block_size)
        data = fix_substitution(data, ORHex, ORnop, base_addr)

    origin.close()
    # recovery = open(filename + '_recovered', 'wb')
    path = sys.argv[3]
    if not os.path.exists(path + filename.split('/')[-2] + '/'):
        os.mkdir(path + filename.split('/')[-2] + '/')
    recovery = open(
        path + filename.split('/')[-2] + '/' + filename.split('/')[-1] +
        '_recovered', 'wb')

    recovery.write(''.join(data))
    recovery.close()
    print 'Successful! The recovered file: %s' % (filename + '_recovered')
    # 8048401:       75 19                   jne    804841c <main+0x2f>
    # 8048403:       81 7d f8 48 47 46 45    cmp    DWORD PTR [ebp-0x8],0x45464748
    # 804840a:       75 10                   jne    804841c <main+0x2f>
    # 804840c:       81 7d fc ef cd ab 00    cmp    DWORD PTR [ebp-0x4],0xabcdef
    # 8048413:       75 07                   jne    804841c <main+0x2f>
    # 8048415:       c7 45 f0 00 00 00 00    mov    DWORD PTR [ebp-0x10],0x0
    # 804841c:       8b 45 f0                mov    eax,DWORD PTR [ebp-0x10]
    # 804841f:       c9                      leave
    # 8048420:       c3                      ret

    start_addr = 0x80483ed
    end_addr = 0x8048420

    print("[+] Recovering function CFG...")

    cfg = barf.recover_cfg(start_addr, end_addr)

    print("[+] Checking path satisfiability...")

    # Preconditions: set stack
    # Note: this isn't strictly necessary but it helps reduce the time it
    # takes the solver find a solution.
    esp = barf.code_analyzer.get_register_expr("esp", mode="pre")

    barf.code_analyzer.add_constraint(esp == 0xffffceec)

    # Traverse paths and check satisfiability
    for bb_path in cfg.all_simple_bb_paths(start_addr, end_addr):
        print("[+] Path: {0}".format(" -> ".join(
            [hex(bb.address) for bb in bb_path])))
Exemple #4
0
def De_BCF(filename, start):
    # sys.argv = ["test.py", '/Users/mark/Desktop/de_obfuscator/benchmark/binary/pyramid-bcf-sub', "0x72c"]
    # start = int(sys.argv[2], 16)
    start = int(start, 16)
    # filename = sys.argv[1]
    filename = filename
    barf = BARF(filename)

    base_addr = barf.binary.entry_point >> 12 << 12
    cfg = barf.recover_cfg(start)
    cmp_blocks, opaque_predicate_blocks = get_predicate_blocks(cfg)
    print(cmp_blocks)
    print(opaque_predicate_blocks)

    blocks = cfg.basic_blocks
    fixhex = []
    fixaddr = []

    # for each block
    for block in blocks:
        command = ''
        # compare blocks(0 for beq(taken), 1 for bne(not-taken))
        if hex(block.address) in cmp_blocks:
            if cmp_blocks[hex(block.address)] == 0:
                for branch in block.branches:
                    if branch[1] == 'taken':
                        off_set = hex(branch[0] - block.instrs[-1].address)
                        command = 'b    #' + off_set

            elif cmp_blocks[hex(block.address)] == 1:
                for branch in block.branches:
                    if branch[1] == 'not-taken':
                        off_set = hex(branch[0] - block.instrs[-1].address)
                        command = 'b    #' + off_set

        # opaque predicate blocks(0 for beq(taken), 1,2 for bne(not-taken))
        if hex(block.address) in opaque_predicate_blocks:
            if opaque_predicate_blocks[hex(block.address)] == 0:
                for branch in block.branches:
                    if branch[1] == 'taken':
                        off_set = hex(branch[0] - block.instrs[-1].address)
                        command = 'b    #' + off_set

            elif opaque_predicate_blocks[hex(block.address)] == 1 or \
                    opaque_predicate_blocks[hex(block.address)] == 2:
                for branch in block.branches:
                    if branch[1] == 'not-taken':
                        off_set = hex(branch[0] - block.instrs[-1].address)
                        command = 'b    #' + off_set

        # change the conditional jump before opaque_predicate_blocks to unconditional jump
        # (force the flow through opaque_predicate_blocks)
        for branch in block.branches:
            if hex(branch[0]) in opaque_predicate_blocks and block.instrs[
                    -1].mnemonic_full == u'blt':
                off_set = hex(branch[0] - block.instrs[-1].address)
                command = 'b    #' + off_set

        # if command.startswith('b'):
        # print command
        if command != '':
            bcommand = bytes(command)
            hexcommand = ''

            try:
                # Initialize engine in X86-32bit mode
                ks = Ks(KS_ARCH_ARM, KS_MODE_LITTLE_ENDIAN)
                encoding, count = ks.asm(bcommand)
                for i in encoding:
                    hexcommand = hexcommand + hex(int(i)) + ','
                fixaddr.append(block.instrs[-1].address)
                fixhex.append(hexcommand)
            except KsError as e:
                print("ERROR: %s" % e)
        # elif command.startswith('negative,'):
        #     hexcommand = ''
        #     off_set = command.split(',')[-1]
        #     x = int(off_set, 16) - 8
        #     x &= 0x3FFFFFF
        #     x >>= 2
        #     tmp = hex(0xEB000000 + x)
        #     for i in range(len(tmp), 2, -2):
        #         hexcommand = hexcommand + '0x' + tmp[i-2:i] + ','
        #     fixaddr.append(block.instrs[-1].address)
        #     fixhex.append(hexcommand)

    origin = open(filename, 'rb')
    data = list(origin.read())

    print fixaddr, fixhex
    data = fix_instruction_substitution(data, fixhex, fixaddr, base_addr)
    origin.close()
    path = sys.argv[3]
    recovery = open(
        path + filename.split('/')[-2] + '/' + filename.split('/')[-1] +
        '_recovered', 'wb')
    recovery.write(''.join(data))
    recovery.close()
    print 'Successful! The recovered file: %s' % (filename + '_recovered')
    # 8048403:       81 7d f8 48 47 46 45    cmp    DWORD PTR [ebp-0x8],0x45464748
    # 804840a:       75 10                   jne    804841c <main+0x2f>
    # 804840c:       81 7d fc ef cd ab 00    cmp    DWORD PTR [ebp-0x4],0xabcdef
    # 8048413:       75 07                   jne    804841c <main+0x2f>
    # 8048415:       c7 45 f0 00 00 00 00    mov    DWORD PTR [ebp-0x10],0x0
    # 804841c:       8b 45 f0                mov    eax,DWORD PTR [ebp-0x10]
    # 804841f:       c9                      leave
    # 8048420:       c3                      ret

    start_addr = 0x80483ed
    end_addr = 0x8048420

    # Recover control flow graph
    print("[+] Recovering function CFG...")

    cfg = barf.recover_cfg(start_addr, end_addr)

    # Set stack
    esp = barf.code_analyzer.get_register_expr("esp")

    barf.code_analyzer.set_precondition(esp == 0xffffceec)

    # Traverse paths and check satisfiability
    print("Checking path satisfiability...")

    for bb_path in cfg.all_simple_bb_paths(start_addr, end_addr):
        path_addrs = [hex(bb.address) for bb in bb_path]

        print("[+] Path : {0}".format(" -> ".join(path_addrs)))

        is_sat = barf.code_analyzer.check_path_satisfiability(bb_path, start_addr)
Exemple #6
0
        data[start + i] = jmp_offset[i]

if __name__ == '__main__':
    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'}
    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************************'
    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)