Exemple #1
0
    def get_mem_string(cls, addr):
        """
        获取内存中的字符串
        """

        addr_t = addr
        dref = idautils.DataRefsFrom(addr_t)
        strs = [cls.strings[x] for x in dref if x in cls.strings]

        # 处理几种特殊情况
        # LDR R1, =sub_xxxx
        # LDR R1, =loc_xxxx
        if idc.print_operand(addr, 1)[:5] in ['=sub_', '=loc_']:
            return []

        # LDR R1, =unk_53B4B6
        # .rodata:0053B4B6 http:
        # .rodata:0053B4BB //%s%s
        if strs != [] and strs[0].find('%') == -1:
            strs = []
            dref = idautils.DataRefsFrom(addr_t)
            for x in dref:
                segname = ida_segment.get_segm_name(ida_segment.getseg(x))
                if segname not in ['.text', '.bss']:
                    strs.append(cls.get_string_from_mem(x))

        # LDR R1, =(aFailedToGetAnI+0x22)
        # LDR R2, =(aSS - 0xCFA4)
        # ADD R2, PC, R2
        if strs == []:
            dref = idautils.DataRefsFrom(addr_t)
            for x in dref:
                segname = ida_segment.get_segm_name(ida_segment.getseg(x))
                if segname not in ['.text', '.bss']:
                    strs.append(cls.get_string_from_mem(x))
                elif len(list(idautils.DataRefsFrom(x))) == 0:
                    reg_t = idc.print_operand(addr_t, 0)
                    num1 = ida_bytes.get_wide_dword(x)
                    while get_mnem(addr_t) != 'ADD' or (idc.print_operand(addr_t, 0) != reg_t and idc.print_operand(addr_t, 1) != 'PC'):
                        addr_t = ida_bytes.next_head(addr_t, ida_idaapi.BADADDR)
                    num2 = addr_t + 8
                    addr_t = num1 + num2
                    strs.append(cls.get_string_from_mem(addr_t))

        # MOVW R1, #0x87B4
        # MOVT.W R1, #0x52
        if strs == [] and get_mnem(addr_t) == 'MOVW':
            reg_t = idc.print_operand(addr_t, 0)
            num1 = int(idc.print_operand(addr_t, 1).split('#')[1], 16)
            while get_mnem(addr_t) not in ['MOVTGT', 'MOVTLE', 'MOVT'] or idc.print_operand(addr_t, 0) != reg_t:
                addr_t = ida_bytes.next_head(addr_t, ida_idaapi.BADADDR)
            num2 = int(idc.print_operand(addr_t, 1).split('#')[1], 16)
            addr_t = (num2<<16) + num1
            strs.append(cls.get_string_from_mem(addr_t))

        return strs
Exemple #2
0
def main():
    for segstart, segend, segname in enum_segments():
        for head in idautils.Heads(segstart, segend):
            if not is_code(head):
                continue

            # pattern:
            #
            #   lea     rax, unk_6BDF88
            #   mov     [rsp+0], rax
            #   mov     qword ptr [rsp+8], 40h
            if ida_ua.ua_mnem(head) != "lea":
                continue

            next_head = ida_bytes.next_head(head, idc.BADADDR)
            if ida_ua.ua_mnem(next_head) != "mov":
                continue

            next_head2 = ida_bytes.next_head(next_head, idc.BADADDR)
            if ida_ua.ua_mnem(next_head2) != "mov":
                continue

            dst = idc.get_operand_value(head, 1)
            if idc.get_segm_name(dst) not in (".rdata", "UPX1"):
                continue

            size = idc.get_operand_value(next_head2, 1)

            if size > 0x100:
                continue
            if size <= 2:
                continue

            buf = ida_bytes.get_bytes(dst, size)
            if not buf:
                continue

            if b"\x00" in buf:
                continue

            try:
                s = buf.decode("ascii")
            except UnicodeDecodeError:
                continue

            print("string pointer: 0x%x -> 0x%x: %s" % (head, dst, s))
            ida_bytes.del_items(dst, 1)
            ida_bytes.create_data(dst, idc.FF_BYTE, 1, idc.BADADDR)
            ida_bytes.set_cmt(dst, s, True)
            ida_name.set_name(dst, "s_%x" % (dst))
