Esempio n. 1
0
File: ESigs.py Progetto: newmsk/ESig
    def handle_dll_calls(self):
        dll_call_count = ida_bytes.get_dword(self.E_info_entry_ea +
                                             self.dll_call_count_offset)
        dll_call_lib_names_ea = ida_bytes.get_dword(
            self.E_info_entry_ea + self.dll_call_lib_names_offset)
        dll_call_func_names_ea = ida_bytes.get_dword(
            self.E_info_entry_ea + self.dll_call_func_names_offset)
        self.dll_calls = Dll_calls(dll_call_lib_names_ea,
                                   dll_call_func_names_ea, dll_call_count)

        ida_auto.auto_wait()

        ea = ida_name.get_name_ea(idaapi.BADADDR, "j__krnl_MCallDllCmd")
        code_fref_eas = []
        fref_ea = ida_xref.get_first_fcref_to(ea)

        while fref_ea != idaapi.BADADDR:
            code_fref_eas.append(fref_ea)
            fref_ea = ida_xref.get_next_cref_to(ea, fref_ea)

        for ref_ea in code_fref_eas:
            #get prev mov instruction
            prev_ins_ea = idaapi.get_item_head(ref_ea - 1)
            ins = ida_lines.generate_disasm_line(prev_ins_ea,
                                                 ida_lines.GENDSM_REMOVE_TAGS)
            if (ins.startswith("mov     eax,")):
                index = ida_bytes.get_dword(prev_ins_ea + 1)
                cmt = self.dll_calls[index]
                ida_bytes.set_cmt(ref_ea, cmt, False)
Esempio n. 2
0
    def extract_info_from_IDA(self):
        prots = ida_bytes.get_qword(self.ea + 0x10)
        if prots:
            count = ida_bytes.get_qword(prots)
            entrysize = 0x8
            p_ea = prots + 8
            for i in range(count):
                proto_ea = idc.get_qword(p_ea)
                self.prots.append(proto_ea)
                p_ea += entrysize

        type_info = ida_bytes.get_qword(self.ea + 0x48)
        for idx in range(0, 4):
            # 0: inst_meths
            # 1: class_meths
            # 2: opt_inst_meths
            # 3: opt_class_meths
            meth_list = ida_bytes.get_qword(self.ea + 0x18 + idx * 8)
            if meth_list:
                entrysize = ida_bytes.get_dword(meth_list)
                count = ida_bytes.get_dword(meth_list + 4)
                ea = meth_list + 8
                for i in range(0, count):
                    sel = idc.get_bytes(idc.Qword(ea), idc.get_item_size(idc.Qword(ea)) - 1)
                    meth_type = idc.get_bytes(idc.Qword(type_info), idc.get_item_size(idc.Qword(type_info)) - 1)
                    self.meths[sel] = meth_type
                    ea += entrysize
                    type_info += 8
Esempio n. 3
0
def guid_at_addr(guid_addr):
    return GUID(bytes=struct.pack(
        "<LLLL", ida_bytes.get_dword(guid_addr),
        ida_bytes.get_dword(guid_addr + 0x4),
        ida_bytes.get_dword(guid_addr + 0x8),
        ida_bytes.get_dword(guid_addr + 0xC)
    ))
        def analyze_block(block):
            """Analyze a basic bloc and return its successors, if it's correspond to a basic bloc treating the Driver case and the address for the DR/TL API table if one is loaded

            :param block: Basic block to analyze
            :type block: ida_gdl.BasicBlock
            :return: Successors Basic Blocks, if it deals with Secure Driver case, and the address of the table loaded if loaded
            :rtype: (Generator, bool, int)
            """

            loaded_value = -1
            is_dr_table = False
            insn = ida_ua.insn_t()
            insn_ea = block.start_ea
            insn_len = 0

            while insn_ea < block.end_ea:
                insn_len = max(1, ida_ua.decode_insn(insn, insn_ea))
                if insn.itype == ida_allins.ARM_sub and \
                        insn.ops[2].type == ida_ua.o_imm and \
                        insn.ops[2].value == 0x1000:
                    is_dr_table = True
                if insn.itype == ida_allins.ARM_ldr and \
                        insn.ops[1].type == ida_ua.o_mem:
                    pool_value = ida_bytes.get_dword(insn.ops[1].addr)
                    value = ida_bytes.get_dword(pool_value)
                    if value > 0x1000:
                        loaded_value = pool_value
                insn_ea += insn_len
            return block.succs(), is_dr_table, loaded_value
