예제 #1
0
    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)
예제 #2
0
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
예제 #3
0
 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
예제 #4
0
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)
예제 #5
0
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)
예제 #6
0
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
예제 #7
0
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
예제 #8
0
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)