Exemple #3
0
 def btn_add_next_inst_bpt(self, code=0):
     """
     给所有断点的下一条指令下断点
     """
     bpt_list = self.get_all_bpt_list()
     for bpt in bpt_list:
         ida_dbg.add_bpt(ida_bytes.next_head(bpt, ida_idaapi.BADADDR), 0,
                         idc.BPT_DEFAULT)
Exemple #4
0
def main():
    is_selected, sel_start, sel_end = ida_kernwin.read_selection()
    if not is_selected:
        logger.error('range must be selected')
        return -1

    sel_end = ida_bytes.next_head(sel_end)

    buf = ida_bytes.get_bytes(sel_start, sel_end - sel_start)
    if buf is None:
        logger.error('failed to fetch instruction bytes')
        return -1

    f = ida_funcs.get_func(sel_start)
    if f != ida_funcs.get_func(sel_end):
        logger.error('range must be within a single function')
        return -1

    # find mappings from "$localN" to "custom_name"
    regvars = {}
    for i in range(0x1000):
        regvar = ida_frame.find_regvar(f, sel_start, '$local%d' % i)
        if regvar is None:
            continue
        regvars[regvar.canon] = regvar.user

        if len(regvars) >= f.regvarqty:
            break

    globals_ = {}
    for i, offset in netnode.Netnode('$ wasm.offsets').get('globals',
                                                           {}).items():
        globals_['$global' + i] = ida_name.get_name(offset)

    frame = {}
    if f.frame != ida_idaapi.BADADDR:
        names = set([])
        for i in range(ida_struct.get_struc_size(f.frame)):
            s = ida_struct.get_struc(f.frame)
            if not s:
                continue
            m = ida_struct.get_member(s, i)
            if not m:
                continue
            name = ida_struct.get_member_name(m.id)
            if name in names:
                continue
            frame[i] = name
            names.add(name)

    emu = Emulator(buf)
    emu.run()
    print(
        emu.render(ctx={
            'regvars': regvars,
            'frame': frame,
            'globals': globals_,
        }))
Exemple #5
0
def Heads(start=None, end=None):
    """
    Get a list of heads (instructions or data)

    @param start: start address (default: inf.min_ea)
    @param end:   end address (default: inf.max_ea)

    @return: list of heads between start and end
    """
    if not start: start = ida_ida.cvar.inf.min_ea
    if not end:   end = ida_ida.cvar.inf.max_ea

    ea = start
    if not idc.is_head(ida_bytes.get_flags(ea)):
        ea = ida_bytes.next_head(ea, end)
    while ea != ida_idaapi.BADADDR:
        yield ea
        ea = ida_bytes.next_head(ea, end)
Exemple #6
0
 def get_disasm(self, start_address, end_address) -> list:
     result = []
     current_start = start_address
     while current_start < end_address:
         # https://github.com/idapython/src/blob/master/python/idautils.py#L202
         result.append(idc.GetDisasm(current_start))
         current_start = ida_bytes.next_head(current_start,
                                             ida_ida.cvar.inf.max_ea)
     return result
Exemple #7
0
 def get_disasm(self, start_address, end_address) -> list:
     result = []
     start = int(start_address, 16)
     end = int(end_address, 16)
     while start <= end:
         # https://github.com/idapython/src/blob/master/python/idautils.py#L202
         next_start = ida_bytes.next_head(start, ida_ida.cvar.inf.max_ea)
         result.append(idc.GetDisasm(start))
         start = next_start
     return result
Exemple #8
0
    def trace_block(self, blk, node, reg):
        """
        在一个基本块内回溯
        """
        reg_t = reg
        cur_t = node['addr']
        while reg_t and cur_t >= blk.start_ea:
            cur_t, reg_t = self.trace_handle(cur_t, reg_t)

        return (ida_bytes.next_head(cur_t, ida_idaapi.BADADDR), reg_t)
Exemple #9
0
 def get_hex(self, start_address, end_address) -> list:
     result = []
     start = int(start_address, 16)
     end = int(end_address, 16)
     while start <= end:
         # https://github.com/idapython/src/blob/master/python/idautils.py#L202
         next_start = ida_bytes.next_head(start, ida_ida.cvar.inf.max_ea)
         result.append(
             binascii.hexlify(ida_bytes.get_bytes(start, next_start -
                                                  start)).decode())
         start = next_start
     return result