Esempio n. 5
0
def find_scatter_table():
    scatter_load_bytes = {
        "__scatterload": [
            "0A A0 90 E8 00 0C 82 44",
            "2C 00 8F E2 00 0C 90 E8 00 A0 8A E0 00 B0 8B E0",  # For 5G
        ],
    }

    tables = {}
    for name, prefixes in scatter_load_bytes.items():
        for prefix in prefixes:
            addrs = create_func_by_prefix(name, prefix, force=True)
            for addr in addrs:
                if addr == idc.BADADDR:
                    continue

                offset_addr = idc.get_operand_value(addr, 1)
                if offset_addr == -1:
                    old_flag = idc.get_sreg(addr, "T")
                    idc.split_sreg_range(addr, "T", not old_flag, idc.SR_user)
                    offset_addr = idc.get_operand_value(addr, 1)

                offset = ida_bytes.get_dword(offset_addr)
                offset2 = ida_bytes.get_dword(offset_addr + 4)
                start = (offset + offset_addr) & 0xFFFFFFFF
                end = (offset2 + offset_addr) & 0xFFFFFFFF
                if not idc.is_loaded(start):
                    continue

                tables[start] = end
                print("__scatter_table: 0x%x -> 0x%x" % (start, end))
                func_name = set_entry_name(start, "__scatter_table")

    return tables
Esempio n. 6
0
def search_guid(guid):
	if isinstance(guid, basestring):
		target_guid = GUID(string = guid)
	else:
		print "UNSUPPORTED FORMAT"
		return
		
	for seg_addr in idautils.Segments():
		seg = ida_segment.getseg(seg_addr)
		cur_addr = seg.start_ea
		seg_end = seg.end_ea
		while cur_addr < seg_end:
			d = [ida_bytes.get_dword(cur_addr),
				 ida_bytes.get_dword(cur_addr+0x4),
				 ida_bytes.get_dword(cur_addr+0x8),
				 ida_bytes.get_dword(cur_addr+0xC)]
			if (d[0] == 0 and d[1] == 0 and d[2] == 0 and d[3] == 0) or \
			   (
				d[0] == 0xFFFFFFFF and d[1] == 0xFFFFFFFF and d[2] == 0xFFFFFFFF and d[3] == 0xFFFFFFFF
			   ):
				cur_addr += 0x10
			else:
				cur_guid = GUID(bytes=struct.pack(
					"<LLLL", d[0], d[1], d[2], d[3]
				))
				if str(target_guid) == str(cur_guid):
					print "  - Found GUID {}  at 0x{:08x}".format(
						str(target_guid), cur_addr
					)
					return
				cur_addr += 1
	print ("  - GUID %s not found" % (str(target_guid)))
Esempio n. 7
0
    def find_pe(self, cursor=False):
        """Search IDB for possible MZ/PE headers"""
        info = idaapi.get_inf_structure()

        mz_headers = []

        # Check current cursor for MZ/PE?
        if cursor:
            # Get IDA cursor address
            addr = idc.here()

            # Get segment and end address
            s = idaapi.getseg(addr)
            e = idc.get_segm_end(addr)

            # Check for MZ magic
            if ida_bytes.get_word(addr) == 0x5a4d:
                # Ensure the PE header is in the segment
                e_lfanew = ida_bytes.get_dword(addr + 0x3c)

                if addr + e_lfanew + 1 < e:
                    # Check for PE magic
                    if ida_bytes.get_word(addr + e_lfanew) == 0x4550:
                        # Found possible MZ/PE header
                        mz_headers.append([addr, idc.get_segm_name(addr), info.is_64bit()])

            self.ret = mz_headers
            return self.ret

        # Search all segments
        for seg in idautils.Segments():
            s = idc.get_segm_start(seg)
            e = idc.get_segm_end(seg)
            addr = s

            while True:
                # Find first byte of MZ header
                addr = ida_bytes.find_byte(addr, e-addr, 0x4d, 0)

                if addr == ida_idaapi.BADADDR or addr >= e:
                    break

                # Check for MZ magic
                if ida_bytes.get_word(addr) == 0x5a4d:
                    # Ensure the PE header is in the segment
                    e_lfanew = ida_bytes.get_dword(addr + 0x3c)

                    if addr + e_lfanew + 1 < e:
                        # Check for PE magic
                        if ida_bytes.get_word(addr + e_lfanew) == 0x4550:
                            # Found possible MZ/PE header
                            mz_headers.append([addr, idc.get_segm_name(s), info.is_64bit()])

                # Resume search from next address
                addr += 1

        self.ret = mz_headers
        return self.ret
