IDA遇到hariki等等各种工具的混同,字符串被加密,难以看出加密之后的字符串.如何失去该字符串.能够试着尝试unicorn模仿执行脚本.
1.用pip装置unicorn,留神pip版本必须是2.x+版本.如果没有请参照:pip装置教程装置.pip install unicorn
2.依据unicorn,编写python脚本,这里在网上找了一个脚本:
#!/usr/bin/env python2# -*- coding: utf-8 -*-# @Author: smartdone# @Date: 2019-07-01 11:00import idaapiimport idautilsimport idcfrom Simulator import *#from capstone import *sys.path.append('/usr/local/lib/python2.7/site-packages/')addr = 0x100075B00PatchDword(addr,0)print(addr, 0)sim = Simulator()sim.sp = 4sim.arch = UC_ARCH_ARM64sim.mode = UC_MODE_ARMfor func in idautils.Functions(): func_name = idc.GetFunctionName(func) func_data = idaapi.get_func(func) start = func_data.start_ea end = func_data.end_ea# print(func_name, hex(start), hex(end))# if "ijm_obf_fun_globalstub_" in func_name : print(func_name, hex(start), hex(end)) start = 0x0000000100006AC8 end = 0x0000000100006B70 sim.emu_start(start, end) break# start=0x00000000002B8B7C# end=0x00000000002B9BA0 sim.patch_segment('data')for seg in sim.segments: if "data" in seg['name']: # 把data段全副undefined print("MakeUnknown %s" % seg['name']) idc.MakeUnknown(seg['start'], seg['end'] - seg['start'], idaapi.DELIT_DELNAMES) # 调用ida从新解析data段 print("analyze area: 0x%x - 0x%x" % (seg['start'], seg['end'])) idaapi.analyze_area(seg['start'], seg['end']) # idaapi.clear_strlist() # idaapi.build_strlist()# 查问string的穿插援用,在援用地位增加备注s = idautils.Strings(False)s.setup()for i, str_info in enumerate(s): if str_info: # print("%x: len=%d index=%d-> '%s'" % (str_info.ea, str_info.length, i, str(str_info))) str_cont = str(str_info) refs = idautils.DataRefsTo(str_info.ea) for ref in refs: idc.MakeComm(ref, str_cont)
通过管制脚本里的 start和end地址 start = 0x0000000100006AC8、end = 0x0000000100006B70,就能够模仿执行对应的地址的代码,最终出现成果比照图:
**解密前**
**解密后**
就失去字符串的名字
留神:如果汇编代码里有if判断,如果不满足条件,if块里的汇编代码不会执行,会导致if后的代码都不执行,所以要找到if块里的代码独自执行.
以上python代码依赖于Simulator脚本,脚本源码如下:
#!/usr/bin/env python2# -*- coding: utf-8 -*-# @Author: smartdone# @Date: 2019-07-01 11:00import idaapiimport idcimport idautilsimport syssys.path.append('/usr/local/lib/python2.7/site-packages/')from unicorn import *from unicorn.x86_const import *from unicorn.arm_const import *from unicorn.arm64_const import *IMAGE_BASE = idaapi.get_imagebase()DEBUG = Truedef hook_code(uc, address, size, user_data): instruction = uc.mem_read(address, size) if instruction == b'\xc3': uc.emu_stop() if address == 0: uc.emu_stop() if address != 0 and address != IMAGE_BASE: idc.set_color(address, idc.CIC_ITEM, 0xFFB6C1) if DEBUG: _code = idc.GetDisasm(address) print("0x%016x \t%s" % (address, _code))class Simulator(object): def __init__(self): self.segments = [] self.mem_map = [] self.ph_flag = None self.ph_id = None self.arch = None self.mode = None self.sp = None self.stack_base = 0 self.stack_length = 1024 * 1024 * 2 self.get_segments() self.get_arch() self.get_unicorn_mem_pages() def get_segments(self): if len(self.segments) == 0: for seg in idautils.Segments(): name = idc.SegName(seg) start = idc.SegStart(seg) end = idc.SegEnd(seg) d = idc.GetManyBytes(start, end - start) d = [ord(item) for item in list(d)] seg_data = {"name": name, "start": start, "end": end, "data": d} self.segments.append(seg_data) return self.segments def get_arch(self): self.ph_id = idaapi.ph.id self.ph_flag = idaapi.ph.flag if self.ph_id == idaapi.PLFM_386 and self.ph_flag & idaapi.PR_USE64: self.arch = UC_ARCH_X86 self.mode = UC_MODE_64 self.sp = UC_X86_REG_RSP elif self.ph_id == idaapi.PLFM_386 and self.ph_flag & idaapi.PR_USE32: self.arch = UC_ARCH_X86 self.mode = UC_MODE_32 self.sp = UC_X86_REG_RSP elif self.ph_id == idaapi.PLFM_ARM and self.ph_flag & idaapi.PR_USE32: self.arch = UC_ARCH_ARM self.mode = UC_MODE_ARM self.sp = UC_ARM_REG_SP elif self.ph_id == idaapi.PLFM_ARM and self.ph_flag & idaapi.PR_USE64: self.arch = UC_ARCH_ARM64 self.mode = UC_MODE_ARM self.sp = UC_ARM64_REG_SP def is_thumb_ea(self, ea): if self.ph_id == idaapi.PLFM_ARM and not self.ph_flag & idaapi.PR_USE64: if idaapi.IDA_SDK_VERSION >= 700: try: t = idaapi.get_sreg(ea, 20) except: t = idaapi.get_sreg(ea, "T") else: t = idaapi.get_segreg(ea, 20) return t is not idaapi.BADSEL and t is not 0 else: return False def emu_start(self, func_start, func_end): if self.arch == UC_ARCH_ARM: if self.is_thumb_ea(func_start): print("thumb mode") self.mode = UC_MODE_THUMB mu = Uc(self.arch, self.mode) for item in self.mem_map: Simulator.map_memory(mu, item['start'], item['length']) # 给栈分配内存 Simulator.map_memory(mu, self.stack_base, self.stack_length) # 写入数据 for item in self.segments: Simulator.write_memory(mu, item['start'], item['data']) # 配置寄存器 mu.reg_write(self.sp, self.stack_base + 1024 * 1024) mu.hook_add(UC_HOOK_CODE, hook_code) try: # 开始执行 if self.mode == UC_MODE_THUMB: mu.emu_start(func_start + 1, func_end) else: mu.emu_start(func_start, func_end) except Exception as e: print("Err: %s. Execution function failed.(The function address is 0x%x)" % (e, func_start)) # 读取数据 for item in self.segments: _data = Simulator.read_memory(mu, item['start'], item['end']) self.replace_data(item['start'], _data) # unmap memory for item in self.mem_map: Simulator.unmap_memory(mu, item['start'], item['length']) Simulator.unmap_memory(mu, self.stack_base, self.stack_length) def replace_data(self, start, data): for i in range(len(self.segments)): if self.segments[i]['start'] == start: self.segments[i]['data'] = data @staticmethod def write_memory(mu, start, data): if isinstance(data, list): data = bytearray(data) mu.mem_write(start, bytes(data)) @staticmethod def read_memory(mu, start, end): _length = end - start _data = mu.mem_read(start, _length) return bytearray(_data) @staticmethod def map_memory(mu, start, _length): mu.mem_map(start, _length) print("map memory: offset 0x%x, size: 0x%x" % (start, _length)) @staticmethod def unmap_memory(mu, start, _length): mu.mem_unmap(start, _length) print("unmap memory: offset 0x%x, size: 0x%x" % (start, _length)) @staticmethod def get_base_and_len(base, length): _base = base - (base % (1024 * 1024)) _length = (length / (1024 * 1024) + 1) * 1024 * 1024 return _base, _length def get_unicorn_mem_pages(self): if len(self.segments) == 0: return None if len(self.mem_map) == 0: seg = None pages = [] for item in self.segments: if not seg: seg = {'start': item['start'], 'end': item['end']} else: if item['start'] - seg['end'] > (1024 * 1024 * 2): pages.append(seg) seg = {'start': item['start'], 'end': item['end']} else: seg['end'] = item['end'] pages.append(seg) for item in pages: start, length = Simulator.get_base_and_len(item['start'], item['end'] - item['start']) self.mem_map.append({"start": start, "length": length}) for item in self.mem_map: if self.stack_base < item['start'] + item['length']: self.stack_base = item['start'] + item['length'] return self.mem_map def patch_segment(self, seg_name): for seg in self.segments: if seg_name in seg['name']: print("patch %s: 0x%x - 0x%x" %(seg['name'], seg['start'], seg['end'])) for i in range(len(seg['data'])): idc.patch_byte(seg['start'] + i, seg['data'][i])