Exemple #10
0
 def get_string(self, start_address, end_address) -> list:
     result = []
     start = int(start_address, 16)
     end = int(end_address, 16)
     while start <= end:
         # https://github.com/idapython/src/blob/master/python/idautils.py#L202
         next_start = ida_bytes.next_head(start, ida_ida.cvar.inf.max_ea)
         if ida_nalt.get_str_type(start) < 4294967295:
             result.append(
                 ida_bytes.get_strlit_contents(
                     start, -1, ida_nalt.get_str_type(start)).decode())
         start = next_start
     return result
Exemple #11
0
def get_func_items_from_xref(xref):
    """
    Returns the rest of the instruction from a given xref
    """
    items = list(idautils.FuncItems(xref))
    if len(items):
        idx = items.index(xref)+1
        items = items[idx:]
    else:
        print "  - Xref at 0x{:08x} wasn't marked as a function".format(xref)
        cur = ida_bytes.next_head(xref, idaapi.cvar.inf.maxEA)
        while True:
            if cur not in items:
                items.append(cur)
                print "adding 0x{:08x}: ".format(cur, disasm(cur))

            inst = idautils.DecodeInstruction(cur)
            if inst.get_canon_mnem() in ['call', 'jmp', 'retn']:
                break
            cur = ida_bytes.next_head(cur, idaapi.cvar.inf.maxEA)

    return items
Exemple #12
0
 def get_string(self, start_address, end_address) -> list:
     result = []
     current_start = start_address
     while current_start < end_address:
         if ida_nalt.get_str_type(current_start) < 4294967295:
             result.append(
                 ida_bytes.get_strlit_contents(
                     current_start, -1,
                     ida_nalt.get_str_type(current_start)).decode())
         # https://github.com/idapython/src/blob/master/python/idautils.py#L202
         current_start = ida_bytes.next_head(current_start,
                                             ida_ida.cvar.inf.max_ea)
     return result
Exemple #13
0
def enum_function_addrs(fva):
    '''
    yield the effective addresses of each instruction in the given function.
    these addresses are not guaranteed to be in any order.
    
    Args:
      fva (int): the starting address of a function
    
    Returns:
      sequence[int]: the addresses of each instruction
    '''
    f = idaapi.get_func(fva)
    if not f:
        raise ValueError('not a function')

    for block in idaapi.FlowChart(f):
        ea = block.start_ea
        while ea <= block.end_ea:
            yield ea
            ea = ida_bytes.next_head(ea, idc.BADADDR)
Exemple #14
0
def jump_next_comment(v):
    """
    Starting at the current line, keep generating lines until
    a comment is found. When this happens, position the viewer
    at the right coordinates.
    """
    loc = ida_moves.lochist_entry_t()
    if ida_kernwin.get_custom_viewer_location(loc, v):
        place = loc.place()
        idaplace = ida_kernwin.place_t_as_idaplace_t(place)
        ea = idaplace.ea
        while ea != ida_idaapi.BADADDR:
            _, disass = ida_lines.generate_disassembly(
                ea,
                1000,  # maximum number of lines
                False,  # as_stack=False
                False
            )  # notags=False - we want tags, in order to spot comments

            found = None

            # If this is the start item, start at the next line
            start_lnnum = (idaplace.lnnum + 1) if ea == idaplace.ea else 0

            for rel_lnnum, line in enumerate(disass[start_lnnum:]):
                vis_cx = find_comment_visual_position_in_tagged_line(line)
                if vis_cx > -1:
                    found = (ea, rel_lnnum, vis_cx)
                    break

            if found is not None:
                idaplace.ea = found[0]
                idaplace.lnnum = start_lnnum + found[1]
                loc.set_place(idaplace)
                loc.renderer_info().pos.cx = found[2]
                ida_kernwin.custom_viewer_jump(v, loc, ida_kernwin.CVNF_LAZY)
                break

            ea = ida_bytes.next_head(ea, ida_idaapi.BADADDR)