Esempio n. 8
0
def run_scatterload(debug=False):
    # Newly identified region may have additional scatter load procedure. Thus,
    # we continuously proceed until no changes left.
    is_changed = True
    while is_changed:
        is_changed = False
        tables = find_scatter_table()
        scatter_funcs = find_scatter_funcs()

        for start, end in tables.items():
            print("Processing table: 0x%x to 0x%x" % (start, end))
            while start < end:
                ida_bytes.create_dword(start, 16)
                ida_offset.op_offset(start, 0, idc.REF_OFF32)
                src = ida_bytes.get_dword(start)
                dst = ida_bytes.get_dword(start + 4)
                size = ida_bytes.get_dword(start + 8)
                how = ida_bytes.get_dword(start + 12)

                if how not in scatter_funcs:
                    print("%x: no addr 0x%x in scatter_funcs" % (start, how))
                    start += 16
                    continue

                func_name = scatter_funcs[how]
                start += 16
                print("%s: 0x%x -> 0x%x (0x%x bytes)" %
                      (func_name, src, dst, size))

                if func_name != "__scatterload_zeroinit":
                    if not idc.is_loaded(src) or size == 0:
                        print("0x%x is not loaded." % (src))
                        continue

                if debug:
                    # only show information above
                    continue

                if func_name == "__scatterload_copy":
                    if add_segment(dst, size, "CODE"):
                        memcpy(src, dst, size)
                        is_changed = True
                elif func_name == "__scatterload_decompress":
                    if add_segment(dst, size, "DATA"):
                        decomp(src, dst, size)
                        is_changed = True
                # some old firmware images have this.
                elif func_name == "__scatterload_decompress2":
                    if add_segment(dst, size, "DATA"):
                        decomp2(src, dst, size)
                        is_changed = True
                elif func_name == "__scatterload_zeroinit":
                    # No need to further proceed for zero init.
                    if add_segment(dst, size, "DATA"):
                        memclr(dst, size)

                ida_auto.auto_wait()
Esempio n. 9
0
def main():
    print("[*] loading crypto constants")
    for const in non_sparse_consts:
        const["byte_array"] = convert_to_byte_array(const)

    for start in idautils.Segments():
        print("[*] searching for crypto constants in %s" % idc.get_segm_name(start))
        ea = start
        while ea < idc.get_segm_end(start):
            bbbb = list(struct.unpack("BBBB", idc.get_bytes(ea, 4)))
            for const in non_sparse_consts:
                if bbbb != const["byte_array"][:4]:
                    continue
                if map(lambda x:ord(x), idc.get_bytes(ea, len(const["byte_array"]))) == const["byte_array"]:
                    print(("0x%0" + str(digits) + "X: found const array %s (used in %s)") % (ea, const["name"], const["algorithm"]))
                    idc.set_name(ea, const["name"])
                    if const["size"] == "B":
                        idc.create_byte(ea)
                    elif const["size"] == "L":
                        idc.create_dword(ea)
                    elif const["size"] == "Q":
                        idc.create_qword(ea)
                    idc.make_array(ea, len(const["array"]))
                    ea += len(const["byte_array"]) - 4
                    break
            ea += 4

        ea = start
        if idc.get_segm_attr(ea, idc.SEGATTR_TYPE) == 2:
            while ea < idc.get_segm_end(start):
                d = ida_bytes.get_dword(ea)
                for const in sparse_consts:
                    if d != const["array"][0]:
                        continue
                    tmp = ea + 4
                    for val in const["array"][1:]:
                        for i in range(8):
                            if ida_bytes.get_dword(tmp + i) == val:
                                tmp = tmp + i + 4
                                break
                        else:
                            break
                    else:
                        print(("0x%0" + str(digits) + "X: found sparse constants for %s") % (ea, const["algorithm"]))
                        cmt = idc.get_cmt(idc.prev_head(ea), 0)
                        if cmt:
                            idc.set_cmt(idc.prev_head(ea), cmt + ' ' + const["name"], 0)
                        else:
                            idc.set_cmt(idc.prev_head(ea), const["name"], 0)
                        ea = tmp
                        break
                ea += 1
    print("[*] finished")
