'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)
#! /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 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)
filename = sys.argv[1] start = int(sys.argv[2], 16) barf = BARF(filename) base_addr = barf.binary.entry_point >> 12 << 12 print "snowtest="+str(barf.binary) print 'snowtest--base_addr%#x' % base_addr b = angr.Project(filename, load_options={ 'auto_load_libs': False, 'main_opts': {'custom_base_addr': 0}}) cfg = barf.recover_cfg(ea_start=start) blocks = cfg.basic_blocks #第一步:找出6大块,可以用静态分析得到 #1.序言:序言为函数开始地址 prologue = start #2.主分发器:序言的后继为主分发器(也就是序言指向的第一个块) main_dispatcher = cfg.find_basic_block(prologue).direct_branch #3.预处理器:后继为主分器的块位预处理器(也就是后面一个代码块是主分器的)
#! /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)
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) # # Recover CFG # print("[+] Recovering program CFG...")
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 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)
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 from barf.barf import BARF if __name__ == "__main__": # # 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)
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)
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])