Exemple #15
0
def _invent_var_type(ea, seg_ref, min_size=1):
    """Try to invent a variable type. This will basically be an array of bytes
    that spans what we need. We will, however, try to be slightly smarter and
    look for cross-references in the range, and when possible, use their types."""
    seg = find_segment_containing_ea(ea, seg_ref)
    if not seg:
        return ea, None

    head_ea = ida_bytes.get_item_head(ea)
    if head_ea < ea:
        head_seg = find_segment_containing_ea(head_ea, seg_ref)
        if head_seg != seg:
            return ea, None
        return _invent_var_type(head_ea, seg_ref, ea - head_ea)

    min_size = max(min_size, ida_bytes.get_item_size(ea))
    next_ea = ida_bytes.next_head(ea + 1, seg.end_ea)
    next_seg = find_segment_containing_ea(next_ea, seg_ref)

    arr = ArrayType()
    arr.set_element_type(IntegerType(1, False))

    if not next_seg or next_seg != seg:
        arr.set_num_elements(min_size)
        return ea, arr

    min_size = min(min_size, next_ea - ea)

    # TODO(pag): Go and do a better job, e.g. find pointers inside of the global.
    # i = 0
    # while i < min_size:
    #   for ref_ea in xref_generator(ea + i, seg_ref):
    #     break
    #   i += 1

    arr.set_num_elements(min_size)
    return ea, arr
Exemple #16
0
def dump_heads(out):
    # out is a file like object, sys.stdout or an acual file object

    # There doesn't seem to a good way to determine what function a
    # particular address is in.  Almost everyone recommends iterating
    # of the functions, and then getting the bytes out of each, but
    # that's not really what we want because it skips non function
    # bytes and reports them in the wrong order. It appears that the
    # best we can do is to build a map in advance. :-(
    a2fmap = build_a2fmap()

    min_ea = idaapi.cvar.inf.minEA
    max_ea = idaapi.cvar.inf.maxEA
    ea = min_ea
    while ea != ida_idaapi.BADADDR:
        ida_auto.show_addr(ea)
        isize = ida_bytes.get_item_size(ea)
        ibytes = ida_bytes.get_bytes(ea, isize)
        ihexbytes = binascii.b2a_hex(ibytes).upper()
        iflags = ida_bytes.get_flags(ea)

        # Skip the PE header?
        if not ida_bytes.is_head(iflags):
            ea = ida_bytes.next_head(ea, max_ea)
            continue

        # Loop up this address in the address-to-function map.
        if ea in a2fmap:
            faddrs = a2fmap[ea]
        else:
            faddrs = [ea]

        tcode = "ERROR"
        imnem = "???"
        iops = "???"

        if ida_bytes.is_code(iflags):
            tcode = "INSN"
            imnem = "???"
            iops = "???"

            insn = idautils.DecodeInstruction(ea)
            if insn == None:
                imnem = "BAD"
                iops = ""
            elif not insn.is_canon_insn():
                imnem = "NCAN"
                iops = ""
            else:
                imnem = insn.get_canon_mnem()

                sops = []
                for n in range(8):
                    ostr = ida_ua.print_operand(ea, n)
                    if ostr is not None:
                        ostrnt = ida_lines.tag_remove(ostr)
                        if ostrnt != '':
                            sops.append(ostrnt)
                iops = ', '.join(sops)

        elif ida_bytes.is_data(iflags):
            tcode = "DATA"
            imnem = "db"
            iops = "???"
            if ida_bytes.is_align(iflags):
                tcode += "_ALIGN"
            #elif ida_bytes.is_struct(iflags):
            #    tcode += "_STRUCT"
            #elif ida_bytes.is_char(iflags):
            #    tcode += "_STR"
            # There are other types that IDA recognizes.
        elif ida_bytes.is_unknown(iflags):
            tcode = "UNK-%08X" % iflags
            imnem = "???"
            iops = "???"

        for faddr in sorted(faddrs):
            out.write('"PART",0x%08X,"%s",0x%08X,"%s","%s","%s"\n' %
                      (ea, tcode, faddr, ihexbytes, imnem, iops))
        ea = ida_bytes.next_head(ea, max_ea)
    print "Analysis complete!"