Esempio n. 10
0
def main():
    print("[*] loading crypto constants")
    for const in non_sparse_consts:
        const["byte_array"] = convert_to_byte_array(const)

    for start in Segments():
        print("[*] searching for crypto constants in %s" %
              get_segm_name(start))
        ea = start
        while ea < get_segm_end(start):
            bbbb = list(struct.unpack("BBBB", get_bytes(ea, 4)))
            for const in non_sparse_consts:
                if bbbb != const["byte_array"][:4]:
                    continue
                if map(lambda x: ord(x), get_bytes(ea, len(
                        const["byte_array"]))) == const["byte_array"]:
                    print("0x%08X: found const array %s (used in %s)" %
                          (ea, const["name"], const["algorithm"]))
                    set_name(ea, const["name"])
                    if const["size"] == "B":
                        idc.create_byte(ea)
                    elif const["size"] == "L":
                        idc.create_dword(ea)
                    elif const["size"] == "Q":
                        idc.create_qword(ea)
                    make_array(ea, len(const["array"]))
                    ea += len(const["byte_array"]) - 4
                    break
            ea += 4

        ea = start
        if get_segm_attr(ea, SEGATTR_TYPE) == 2:
            while ea < get_segm_end(start):
                d = ida_bytes.get_dword(ea)
                for const in sparse_consts:
                    if d != const["array"][0]:
                        continue
                    tmp = ea + 4
                    for val in const["array"][1:]:
                        for i in range(8):
                            if ida_bytes.get_dword(tmp + i) == val:
                                tmp = tmp + i + 4
                                break
                        else:
                            break
                    else:
                        print("0x%08X: found sparse constants for %s" %
                              (ea, const["algorithm"]))
                        ea = tmp
                        break
                ea += 1
    print("[*] finished")
Esempio n. 11
0
 def is_method_a_getter(self, sel, f=None):
     base_props = ida_bytes.get_qword(self.info + 0x40)
     if not base_props:
         return False
     entrysize = ida_bytes.get_dword(base_props)
     count = ida_bytes.get_dword(base_props + 4)
     p_ea = base_props + 8
     for i in range(count):
         p_name = idc.get_bytes(idc.Qword(p_ea), idc.get_item_size(idc.Qword(p_ea)) - 1)
         if p_name == sel:
             return True
         p_ea += entrysize
     return False
Esempio n. 12
0
def callback2(ea):
    print("Found ref to cmd string at 0x%08X" % ea)
    ref=ida_bytes.get_dword(ea)&0xFFFF0000
    for i in range(0,0x1000*4,0x10):
        value=ida_bytes.get_dword(ea+i)
        if value&0xFFFF0000 != ref:
            valbyte=ida_bytes.get_byte(ea+i)
            if valbyte==ord('$') or valbyte==ord('!') or valbyte==ord('+') or valbyte==ord('^') or valbyte==ord('*'):
                return ea+i
            break
        logger.debug("cmd_ref:%x" % (ea+i))
        references.append(ea+i)
    return 0
