def parse(self): if ida_segment.get_segm_by_name('DYLD_CACHE_HEADER'): seg = ida_segment.get_first_seg() def handle(seg): name = ida_segment.get_segm_name(seg) try: mod, segname = name.split(':') except ValueError: return if segname == '__objc_protolist': self.handle_proto_seg(seg) elif segname == '__objc_classlist': self.handle_class_seg(seg) while seg: handle(seg) seg = ida_segment.get_next_seg(seg.start_ea) return protocols = ida_segment.get_segm_by_name('__objc_protolist') if protocols: self.handle_proto_seg(protocols) classes = ida_segment.get_segm_by_name('__objc_classlist') if classes: self.handle_class_seg(classes)
def find_segm_fixed(name): # ida_segments'getting segment by name returns a random one # segment_t.name is a bogus value # ... wtf? that "API" is a mess. it = ida_segment.get_first_seg() while ida_segment.get_segm_name(it) != name and it: it = ida_segment.get_next_seg(it.start_ea + 1) return it
def getBinary(self): result = b"" segment = ida_segment.get_first_seg() while segment: result += ida_bytes.get_bytes(segment.start_ea, segment.end_ea - segment.start_ea) segment = ida_segment.get_next_seg(segment.end_ea) return result
def FindInstructions(instr, asm_where=None): """ Finds instructions/opcodes @return: Returns a tuple(True, [ ea, ... ]) or a tuple(False, "error message") """ if not asm_where: # get first segment seg = ida_segment.get_first_seg() asm_where = seg.start_ea if seg else ida_idaapi.BADADDR if asm_where == ida_idaapi.BADADDR: return (False, "No segments defined") # regular expression to distinguish between opcodes and instructions re_opcode = re.compile('^[0-9a-f]{2} *', re.I) # split lines lines = instr.split(";") # all the assembled buffers (for each instruction) bufs = [] for line in lines: if re_opcode.match(line): # convert from hex string to a character list then join the list to form one string buf = bytes(bytearray([int(x, 16) for x in line.split()])) else: # assemble the instruction ret, buf = idautils.Assemble(asm_where, line) if not ret: return (False, "Failed to assemble:" + line) # add the assembled buffer bufs.append(buf) # join the buffer into one string buf = b''.join(bufs) # take total assembled instructions length tlen = len(buf) # convert from binary string to space separated hex string bin_str = ' '.join( ["%02X" % (ord(x) if sys.version_info.major < 3 else x) for x in buf]) # find all binary strings print("Searching for: [%s]" % bin_str) ea = ida_ida.cvar.inf.min_ea ret = [] while True: ea = ida_search.find_binary(ea, ida_idaapi.BADADDR, bin_str, 16, ida_search.SEARCH_DOWN) if ea == ida_idaapi.BADADDR: break ret.append(ea) ida_kernwin.msg(".") ea += tlen if not ret: return (False, "Could not match [%s]" % bin_str) ida_kernwin.msg("\n") return (True, ret)
def FindInstructions(instr, asm_where=None): """ Finds instructions/opcodes @return: Returns a tuple(True, [ ea, ... ]) or a tuple(False, "error message") """ if not asm_where: # get first segment seg = ida_segment.get_first_seg() asm_where = seg.start_ea if seg else ida_idaapi.BADADDR if asm_where == ida_idaapi.BADADDR: return (False, "No segments defined") # regular expression to distinguish between opcodes and instructions re_opcode = re.compile('^[0-9a-f]{2} *', re.I) # split lines lines = instr.split(";") # all the assembled buffers (for each instruction) bufs = [] for line in lines: if re_opcode.match(line): # convert from hex string to a character list then join the list to form one string buf = ''.join([chr(int(x, 16)) for x in line.split()]) else: # assemble the instruction ret, buf = idautils.Assemble(asm_where, line) if not ret: return (False, "Failed to assemble:"+line) # add the assembled buffer bufs.append(buf) # join the buffer into one string buf = ''.join(bufs) # take total assembled instructions length tlen = len(buf) # convert from binary string to space separated hex string bin_str = ' '.join(["%02X" % ord(x) for x in buf]) # find all binary strings print("Searching for: [%s]" % bin_str) ea = ida_ida.cvar.inf.min_ea ret = [] while True: ea = ida_search.find_binary(ea, ida_idaapi.BADADDR, bin_str, 16, ida_search.SEARCH_DOWN) if ea == ida_idaapi.BADADDR: break ret.append(ea) ida_kernwin.msg(".") ea += tlen if not ret: return (False, "Could not match [%s]" % bin_str) ida_kernwin.msg("\n") return (True, ret)
def find_segm_fixed(name): # ida_segments'getting segment by name returns a random one # segment_t.name is a bogus value # ... wtf? that "API" is a mess. res = [] it = ida_segment.get_first_seg() while it: if ida_segment.get_segm_name(it) == name: res += [it] it = ida_segment.get_next_seg(it.start_ea + 1) return res
def _find_segment_containing_ea(ea, seg_ref): """Find and return a `segment_t` containing `ea`, or `None`.""" seg = seg_ref[0] if seg and seg.contains(ea): return seg seg = ida_segment.get_first_seg() while seg: seg_ref[0] = seg if seg.contains(ea): return seg seg = ida_segment.get_next_seg(seg.start_ea) return None
def unicorn_init(): global stack_bottom global uc # Fingers crossed there are no holes in this VM region... start = ida_segment.get_first_seg().start_ea end = (ida_segment.get_last_seg().end_ea + 0x400) & ~0x3ff stack_bottom = end uc = Uc(UC_ARCH_ARM64, UC_MODE_LITTLE_ENDIAN) # Map the entire kc and stack only once uc.mem_map(start, end - start) uc.mem_map(stack_bottom, 0x400) uc.reg_write(UC_ARM64_REG_SP, stack_bottom + 0x400) uc.reg_write(UC_ARM64_REG_CPACR_EL1, 0x300000)