Exemple #17
0
    def activate(self, ctx):
        selection = idaapi.read_selection()
        if not selection[0]:
            return 0

        start = selection[1] - 1
        stop = selection[2] + 1

        print('Parsing selection between %X -> %X' % (start, stop))

        prefix = ida_kernwin.ask_str('', 0, 'Prefix')

        if prefix is not None:
            prefix = prefix.replace('/', '::')

        while True:
            name_address = ida_bytes.next_head(start, stop)

            if name_address == idaapi.BADADDR:
                break

            name_offset = ida_bytes.get_dword(name_address)

            name = ida_bytes.get_strlit_contents(name_offset, -1, 0)

            if prefix is not None:
                name = prefix + '::' + name

            signature_address = ida_bytes.next_head(name_address, stop)

            if signature_address == idaapi.BADADDR:
                break

            signature_offset = ida_bytes.get_dword(signature_address)

            signature = ida_bytes.get_strlit_contents(signature_offset, -1, 0)

            function_address = ida_bytes.next_head(signature_address, stop)

            if function_address == idaapi.BADADDR:
                break

            function_offset = ida_bytes.get_dword(function_address)

            if function_offset % 2 != 0:
                function_offset -= 1

            try:
                c_signature = JNINativeMethodSignature(name, signature).c
            except JNINativeMethodError:
                break

            start = function_address

            parsed_decl = ida_typeinf.idc_parse_decl(None, c_signature,
                                                     ida_typeinf.PT_SIL)

            if parsed_decl is None:
                return 0

            ida_typeinf.apply_type(None, parsed_decl[1], parsed_decl[2],
                                   function_offset, 1)

            ida_name.set_name(function_offset, name, ida_name.SN_FORCE)

        return 1
Exemple #18
0
    def __init__(self):
        ida_kernwin.UI_Hooks.__init__(self)

        # We'll color all lines starting with the current
        # one, with all available highlights...
        self.instantiated_at = ida_kernwin.get_screen_ea()
        self.color_info = []

        data = [
            ida_kernwin.CK_EXTRA1,
            ida_kernwin.CK_EXTRA2,
            ida_kernwin.CK_EXTRA3,
            ida_kernwin.CK_EXTRA4,
            ida_kernwin.CK_EXTRA5,
            ida_kernwin.CK_EXTRA6,
            ida_kernwin.CK_EXTRA7,
            ida_kernwin.CK_EXTRA8,
            ida_kernwin.CK_EXTRA9,
            ida_kernwin.CK_EXTRA10,
            ida_kernwin.CK_EXTRA11,
            ida_kernwin.CK_EXTRA12,
            ida_kernwin.CK_EXTRA13,
            ida_kernwin.CK_EXTRA14,
            ida_kernwin.CK_EXTRA15,
            ida_kernwin.CK_EXTRA16,
            # let's also try these colors keys, because why not
            ida_kernwin.CK_TRACE,
            ida_kernwin.CK_TRACE_OVL,
            [
                ida_kernwin.CK_TRACE,
                ida_kernwin.CK_TRACE_OVL,
            ],
        ]
        ea = self.instantiated_at
        for one in data:
            self.color_info.append((ea, one))
            ea = ida_bytes.next_head(ea, ida_idaapi.BADADDR)

        # ...and then we'll a few more things, such as
        # overriding parts of a previously-specified overlay,
        # and restricting the override to a few glyphs
        self.color_info.append((self.color_info[6][0], [
            (ida_kernwin.CK_EXTRA2, 7, 3),
            (ida_kernwin.CK_EXTRA4, 2, 1),
            (ida_kernwin.CK_EXTRA10, 2, 0),
            (ida_kernwin.CK_EXTRA10, 20, 10),
        ]))
        self.color_info.append((self.color_info[7][0], [
            (ida_kernwin.CK_EXTRA1, 1, 1),
            (ida_kernwin.CK_EXTRA2, 3, 1),
            (ida_kernwin.CK_EXTRA3, 5, 1),
            (ida_kernwin.CK_EXTRA4, 7, 1),
            (ida_kernwin.CK_EXTRA5, 9, 1),
            (ida_kernwin.CK_EXTRA6, 11, 1),
            (ida_kernwin.CK_EXTRA7, 13, 1),
            (ida_kernwin.CK_EXTRA8, 15, 1),
            (ida_kernwin.CK_EXTRA9, 17, 1),
            (ida_kernwin.CK_EXTRA10, 19, 1),
            (ida_kernwin.CK_EXTRA11, 21, 1),
            (ida_kernwin.CK_EXTRA12, 23, 1),
            (ida_kernwin.CK_EXTRA13, 25, 1),
            (ida_kernwin.CK_EXTRA14, 27, 1),
            (ida_kernwin.CK_EXTRA15, 29, 1),
            (ida_kernwin.CK_EXTRA16, 31, 1),
        ]))
        self.color_info.append((self.color_info[8][0], [
            (ida_kernwin.CK_EXTRA1, 16, 45),
            (ida_kernwin.CK_EXTRA2, 19, 45),
            (ida_kernwin.CK_EXTRA3, 22, 45),
            (ida_kernwin.CK_EXTRA4, 25, 45),
        ]))