Esempio n. 13
0
def rename_guids():
    labels = {}
    # Load GUIDs
    guids = dict(
        (str(GUID(array=v)), k) for k, v in efiguids.GUIDs.iteritems()
    )
    guids.update(dict((v, k) for k, v in local_guids.iteritems()))

    # Find all the data segments in this binary
    for seg_addr in idautils.Segments():
        seg = ida_segment.getseg(seg_addr)
        if seg.type == ida_segment.SEG_DATA or True:
            print "Processing data segment at 0x{:08x}".format(seg_addr)

            # Find any GUIDs we know about in the data segment
            cur_addr = seg.start_ea
            seg_end = seg.end_ea
            while cur_addr < seg_end:
                d = [ida_bytes.get_dword(cur_addr),
                     ida_bytes.get_dword(cur_addr+0x4),
                     ida_bytes.get_dword(cur_addr+0x8),
                     ida_bytes.get_dword(cur_addr+0xC)]
                if (d[0] == 0 and d[1] == 0 and d[2] == 0 and d[3] == 0) or \
                   (
                    d[0] == 0xFFFFFFFF and d[1] == 0xFFFFFFFF and
                    d[2] == 0xFFFFFFFF and d[3] == 0xFFFFFFFF
                   ):
                    cur_addr += 0x10
                else:
                    guid = GUID(bytes=struct.pack(
                        "<LLLL", d[0], d[1], d[2], d[3]
                    ))
                    gstr = str(guid)
                    if gstr in guids.keys():
                        print "  - Found GUID {} ({}) at 0x{:08x}".format(
                            gstr, guids[gstr], cur_addr
                        )
                        struct_label = get_next_unused_label(
                            underscore_to_global(guids[gstr])
                        )
                        ida_name.set_name(cur_addr, struct_label)
                        labels[struct_label] = (cur_addr, guids[gstr])
                        cur_addr += 0xf
                    cur_addr += 0x01
        else:
            print "Skipping non-data segment at 0x{:08x}".format(seg_addr)

    return labels
Esempio n. 14
0
File: ESigs.py Progetto: newmsk/ESig
def get_E_main():
    # .text:00485090 55                          push    ebp
    # .text:00485091 8B EC                       mov     ebp, esp
    # .text:00485093 51                          push    ecx
    # .text:00485094 53                          push    ebx
    # .text:00485095 56                          push    esi
    # .text:00485096 8B F1                       mov     esi, ecx
    # .text:00485098 57                          push    edi
    # .text:00485099 8B 4E 68                    mov     ecx, [esi+68h]
    # .text:0048509C 8D 86 D8 00 00 00           lea     eax, [esi+0D8h]
    # .text:004850A2 50                          push    eax             ; int
    # .text:004850A3 51                          push    ecx             ; hModule
    # .text:004850A4 E8 C7 D3 00 00              call    krnln_?GetInstancePath@@YAXPAUHINSTANCE__@@AAVCString@@@Z
    E_main_pat = "55 8B EC 51 53 56 8B F1 57 8B 4E 68 8D 86 D8 00 00 00 50 51 E8"
    E_main_call_ins_offset = 0x37

    E_main_func_ea = 0
    code_segs = get_code_segs()
    for seg in code_segs:
        start_ea = seg.start_ea
        end_ea = seg.end_ea
        E_main_pat_ea = ida_search.find_binary(start_ea, end_ea, E_main_pat,
                                               16, ida_search.SEARCH_DOWN)
        if E_main_pat_ea != idaapi.BADADDR:
            call_ins_ea = E_main_pat_ea + E_main_call_ins_offset
            addr_off = ida_bytes.get_dword(call_ins_ea + 1)
            E_main_func_ea = call_ins_ea + 5 + idaapi.as_int32(addr_off)
            print("Find E_main addr 0x%X" % (E_main_func_ea))
            break

    return E_main_func_ea
Esempio n. 15
0
def method_list(ea):
    if not ea:
        return

    count = ida_bytes.get_dword(ea + 4)
    name = idc.get_segm_name(ea)
    first = ea + 8

    def post14format(addr):
        for _ in range(3):
            data = ida_bytes.get_bytes(addr, 4)
            offset, = struct.unpack('<i', data)
            yield addr + offset
            addr += 4
        
    is14 = name and (name.endswith(':__objc_const_ax') or name.endswith(':__objc_methlist'))
    for i in range(count):
        if is14:
            # iOS 14
            yield Post14Method(*post14format(first + i * 12))

        else:
            ea_method_t = first + i * Objc2Method.length
            data = ida_bytes.get_bytes(ea_method_t, Objc2Method.length)
            yield Objc2Method(data)
