def decrypt_all_strings(decrypt_string_func_ea): global STRING_DICTIONARY for ref in idautils.CodeRefsTo(decrypt_string_func_ea, 1): # this function can be better. I hate it rn but oh well prev_instruction_ea = 0x472DAC if ref == translate_ea( 0x1db3) else idc.prev_head(ref) if idc.print_insn_mnem( prev_instruction_ea) == 'push' or idc.print_insn_mnem( prev_instruction_ea) == 'lea': encrypted_blob_ea = idc.get_operand_value( prev_instruction_ea, 1) if ref == translate_ea(0x1db3) else idc.get_operand_value( prev_instruction_ea, 0) length = int.from_bytes(idaapi.get_bytes(encrypted_blob_ea - 4, 4), 'little') #print(hex(prev_instruction_ea) + " and " + hex(encrypted_blob_ea) + " and " + hex(length)) encrypted_blob = [ x for x in idaapi.get_bytes(encrypted_blob_ea, length) ] encrypted_blob = decrypt_config(encrypted_blob, length) string = '' for each in encrypted_blob: if each != 0: string += chr(each) STRING_DICTIONARY[translate_ea_to_offset( encrypted_blob_ea)] = string return
def formbook_decrypt_c2c_uri(): fb_decrypt = FormBookDecryption() encbuf6_addr = 0x0041AAA4 # fake prologue encbuf7_addr = 0x0041AE45 # fake prologue encbuf8_addr = 0x0041AF4C # fake prologue encbuf9_addr = 0x00419A83 # fake prologue encbuf7_s0 = idaapi.get_bytes(encbuf7_addr, 0x14 * 2) encbuf6_s0 = idaapi.get_bytes(encbuf6_addr, 0x14 * 2) encbuf8_s0 = idaapi.get_bytes(encbuf8_addr, 0x139 * 2) encbuf9_s0 = idaapi.get_bytes(encbuf9_addr, 0x9d3 * 2) rc4_key_two = fb_decrypt.decrypt_func1(encbuf6_s0, 0x14) rc4_key_one = fb_decrypt.decrypt_func1(encbuf7_s0, 0x14) encbuf8_s1 = fb_decrypt.decrypt_func1(encbuf8_s0, 0x139) encbuf9_s1 = fb_decrypt.decrypt_func1(encbuf9_s0, 0x9d3) rc4_key = formbook_compute_sha1(encbuf9_s1) encbuf8_s2 = fb_decrypt.decrypt_func2(encbuf8_s1, rc4_key) encrypted_c2c_uri = encbuf8_s2[220:220+44] # 44 is the length of the C&C URI encrypted_c2c_uri = fb_decrypt.decrypt_func2(encrypted_c2c_uri, rc4_key_two) c2c_uri = fb_decrypt.decrypt_func2(encrypted_c2c_uri, rc4_key_one) print('C&C URI: {:s}'.format(c2c_uri))
def get_FULL_CONFIG(): global config_extract_ea, FULL_CONFIG # get FULL_CONFIG size curr_ea = config_extract_ea stop_bytes = 0 # this should be 0xDEADBEEF FULL_CONFIG_ea = 0 while True: next_instruction_ea = idc.next_head(curr_ea) if idc.print_insn_mnem(next_instruction_ea) == 'cmp': stop_bytes = idc.get_operand_value(next_instruction_ea, 1) break elif idc.print_insn_mnem(next_instruction_ea) == 'lea': FULL_CONFIG_ea = idc.get_operand_value(next_instruction_ea, 1) curr_ea = next_instruction_ea config_length = 0 while True: if int.from_bytes(idaapi.get_bytes(FULL_CONFIG_ea + config_length, 4), 'little') == stop_bytes: break config_length += 1 FULL_CONFIG = [ each_byte for each_byte in idaapi.get_bytes(FULL_CONFIG_ea, config_length) ] FULL_CONFIG = decrypt_config(FULL_CONFIG, config_length)
def formbook_decrypt_hashes_and_strings(): fb_decrypt = FormBookDecryption() # PE base address: 0x00400000 encbuf1_addr = 0x0041AF4C # fake prologue encbuf2_addr = 0x0041B160 # fake prologue encbuf3_addr = 0x0041AAA4 # fake prologue encbuf4_addr = 0x00419A83 # fake prologue # decrypt_func1 input length buffer is unknown # but is always >= output length encbuf1_s0 = idaapi.get_bytes(encbuf1_addr, 0x139 * 2) encbuf2_s0 = idaapi.get_bytes(encbuf2_addr, 0x35C * 2) encbuf3_s0 = idaapi.get_bytes(encbuf3_addr, 0x14 * 2) encbuf4_s0 = idaapi.get_bytes(encbuf4_addr, 0x9d3 * 2) encbuf1_s1 = fb_decrypt.decrypt_func1(encbuf1_s0, 0x139) encbuf2_s1 = fb_decrypt.decrypt_func1(encbuf2_s0, 0x35c) encbuf3_s1 = fb_decrypt.decrypt_func1(encbuf3_s0, 0x14) encrypted_strings = fb_decrypt.decrypt_func1(encbuf4_s0, 0x9d3) rc4_key_one = formbook_compute_sha1(encbuf1_s1) rc4_key_two = formbook_compute_sha1(encbuf3_s1) encbuf2_s2 = fb_decrypt.decrypt_func2(encbuf2_s1, rc4_key_one) encrypted_hashes_array = fb_decrypt.decrypt_func2(encbuf2_s2, rc4_key_two) rc4_key_pre_final = formbook_compute_sha1(encrypted_hashes_array) rc4_key_final = fb_decrypt.decrypt_func2(encbuf3_s1, rc4_key_pre_final) formbook_decrypt_hashes(fb_decrypt, rc4_key_final, encrypted_hashes_array) formbook_decrypt_strings(fb_decrypt, rc4_key_final, encrypted_strings)
def getStructArg(struct_addr, arg, arg_size=8, size=32): print_bytes = idaapi.get_bytes(struct_addr+arg*arg_size, arg_size) arg_value = px_qw(struct_addr+arg*arg_size, False) print("Struct Base: 0x%08x -> Arg[%d]: 0x%08x -> Value: 0x%08x" % (struct_addr, arg, struct_addr+arg*arg_size, arg_value)) print_bytes = idaapi.get_bytes(arg_value, size) dump = [] for b in print_bytes: dump.append(ord(b)) hexdump_raw(arg_value, dump)
def decode_callback(eh, address, argv, userData): encoded_str_ea = eh.getRegVal('edx') ENCRYPTED_STRING_BUFFER = argv[0] key_offset = argv[1] key_length = argv[2] data_length = argv[3] RC4_key = idaapi.get_bytes(ENCRYPTED_STRING_BUFFER + key_offset, key_length) RC4_encrypted_buffer = idaapi.get_bytes( ENCRYPTED_STRING_BUFFER + key_offset + key_length, data_length) decrypted_str = RC4_crypt(RC4_key, RC4_encrypted_buffer) print(hex(address) + ' ' + decrypted_str) eh.analysisHelper.setComment(address, decrypted_str, False)
def get_encrypted_lib_table(): LoadLibraryA_ea = idc.get_name_ea_simple("LoadLibraryA") LoadLibraryA_ref = None if LoadLibraryA_ea != idaapi.BADADDR: for ref in idautils.CodeRefsTo(LoadLibraryA_ea, 1): LoadLibraryA_ref = ref break ENCRYPTED_LIB_TABLE_instruction_ea = LoadLibraryA_ref - 22 API_TABLE_start_instruction_ea = LoadLibraryA_ref - 16 if 'lea' not in idc.GetDisasm( ENCRYPTED_LIB_TABLE_instruction_ea) or 'lea' not in idc.GetDisasm( API_TABLE_start_instruction_ea): print(hex(ENCRYPTED_LIB_TABLE_instruction_ea)) print('Parsing fails...') return ENCRYPTED_LIB_TABLE_ea = idc.get_operand_value( ENCRYPTED_LIB_TABLE_instruction_ea, 1) ENCRYPTED_LIB_TABLE_ea -= 4 global API_TABLE_start_ea API_TABLE_start_ea = idc.get_operand_value(API_TABLE_start_instruction_ea, 1) global ENCRYPTED_LIB_TABLE # 3694 bytes ENCRYPTED_LIB_TABLE = idaapi.get_bytes(ENCRYPTED_LIB_TABLE_ea, 3694)
def get_segments_memory(self): memory = b"" step_size = self.entropy_cfg['step_size'] segments = OrderedDict() for ea in filter(self.segment_filter, idautils.Segments()): seg_name = idc.get_segm_name(ea) segm = idaapi.get_segm_by_name(seg_name) data = idaapi.get_bytes(segm.start_ea, segm.size()) assert len(data) == segm.size() start_offset = len(memory) end_offset = (start_offset+len(data)) seg_info = { 'segm': segm, 'entropy': entropy(data), 'offsets': [ start_offset , end_offset ], 'chart_offsets': [ start_offset // step_size, end_offset // step_size ] } segments[seg_name] = seg_info memory += data self.data = memory self.data_size = len(memory) self.segments = segments
def formbook_patch_encrypted_bytecode(): text_segm = ida_segment.get_segm_by_name('.text') if not text_segm: return idaapi.BADADDR seg_start = text_segm.startEA seg_end = text_segm.endEA fb_decrypt = FormBookDecryption() rc4_key = "faddefad156c45629c95d5f429363b0653ad5c1d".decode('hex') # same as rc4_final from formbook_decrypt_hashes_and_strings() for i in [(0x40, 0x48), (0x41, 0x49), (0x42, 0x4a), (0x43, 0x4b), (0x44, 0x4c)]: egg_pattern = ''.join('{:02x} '.format(x) for x in [i[0], 0x90, 0x90, 0x90, i[1]]) encrypted_start = idaapi.find_binary(seg_start, seg_end, egg_pattern, 16, idaapi.SEARCH_DOWN) if encrypted_start != idaapi.BADADDR: encrypted_end = idaapi.find_binary(encrypted_start + 5, seg_end, "90 90 90 90", 16, idaapi.SEARCH_DOWN) if encrypted_end != idaapi.BADADDR: encrypted_start += 5 patch_length = encrypted_end - encrypted_start if idaapi.visit_patched_bytes(encrypted_start, encrypted_end, callback_on_patched_bytes) == 0: encrypted_buff = idaapi.get_bytes(encrypted_start, patch_length) decrypted_buff = fb_decrypt.decrypt_func2(encrypted_buff, rc4_key) print('Patching encrypted bytecode at 0x{:x} ({:d} bytes)'.format(encrypted_start, patch_length)) idaapi.patch_many_bytes(encrypted_start, decrypted_buff) else: print('Encrypted bytecode at 0x{:x} ({:d} bytes) is already patched'.format(encrypted_start, patch_length))
def parse_func(pfn): try: hf = idaapi.hexrays_failure_t() cfunc = idaapi.decompile(pfn.start_ea, hf) mbr = idaapi.mba_ranges_t(pfn) mba = idaapi.gen_microcode( mbr, hf, None, idaapi.DECOMP_NO_WAIT | idaapi.DECOMP_NO_CACHE, idaapi.MMAT_GLBOPT3 ) except Exception: return if mba is None: return G = Graph() ctree_state, ctree_expr, ctree_int, ctree_str, micro_int = [], [], [], [], [] # node level for i in range(mba.qty): mb = mba.get_mblock(i) minsn = mb.head blk = [] while minsn: ins = parse_minsn(minsn, micro_int) blk.append(ins) minsn = minsn.next vp = idaapi.qstring_printer_t(None, True) mb._print(vp) G.add_node(mb.serial, feat=blk, raw_data=vp.s) for succ in mb.succset: G.add_edge(mb.serial, succ) G.remove_featempty_nodes() if not G.have_nodes(): return # add a fake edge if there is no edge if not G.have_edges(): G.add_edge(G.graph['nodes'][0]['id'], G.graph['nodes'][0]['id']) # graph level ctree_fea = CtreeFeature(ctree_state, ctree_expr, ctree_int, ctree_str) ctree_fea.apply_to(cfunc.body, None) G.graph['graph']['c_state'], G.graph['graph']['c_expr'], G.graph['graph']['c_int'], G.graph['graph'][ 'c_str'], G.graph['graph']['m_int'] = ctree_state, ctree_expr, ctree_int, ctree_str, micro_int G.graph['graph']['arg_num'] = len(cfunc.argidx) func_bytes = b'' for start, end in idautils.Chunks(pfn.start_ea): fb = idaapi.get_bytes(start, end-start) func_bytes += fb G.graph['graph']['hash'] = hashlib.md5(func_bytes).hexdigest() return G.graph
def __init__(self, parent, display, location): """initialize item details section shows byte preview for match @param parent: parent node @param display: text to display in UI @param location: virtual address as seen by IDA """ byte_snap = idaapi.get_bytes(location, 32) if byte_snap: byte_snap = codecs.encode(byte_snap, "hex").upper() if sys.version_info >= (3, 0): details = " ".join([ byte_snap[i:i + 2].decode() for i in range(0, len(byte_snap), 2) ]) else: details = " ".join( [byte_snap[i:i + 2] for i in range(0, len(byte_snap), 2)]) else: details = "" super(CapaExplorerByteViewItem, self).__init__(parent, display, location=location, details=details) self.ida_highlight = idc.get_color(location, idc.CIC_ITEM)
def get_struct(address, struct_type): assert idaapi.is_loaded( address) == True, "Can't access memory at 0x%x" % address sbytes = idaapi.get_bytes(address, sizeof(struct_type)) struct = struct_type.from_buffer_copy(sbytes) struct._addr = address return struct
def __get_real_gp(rom_addr, rom_end): # li gp, 0xADDR; move $fp, $sp gp_set, _ = masked_search(rom_addr, rom_end, b'\x9C\x27\x21\xF0\xA0\x03', b'\xFF\xFF\xFF\xFF\xFF\xFF') if gp_set != idaapi.BADADDR: gp_set -= 6 gp1 = idaapi.get_bytes(gp_set + 0, 2) gp2 = idaapi.get_bytes(gp_set + 4, 2) new_gp = ((gp1[1] & 0xFF) << 24) | ((gp1[0] & 0xFF) << 16) | ((gp2[1] & 0xFF) << 8) | ((gp2[0] & 0xFF) << 0) idaapi.msg("Real GP found at 0x%08X => 0x%08X!\n" % (gp_set, new_gp)) return new_gp return 0
def _sig_bytes(self, addr: int, count: int) -> str: """ Get the bytes for a single instruction without wildcards :param addr: Byte start address :param count: Number of bytes to get :return: A signature """ return ' '.join(f'{b:02X}' for b in idaapi.get_bytes(addr, count))
def iterate_vtable(vtable_addr): ea = vtable_addr while True: fn_ea = struct.unpack('<Q', idaapi.get_bytes(ea, 8))[0] if idaapi.get_name(fn_ea) != "__cxa_pure_virtual" and not idaapi.is_func(idaapi.get_flags(fn_ea)): return yield fn_ea ea += 8
def get_data(self): data = None if self.config.use_disk_binary: data = get_disk_binary() else: data_size = self.config.end_addr - self.config.start_addr data = idaapi.get_bytes(self.config.start_addr, data_size) return data
def hexdump(addr, size): print_bytes = idaapi.get_bytes(addr, size) dump = [] for b in print_bytes: dump.append(ord(b)) hexdump_raw(addr, dump)
def handle_string_mov(ea, state): """Updates the stack based on a movs instruction. Used by create_stack If a rep/repne prefix is used, takes the count from ecx. If the count cannot be determined, will ignore the instruction. Also assumes that esi points to memory within the executable, and edi points to the stack. On any errors, this will ignore the instruction. :param ea: instruction location :param state: the current TraceState :return: None - updates stack or regs """ opcode = idaapi.get_bytes(ea, 1) rep_inst = opcode in [b"\xf2", b"\xf3"] count = state.get_reg_value("ecx") if rep_inst else 1 if not count or count < 0: return cmd = idaapi.insn_t() inslen = idaapi.decode_insn(cmd, ea) dtype = cmd.ops[0].dtype word_size = [1, 2, 4][dtype] if dtype < 3 else 4 count *= word_size src = state.get_reg_value("esi") dst = state.get_reg_value("edi") if src is None or dst is None: return # In IDA 7, get_bytes doesn't return None on failure, instead it will return # a string of \xff the size of count. My theory is that the function changed # to return -1 for each byte within the c code and something is casting it to a string before returning. # Since, all \xff's could be valid we need to check if src is valid instead. if not idc.is_loaded(src): return bytes_ = idaapi.get_bytes(src, count) if bytes_ in ( None, -1): # Keep this around in-case they fix it in a future version. return for i in range(count): state.stack[dst + i] = ((bytes_[i]), ea) if rep_inst: state.set_reg_value("ecx", 0, ea) state.set_reg_value("esi", src + count, ea) state.set_reg_value("edi", dst + count, ea)
def get_KEY_BUFFER(init_resolve_func_ea): global KEY_BUFFER if init_resolve_func_ea is None: print('get_KEY_BUFFER fails...') return None print(hex(init_resolve_func_ea)) ref_ea = None for ref in idautils.CodeRefsTo(init_resolve_func_ea, 1): # only 1 ref ref_ea = ref break arg_list = [0, 0, 0] curr_ea = ref_ea for i in range(0, 3): while True: prev_instruction_ea = idc.prev_head(curr_ea) if idc.print_insn_mnem(prev_instruction_ea) == 'push': arg_list[i] = idc.get_operand_value(prev_instruction_ea, 0) curr_ea = prev_instruction_ea break key1 = [] key1_ea = arg_list[0] length = arg_list[2] while key1_ea < arg_list[0] + length: key1.append(int.from_bytes(idaapi.get_bytes(key1_ea, 4), 'little')) key1_ea += 4 key2 = [] key2_ea = arg_list[1] while key2_ea < arg_list[1] + length: key2.append(int.from_bytes(idaapi.get_bytes(key2_ea, 1), 'little')) key2_ea += 1 init_resolve_buffer(key1, key2, length)
def StartDump(self): # print self.start # print self.endorlen self.filepath = idaapi.ask_file(1, "*.dump", "save dump file") if self.dumptype == 0: ea = self.getHexNum(self.start) len = self.getHexNum(self.endorlen) if not idaapi.is_loaded(ea) or not idaapi.is_loaded(ea + len): idaapi.warning("arrary is out of bound") return -1 if len <= 0: idaapi.warning("len is <= 0") return -1 print("start read bytes") self.Close(0) idaapi.show_wait_box("read bytes") self.memdata = idaapi.get_bytes(ea, len) print("read bytes end") #idaapi.hide_wait_box("read end") idaapi.hide_wait_box() elif self.dumptype == 1: ea = self.getHexNum(self.start) len = self.getHexNum(self.endorlen) - self.getHexNum(self.start) if not idaapi.is_loaded(ea) or not idaapi.is_loaded(ea + len): idaapi.warning("arrary is out of bound") return -1 if len <= 0: idaapi.warning("len is <= 0") return -1 print("start read bytes") self.Close(0) idaapi.show_wait_box("read bytes") self.memdata = idaapi.get_bytes(ea, len) print("read bytes end") #idaapi.hide_wait_box("read end") idaapi.hide_wait_box() fp = open(self.filepath, 'wb') fp.write(self.memdata) fp.close() idaapi.msg("save:" + self.filepath) return 1
def generate_yara_rule(self, mode, is_data=False): start, end = get_selection() size = end - start data = idaapi.get_bytes(start, size) ins_set, ins_mode = get_arch_info() yr_gen = YaraGenerator(mode, ins_set, ins_mode) yr_gen.add_chunk(data, offset=start, is_data=is_data) rule_obj = yr_gen.generate_rule() file_hash = get_input_file_hash() rule_obj.metas["hash"] = "\"{}\"".format(file_hash) rule = rule_obj.get_rule_string() self.dialog = YaraRuleDialog(None, start, end, rule) self.dialog.show()
def main(): text_ea = None #for some reason SegByName() isn't working for me - maybe an IDA 7 regression? for seg in Segments(): if get_segm_name(seg) == ".text": text_ea = seg if text_ea is None: print "ERROR: Unable to get .text segment!" return # first find all the functions for head in Heads(text_ea, SegEnd(text_ea)): func_ea = idaapi.get_func(head) if func_ea is None: if idaapi.get_bytes(head, 13) == '\x8b\xff\xe8\x00\x00\x00\x00\x83\xc4\x04\x0f\xff\xf0': print "Unrecognized apicall function at @ 0x%x"%(head) MakeFunction(head) #now name the functions for funcea in Functions(text_ea, SegEnd(text_ea)): functionName = GetFunctionName(funcea) for (startea, endea) in Chunks(funcea): for head in Heads(startea, endea): insnbytes = idaapi.get_bytes(head, 3) if insnbytes == '\x0f\xff\xf0': apicrc = idaapi.get_long(head+3) apiname = hashesToNames.get(apicrc) if apiname is None: print "ERROR: apicrc 0x%x NOT FOUND! @ 0x%x"%(apicrc, head) else: print "PROCESS - apicall: %s @ 0x%x"%(apiname, head) func_ea = idaapi.get_func(head).start_ea fname = idc.GetFunctionName(func_ea) if fname.startswith("sub_"): MakeName(func_ea, "apicall_" + apiname)
def activate(self, ctx): start, end = idc.read_selection_start(), idc.read_selection_end() if start == idaapi.BADADDR: print 'Please select something' return import capstone md = capstone.Cs(capstone.CS_ARCH_X86, capstone.CS_MODE_64) md.details = True data = idaapi.get_bytes(start, end - start) for insn in md.disasm(data, start): # print "0x%x:\t%s\t%s" % (insn.address, insn.mnemonic, insn.op_str) idaapi.set_cmt(insn.address, str('%s %s' % (insn.mnemonic, insn.op_str)), False)
def hook(self, hook_addr=0): """ Args: hook_addr(int): address for inline hook code, 0 indicates bpt hook. Returns: memory size in bytes used for inline hook. """ self.hook_addr = hook_addr self.func_addr = idc.get_name_ea_simple(self.name) if self.func_addr == 0: return 0 print("Hooking %s at 0x%x" % (self.name, self.func_addr)) if self.hook_addr == 0: idc.add_bpt(self.func_addr) idc.set_bpt_cond(self.func_addr, self.bpt_cond_hook_code) return 0 else: # assemble jmp code jmp_code = "jmp 0x%x" % self.hook_addr jmp_buf, _ = assemble(jmp_code, self.func_addr) # read function prologue according to jmp code length # NOTE: instructions like 'call $+5' in prologue will # cause problems. insn = idaapi.insn_t() move_length = 0 while move_length < len(jmp_buf): idaapi.decode_insn(insn, self.func_addr + move_length) move_length += insn.size prologue = idaapi.get_bytes(self.func_addr, move_length) # write jmp code idaapi.patch_bytes(self.func_addr, jmp_buf) # assmble hook code hook_buf, _ = assemble(self.inline_hook_code, self.hook_addr) hook_buf += prologue jmp_back_code = 'jmp 0x%x' % (self.func_addr + move_length) jmp_back_buf, _ = assemble(jmp_back_code, self.hook_addr + len(hook_buf)) hook_buf += jmp_back_buf # wirte hook code idaapi.patch_bytes(self.hook_addr, hook_buf) return len(hook_buf)
def get_segment_buffer(seg): """return bytes stored in a given segment decrease buffer size until IDA is able to read bytes from the segment """ buff = b"" sz = seg.end_ea - seg.start_ea while sz > 0: buff = idaapi.get_bytes(seg.start_ea, sz) if buff: break sz -= 0x1000 # IDA returns None if get_bytes fails, so convert for consistent return type return buff if buff else b""
def getOpcodes(addr, size): md = capstone.Cs(capstone.CS_ARCH_X86, CAPSTONE_MODE) md.detail = True instr_bytes = idaapi.get_bytes(addr, size) opcodes_buf = b'' for i in md.disasm(instr_bytes, size): # get last opcode if i.opcode[3] != 0: opcodes_buf += "%02x" % (i.opcode[3]) elif i.opcode[2] != 0: opcodes_buf += "%02x" % (i.opcode[2]) elif i.opcode[1] != 0: opcodes_buf += "%02x" % (i.opcode[1]) else: opcodes_buf += "%02x" % (i.opcode[0]) return opcodes_buf
def __init__(self, targetSeg=".text", vmpSeg=".asp0"): #Get Segment Info (start, end, size) if self.getVmpCallList(targetSeg, vmpSeg) is not True: print("Get Call list Fail") return for x in self.call_list: result = self.functionTracer(x) if result is False: self.fail_list.append(x) else: self.gadget_list.append(result) self.decodeAddress() for x in self.call_list: #print "" result = self.functionDummyTracer(x) if result is False: self.dummy_fail_list.append(x) else: self.dummy_patch_list.append(x + 5) self.dummy_gadget_list.append(result) if idaapi.get_bytes(x + 5, 1) != '\x90': self.dummy_patch_list.append(x + 5) self.dummy_gadget_list.append(result) else: self.dummy_patch_list.append(x + 5) self.dummy_gadget_list.append(result) print("################### vmp0 Call List ###################") self.printCallList() print("################### Trace Fail List ###################") self.printFailList() print("################### Gadget List ###################") self.printGadget() print("################### Decoded Api List ###################") self.printDecodedApi() print("################### Decoded Dummy Api List ###################") self.printDummyGadget() for x in self.dummy_patch_list: print hex(x).rstrip('L')
def __init__(self, inst, isContent=False): # type: (int, bool) -> () """ Loads the content at the specified address inst. if isContent, inst itself is taken as the content :param inst: linear address of instuction item, or the content itself :param isContent: whether inst is a linear address or content :raises ValueError: if the instruction could not be decoded """ if isContent: self.inst = inst else: self.inst = idaapi.get_bytes(inst, 2) self.inst = ord(self.inst[0]) + (ord(self.inst[1]) << 8) # TODO: if it's a BL, it's 4 bytes, figure that out here self.fields = decode(self.inst) if self.fields == None: raise ValueError('could not decode {:X}'.format(inst))
def visit_expr(self, e): if e.op == idaapi.cot_call and \ e.x.op == idaapi.cot_obj and \ e.x.obj_ea == self.ea: arg = e.a[0] # print(f"arg={arg}, arg.op={arg.op}") t = idaapi.tinfo_t.get_stock(idaapi.STI_PCHAR) if arg.op == idaapi.cot_obj: prefix = idaapi.get_bytes(arg.obj_ea, 2) # print(prefix) if prefix[0] == 1: log_level = chr(prefix[1]) idaapi.del_items(arg.obj_ea) arg.obj_ea += 2 idc.create_strlit(arg.obj_ea, idaapi.BADADDR) arg.type = t arg.exflags = idaapi.EXFL_CSTR return 0
def masked_search(start_addr: int, end_addr: int, bytes_data: bytes, masks_data: bytes) -> Tuple[int, Optional[bytes]]: def prepare_first_search(bd: bytes, md: bytes) -> bytes: bd_str = binascii.hexlify(bd, ' ').split(b' ') md_str = binascii.hexlify(md, ' ').split(b' ') for ii, md_token in enumerate(md_str): if md_token != b'ff': bd_str[ii] = b'?' bd_str = b' '.join(bd_str) return bd_str len_bytes = len(bytes_data) bytes_data_prep = prepare_first_search(bytes_data, masks_data) if idaapi.IDA_SDK_VERSION >= 760: patterns = ida_bytes.compiled_binpat_vec_t() idaapi.parse_binpat_str(patterns, start_addr, bytes_data_prep.decode(), 16) ea = ida_bytes.bin_search(start_addr, end_addr, patterns, ida_bytes.BIN_SEARCH_FORWARD | ida_bytes.BIN_SEARCH_NOBREAK | ida_bytes.BIN_SEARCH_NOSHOW) else: ea = ida_search.find_binary(start_addr, end_addr, bytes_data_prep.decode(), 16, idaapi.SEARCH_DOWN) if ea == idaapi.BADADDR: return idaapi.BADADDR, None found_bytes = idaapi.get_bytes(ea, len_bytes) equal = True for i in range(len_bytes): m = masks_data[i] if found_bytes[i] & m != bytes_data[i] & m: equal = False break if equal: return ea, found_bytes return idaapi.BADADDR, None