Esempio n. 16
0
    def search_idb(self):
        """Search IDB for possible MZ/PE headers"""
        # Search all segments
        for seg in idautils.Segments():
            s = idc.get_segm_start(seg)
            e = idc.get_segm_end(seg)
            addr = s

            while True:
                # Find first byte of MZ header
                addr = ida_bytes.find_byte(addr, e-addr, 0x4d, 0)

                if addr == ida_idaapi.BADADDR or addr >= e:
                    break

                # Check for MZ magic
                if ida_bytes.get_word(addr) == 0x5a4d:
                    # Ensure the PE header is in the segment
                    e_lfanew = ida_bytes.get_dword(addr + 0x3c)

                    if addr + e_lfanew + 1 < e:
                        # Check for PE magic
                        if ida_bytes.get_word(addr + e_lfanew) == 0x4550:
                            # Found possible MZ/PE file
                            self.form.runtime.log("0x{:08x} - {}".format(addr, idc.get_segm_name(s)))

                            self.form.map_pe(image_base=addr)

                # Resume search from next address
                addr += 1
Esempio n. 17
0
def capstone_disas(ea):
    global cs

    insn = ida_bytes.get_dword(ea)
    insn_bytes = insn.to_bytes(4, byteorder='little')

    return cs.disasm(insn_bytes, ea)
Esempio n. 18
0
def analyze_str_ptr(start_ea, end_ea):
    str_cnt = 0
    start_time = time.time()

    # First, find string references. strings referenced by pointers are highly
    # likely string.
    ea = start_ea
    while ea != idc.BADADDR and ea < end_ea:
        status, ea = is_assigned(ea)
        if status:
            continue

        str_ptr = ida_bytes.get_dword(ea)
        if idc.get_str_type(str_ptr) is not None or check_string(str_ptr, 8):
            # even already assigned strings may not have reference.
            ida_offset.op_offset(ea, 0, idc.REF_OFF32)

            if idc.get_str_type(str_ptr) is None:
                create_string(str_ptr)

            str_cnt += 1
            if str_cnt % 10000 == 0:
                print("%x: %d strings has been found. (%0.3f secs)" %
                      (ea, str_cnt, time.time() - start_time))

        ea = next_addr_aligned(ea, 4)

    print("Created %d strings. (%0.3f secs)" %
          (str_cnt, time.time() - start_time))
Esempio n. 19
0
def find_parse_ip(li, ea, parsecode):
    # TODO check memory for SEGA SATURN string
    # segaSaturn = li.read(16)
    # warning(segaSaturn+' '+str(li.tell()))
    ida_bytes.create_strlit(ea, 16, ida_nalt.STRTYPE_C)
    ida_bytes.create_strlit(ea + 0x10, 16, ida_nalt.STRTYPE_C)
    ida_bytes.create_strlit(ea + 0x20, 10, ida_nalt.STRTYPE_C)
    ida_bytes.create_strlit(ea + 0x2A, 6, ida_nalt.STRTYPE_C)
    ida_bytes.create_strlit(ea + 0x30, 8, ida_nalt.STRTYPE_C)
    ida_bytes.create_strlit(ea + 0x38, 8, ida_nalt.STRTYPE_C)
    ida_bytes.create_strlit(ea + 0x40, 10, ida_nalt.STRTYPE_C)
    ida_bytes.create_strlit(ea + 0x4A, 6, ida_nalt.STRTYPE_C)
    ida_bytes.create_strlit(ea + 0x50, 16, ida_nalt.STRTYPE_C)
    ida_bytes.create_strlit(ea + 0x60, 0x70, ida_nalt.STRTYPE_C)
    ida_bytes.create_byte(ea + 0xD0, 16)
    ida_bytes.create_dword(ea + 0xE0, 4)
    ida_bytes.create_dword(ea + 0xE4, 4)
    ida_bytes.create_dword(ea + 0xE8, 4)
    ida_bytes.create_dword(ea + 0xEC, 4)
    ida_bytes.create_dword(ea + 0xF0, 4)
    ida_funcs.add_func(ida_bytes.get_dword(ea + 0xF0), ida_idaapi.BADADDR)
    ida_bytes.create_dword(ea + 0xF4, 4)
    ida_bytes.create_dword(ea + 0xF8, 4)
    ida_bytes.create_dword(ea + 0xFC, 4)
    if parsecode:
        ida_funcs.add_func(ea + 0x100, ida_idaapi.BADADDR)
    return 1
Esempio n. 20
0
def find_pointers(start, end):
    for va in range(start, end - 0x8):
        ptr = ida_bytes.get_qword(va)
        if idc.get_segm_start(ptr) != idc.BADADDR:
            yield va, ptr, 8
        ptr = ida_bytes.get_dword(va)
        if idc.get_segm_start(ptr) != idc.BADADDR:
            yield va, ptr, 4
Esempio n. 21
0
File: ESigs.py Progetto: newmsk/ESig
 def load_flirt_sigs(self):
     elib_count = ida_bytes.get_dword(self.E_info_entry_ea +
                                      self.elib_count_offset)
     elibs_start_ea = ida_bytes.get_dword(self.E_info_entry_ea +
                                          self.elib_infos_entry_offset)
     self.elibs = Elibs(elibs_start_ea, elib_count)
     for elib in self.elibs:
         if elib.sig_name:
             rc = ida_funcs.plan_to_apply_idasgn(elib.sig_name)
             if rc == 0:
                 print(
                     "Plan to apply %s ida signature error, may be there is no correspoing sig file in sig folder !!!"
                     % elib.sig_name)
         else:
             print(
                 "There is no known sigature file corresponding to the library %s, you can make it by yourself !!!"
                 % elib.name)
Esempio n. 22
0
def find_ptr(pattern: str,
             expected: int = 1,
             index: int = 0,
             offset: int = 0) -> int:
    addr = find_pattern(pattern, expected, index)
    disp = ida_bytes.get_dword(addr + offset)

    # Real address is: pattern_addr + offset + displacement + size_of_displacement.
    return addr + offset + disp + 4
Esempio n. 23
0
def find_funcname_ptr(ea, n):
    for i in range(4, n * 4, 4):
        name_ptr = ida_bytes.get_dword(ea + i)
        # this might be a function, so break and proceed next check
        if name_ptr & 1 == 1:
            return
        elif check_funcname(name_ptr):
            return ea + i
    return
Esempio n. 24
0
    def read_xword(self):
        if bitness == 32:
            res = ida_bytes.get_dword(self.addr)
        elif bitness == 64:
            res = ida_bytes.get_qword(self.addr)
        else:  # bitness == 16
            res = ida_bytes.get_word(self.addr)
        self.inc(self.bitness >> 3)

        return res
Esempio n. 25
0
def method_list(ea):
    if not ea:
        return

    count = ida_bytes.get_dword(ea + 4)
    first = ea + 8
    for i in range(count):
        ea_method_t = first + i * Objc2Method.length
        data = ida_bytes.get_bytes(ea_method_t, Objc2Method.length)
        yield Objc2Method(data)
Esempio n. 26
0
    def extract_info_from_IDA(self):
        for xref in idautils.XrefsTo(self.ea):
            frm = xref.frm
            if idc.SegName(frm) == '__objc_classrefs':
                self.classref = frm
            if idc.SegName(frm) == '__objc_superrefs':
                self.superref = frm

        base_ivars = ida_bytes.get_qword(self.info + 0x30)
        if base_ivars and idc.SegName(base_ivars) == '__objc_const':
            entrysize = ida_bytes.get_dword(base_ivars)
            count = ida_bytes.get_dword(base_ivars + 4)
            ea = base_ivars + 8
            for i in range(count):
                offset = ida_bytes.get_dword(idc.get_qword(ea))
                _type = idc.get_bytes(idc.Qword(ea + 0X10), idc.get_item_size(idc.Qword(ea + 0X10)) - 1)
                _name = idc.get_bytes(idc.Qword(ea + 0X08), idc.get_item_size(idc.Qword(ea + 0X08)) - 1)
                # self.ivars[offset] = _type
                self.ivars[_name] = _type
                ea += entrysize

        base_props = ida_bytes.get_qword(self.info + 0x40)
        if base_props and idc.SegName(base_props) == '__objc_const':
            entrysize = ida_bytes.get_dword(base_props)
            count = ida_bytes.get_dword(base_props + 4)
            ea = base_props + 8
            for i in range(count):
                _type = idc.get_bytes(idc.Qword(ea + 0X08), idc.get_item_size(idc.Qword(ea + 0X08)) - 1)
                _name = idc.get_bytes(idc.Qword(ea), idc.get_item_size(idc.Qword(ea)) - 1)
                self.props[_name] = _type
                ea += entrysize

        base_prots = ida_bytes.get_qword(self.info + 0x28)
        if base_prots and idc.SegName(base_prots) == '__objc_const':
            count = ida_bytes.get_qword(base_prots)
            entrysize = 0x8
            p_ea = base_prots + 8
            for i in range(count):
                proto_ea = idc.get_qword(p_ea)
                self.prots.append(proto_ea)
                Protocol.add_implementing_class(proto_ea, self.ea)
                p_ea += entrysize
def find_mclib_jumper():
    """Retrieves the address of the McLib jumper fills by the loader during
    the trustlet loading process

    :return: McLib jumper address
    :rtype: int
    """
    segm = ida_segment.get_segm_by_name("rtm")
    mclib_jumper = ida_bytes.get_dword(segm.start_ea + 0x8C)

    return mclib_jumper
def set_name_prototype_tl_dr_function(api_number):
    """Set the name and the prototype of the TL/DR API function associated with the given function number

    :param api_number: API function number
    :type api_number: int
    """
    global MAX_TL_API
    global MAX_DR_API

    tl_api_name, tl_api_type, dr_api_name, dr_api_type = get_apis_name_type(api_number)
    index = api_number * 4

    if api_number < MAX_TL_API:
        if not tl_api_name:
            pass
        else:
            dword = ida_bytes.get_dword(tl_table + index)
            func = ida_funcs.get_func(dword)
            if func is None:
                MAX_TL_API = dword
            else:
                func_name = ida_name.get_name(func.start_ea)
                print("[*] Renaming function %s to %s" % (func_name, tl_api_name))
                ida_name.set_name(func.start_ea, encode(tl_api_name), ida_name.SN_FORCE)
                if tl_api_type:
                    set_function_prototype(func, encode(tl_api_type))

    if api_number < MAX_DR_API:
        if not dr_api_name:
            pass
        else:
            dword = ida_bytes.get_dword(dr_table + index)
            func = ida_funcs.get_func(dword)
            if func is None:
                MAX_DR_API = dword
            else:
                func_name = ida_name.get_name(func.start_ea)
                print("[*] Renaming function %s to %s" % (func_name, tl_api_name))
                ida_name.set_name(func.start_ea, encode(dr_api_name), ida_name.SN_FORCE)
                if dr_api_type:
                    set_function_prototype(func, encode(dr_api_type))
Esempio n. 29
0
def process_node(addr):
    global node_info

    if addr in node_info:
        node_info[addr]['first'] = False
        return node_info[addr]

    arg0  = ida_bytes.get_dword(addr)
    arg1  = ida_bytes.get_dword(addr + 0x4)
    func  = ida_bytes.get_dword(addr + 0x8)
    n_out = ida_bytes.get_dword(addr + 0xC)
    out_ptr = ida_bytes.get_dword(addr + 0x10)
    out = [ida_bytes.get_dword(out_ptr + 4*i) for i in range(n_out)]

    info = {
        'arg0'   : arg0, 
        'arg1'   : arg1,
        'func'   : func,
        'n_out'  : n_out,
        'out'    : out,
    }

    node_info[addr] = info

    return info
Esempio n. 30
0
 def followAddress(self, address):
     b = idaapi.get_byte(address)
     if (b == 0xE8):
         callOffset = ida_bytes.get_dword(address + 1)
         if (callOffset > 2147483647):
             callOffset -= 4294967296
         address = address + 5 + callOffset
         return address, False
     elif (b == 0xE9):
         # Lazy and none of my signatures use this yet...
         return address, "JMP Instruction signatures not supported yet"
     else:
         return address, False
Esempio n. 31
0
    def _defineImportThunk(self, start, thunk_val):
        """If the binary has the Import Thunk filled, define it as a data chunk of appropriate size.
        """

        info = idaapi.get_inf_structure()
        if info.is_64bit():
            curr_val = idc.get_qword(start)
            if (curr_val == thunk_val):
                return ida_bytes.create_data(start, idaapi.FF_QWORD, 8,
                                             idaapi.BADADDR)
        elif info.is_32bit():
            curr_val = ida_bytes.get_dword(start)
            if (curr_val == thunk_val):
                return ida_bytes.create_data(start, idaapi.FF_DWORD, 4,
                                             idaapi.BADADDR)
        return False