Beispiel #1
0
def main():
    tid = get_guid_tid()
    for type_name, type_prefix, filepath in GUID_LIST:
        print('[*] scanning {}'.format(type_name))
        fp = open(filepath, 'r')
        for line in fp.readlines():
            line = line.strip()
            if line == "":
                continue
            guid, guid_name = line.split(' ')
            guid_name = type_prefix + guid_name
            binary_pattern = make_binary_pattern(guid)

            ea = 0
            while True:
                ea = idc.find_binary(
                    ea, ida_search.SEARCH_DOWN | ida_search.SEARCH_NEXT
                    | ida_search.SEARCH_NOSHOW, binary_pattern)
                if ea == idaapi.BADADDR:
                    break

                idc.del_items(ea, 16, 0)
                ida_bytes.create_struct(ea, ida_struct.get_struc_size(tid),
                                        tid)
                if idc.set_name(ea, guid_name, ida_name.SN_NOWARN) != 1:
                    for i in range(0, 100):
                        if idc.set_name(ea, guid_name + "_" + str(i),
                                        ida_name.SN_NOWARN) == 1:
                            break
                    else:
                        print("[!] 0x{:X}: failed to apply {}".format(
                            ea, guid_name))
                print("[*] 0x{:X}: {}".format(ea, guid_name))

    print("[*] finished")
Beispiel #2
0
    def load(infos):
        for info in infos:
            ida_name.set_name(info['address'], info['name'])
            type = info.get('type', None)

            # TODO this code is kind of mashed together... not sure of the
            # right way.
            tid = ida_struct.get_struc_id(type) if type else BADADDR
            if type:
                ida_bytes.create_struct(info['address'], info['sz'], tid)
            ida_bytes.create_data(
                info['address'], info['flags'], info['sz'], tid)
Beispiel #3
0
    def load(infos):
        for info in infos:
            ida_name.set_name(info['address'], info['name'])

            # TODO this code is kind of mashed together... not sure of the
            # right way.
            tid = ida_struct.get_struc_id(
                info['type']) if info['type'] else BADADDR
            if info['type']:
                print(info['type'], hex(tid))
                ida_bytes.create_struct(info['address'], info['sz'], tid)
            ida_bytes.create_data(info['address'], info['flags'], info['sz'],
                                  tid)
Beispiel #4
0
def force_make_struct(ea, struct_name):
    sptr = get_sptr_by_name(struct_name)
    if sptr == BADADDR:
        return False
    s_size = ida_struct.get_struc_size(sptr)
    ida_bytes.del_items(ea, ida_bytes.DELIT_SIMPLE, s_size)
    return ida_bytes.create_struct(ea, s_size, sptr.id)
Beispiel #5
0
def force_make_struct(ea, struct_name):
    """@return: True on success, False on failure"""
    sid = idc.get_struc_id(struct_name)
    if sid == BADADDR:
        log.warn("Structure not found: %s", struct_name)
        return False
    size = idc.get_struc_size(sid)
    if not size:
        log.warn("Structure with zero size: %s", struct_name)
        return False
    if not ida_bytes.del_items(ea, ida_bytes.DELIT_SIMPLE, size):
        log.warn("Failed to delete structure items: %s", struct_name)
        return False
    return ida_bytes.create_struct(ea, size, sid)
Beispiel #6
0
 def apply_struct(ea, size, sid):
     ida_bytes.del_items(ea, size, idc.DELIT_DELNAMES)
     ida_bytes.create_struct(ea, size, sid)
     return size
Beispiel #7
0
def update_vtable_struct(
    functions_ea,
    vtable_struct,
    class_name,
    this_type=None,
    get_next_func_callback=get_vtable_line,
    vtable_head=None,
    ignore_list=None,
    add_dummy_member=False,
    pure_virtual_name=None,
    parent_name=None,
    add_func_this=True,
    force_rename_vtable_head=False,  # rename vtable head even if it is already named by IDA
    # if it's not named, then it will be renamed anyway
):
    # pylint: disable=too-many-arguments,too-many-locals,too-many-branches
    # TODO: refactor
    if this_type is None:
        this_type = utils.get_typeinf_ptr(class_name)
    if not add_func_this:
        this_type = None
    func_ea, next_func = get_next_func_callback(
        functions_ea,
        ignore_list=ignore_list,
        pure_virtual_name=pure_virtual_name,
    )
    dummy_i = 1
    offset = 0
    while func_ea is not None:
        new_func_name, _ = update_func_name_with_class(func_ea, class_name)
        func_ptr = None
        if ida_hexrays.init_hexrays_plugin():
            fix_userpurge(func_ea, idc.TINFO_DEFINITE)
            update_func_this(func_ea, this_type, idc.TINFO_DEFINITE)
            func_ptr = utils.get_typeinf_ptr(utils.get_func_tinfo(func_ea))
        else:
            func_ptr = make_funcptr_pt(func_ea, this_type)  # TODO: maybe try to get or guess type?
        if add_dummy_member:
            utils.add_to_struct(vtable_struct, "dummy_%d" % dummy_i, func_ptr)
            dummy_i += 1
            offset += utils.WORD_LEN
        ptr_member = utils.add_to_struct(
            vtable_struct, new_func_name, func_ptr, offset, overwrite=True, is_offs=True
        )
        if ptr_member is None:
            log.error(
                "Couldn't add %s(%s) to vtable struct 0x%X at offset 0x%X",
                new_func_name,
                str(func_ptr),
                vtable_struct.id,
                offset,
            )
        offset += utils.WORD_LEN
        if not ida_xref.add_dref(ptr_member.id, func_ea, ida_xref.XREF_USER | ida_xref.dr_I):
            log.warn(
                "Couldn't create xref between member %s and func %s",
                ida_struct.get_member_name(ptr_member.id),
                idc.get_name(func_ea),
            )
        func_ea, next_func = get_next_func_callback(
            next_func,
            ignore_list=ignore_list,
            pure_virtual_name=pure_virtual_name,
        )

    vtable_size = ida_struct.get_struc_size(vtable_struct)

    if vtable_head is None:
        vtable_head = functions_ea
    # ida_bytes.del_items(vtable_head, ida_bytes.DELIT_SIMPLE, vtable_size)
    ida_bytes.create_struct(vtable_head, vtable_size, vtable_struct.id)
    if not idc.hasUserName(idc.get_full_flags(vtable_head)) or force_rename_vtable_head:
        if parent_name is None and this_type:
            parent = utils.deref_struct_from_tinfo(this_type)
            parent_name = ida_struct.get_struc_name(parent.id)
            if parent_name == class_name:
                parent_name = None
        idc.set_name(
            vtable_head,
            get_vtable_instance_name(class_name, parent_name),
            ida_name.SN_CHECK | ida_name.SN_FORCE,
        )
Beispiel #8
0
def load_file(f, neflags, format):
    f.seek(0)

    ida_idp.set_processor_type("metapc", ida_idp.SETPROC_LOADER)
    MGROUPStart = 0
    magic = f.read(2)

    if magic == MZ_HEADER_MAGIC:
        f.seek(0x22)
        MGROUPStart = DW(f) * 16
        f.seek(MGROUPStart)
        magic = f.read(2)

    headerSize = DW(f)
    segmentDataAlignment = DW(f)
    nextExeOff = DD(f)
    SegDataOff = DD(f)

    f.file2base(MGROUPStart, 0, SegDataOff, True)
    ida_segment.add_segm(0, 0, 0x50, "HEADER", "MODULE")
    f.seek(MGROUPStart + 2)

    headerSize = rnDW(f, "headerSize", MGROUPStart)
    segmentDataAlignment = rnDW(f, "segmentDataAlignment", MGROUPStart)
    nextExeOff = rnDD(f, "nextExeOff", MGROUPStart)
    SegDataOff = rnDD(f, "SegDataOff", MGROUPStart)

    ResDataOff = rnDD(f, "ResDataOff", MGROUPStart)
    flags = rnDW(f, "flags", MGROUPStart)
    version = rnDB(f, "version", MGROUPStart)
    revision = rnDB(f, "revision", MGROUPStart)
    AutoDataSegNo = rnDW(f, "AutoDataSegNo", MGROUPStart)
    HeapSize = rnDW(f, "HeapSize", MGROUPStart)
    StackSize = rnDW(f, "StackSize", MGROUPStart)
    StartProc = rnDD(f, "StartProc", MGROUPStart)
    LoadProc = rnDD(f, "LoadProc", MGROUPStart)
    FreeProc = rnDD(f, "FreeProc", MGROUPStart)
    nSegments = rnDW(f, "nSegments", MGROUPStart)
    pSegTable = rnDW(f, "pSegTable", MGROUPStart)
    cbResTab = rnDW(f, "cbResTab", MGROUPStart)
    pResTab = rnDW(f, "pResTab", MGROUPStart)
    cbEntTab = rnDW(f, "cbEntTab", MGROUPStart)
    pEntTab = rnDW(f, "pEntTab", MGROUPStart)
    cbNamTab = rnDW(f, "cbNamTab", MGROUPStart)
    pNamTab = rnDW(f, "pNamTab", MGROUPStart)
    cbStrTab = rnDW(f, "cbStrTab", MGROUPStart)
    pStrTab = rnDW(f, "pStrTab", MGROUPStart)
    cbNRNamTab = rnDW(f, "cbNRNamTab", MGROUPStart)
    pNRNamTab = rnDW(f, "pNRNamTab", MGROUPStart)

    ida_segment.add_segm(0, pSegTable,
                         pSegTable + (nSegments * SEG_STRUCT_SIZE), "SEGTABLE",
                         "MODULE")
    ida_segment.add_segm(0, pResTab, pResTab + cbResTab, "RESOURCES", "MODULE")
    ida_segment.add_segm(0, pEntTab, pEntTab + cbEntTab, "ENTTABLE", "MODULE")
    ida_segment.add_segm(0, pNamTab, pNamTab + cbNamTab, "ENTNAME", "MODULE")
    ida_segment.add_segm(0, pStrTab, pStrTab + cbStrTab, "IMPORTS", "MODULE")
    ida_segment.add_segm(0, pNRNamTab, pNRNamTab + cbNRNamTab, "NRENTNAME",
                         "MODULE")

    #parse segtable
    segentsid = defSEGENT()
    base = SegDataOff // 16

    importCount = 0
    for i in range(nSegments):
        segEntStart = pSegTable + i * SEG_STRUCT_SIZE
        ida_bytes.create_struct(segEntStart, SEG_STRUCT_SIZE, segentsid)
        segStart = ida_bytes.get_word(segEntStart + 2)
        segLen = ida_bytes.get_word(segEntStart + 4)
        segImports = ida_bytes.get_word(segEntStart + 6)
        importCount += segImports
        f.file2base(MGROUPStart + SegDataOff + segStart * 16,
                    SegDataOff + segStart * 16,
                    SegDataOff + (segStart + segLen) * 16, True)

        segBase = (base + segStart) * 16
        #segmentDef = ida_segment.segment_t()
        #segmentDef.start_ea = segBase
        #segmentDef.end_ea = (base+segStart+segLen)*16
        #ida_segment.set_selector()
        print(base + segStart)
        ida_segment.add_segm(base + segStart, segBase,
                             (base + segStart + segLen) * 16, "", "", 0)
        sel = ida_segment.find_selector(base + segStart)
        seg = ida_segment.getseg(segBase)
        ida_segment.set_segm_addressing(seg, 0)
        segtable[i] = seg
        segimportstable[i] = segImports
        if i + 1 == AutoDataSegNo:
            ida_segment.set_segm_name(seg, "DATA", 0)
            ida_segment.set_segm_class(seg, "DATA", 0)
            dataSel = sel
        else:
            ida_segment.set_segm_name(seg, "TEXT", 0)
            ida_segment.set_segm_class(seg, "CODE", 0)
            if AutoDataSegNo == 0:
                dataSel = sel
    ida_segregs.set_default_dataseg(dataSel)

    #parse enttable
    pENT = pEntTab
    currord = 1
    while pENT < pEntTab + cbEntTab:
        bundleCount = ida_bytes.get_byte(pENT)
        bundleFlags = ida_bytes.get_byte(pENT + 1)
        if bundleCount == 0 and bundleFlags == 0:
            break
        pENT += 2
        for i in range(bundleCount):
            if bundleFlags == 0xFF:
                ordFlags = ida_bytes.get_byte(pENT)
                if ordFlags & 0x80:
                    toexport.append(currord)
                segNo = ida_bytes.get_byte(pENT + 3)
                segOff = ida_bytes.get_word(pENT + 4)

                enttable[currord] = (segtable[segNo - 1].start_ea // 16,
                                     segOff)
                pENT += 6
            else:
                ordFlags = ida_bytes.get_byte(pENT)
                if ordFlags & 0x80:
                    toexport.append(currord)
                segOff = ida_bytes.get_word(pENT + 1)
                enttable[currord] = (segtable[bundleFlags - 1].start_ea // 16,
                                     segOff)
                pENT += 3

            currord += 1

    modulename = readPASSTR(pNamTab)

    make_entry(StartProc, modulename + "_start")
    make_entry(LoadProc, modulename + "_load")
    make_entry(FreeProc, modulename + "_free")

    #export named ordinals
    namedordtable = loadExportsF(f)

    for i in toexport:
        if i in namedordtable:
            name = namedordtable[i]
        else:
            name = "Ordinal" + str(i)
        (base, off) = enttable[i]
        addr = base * 16 + off
        ida_entry.add_entry(i, addr, name, 1)

    #process imports

    ida_segment.add_segm(0xF000, 0xF0000, 0xF0000 + importCount * 2, "IMPORTS",
                         "XTRN", 0)

    import_ea = 0xF0000

    for seg in segtable:
        segend = segtable[seg].end_ea
        f.seek(MGROUPStart + segend)

        for i in range(segimportstable[seg]):
            count = DB(f)
            mode = DB(f)
            relocStart = DW(f)
            module = DW(f)
            proc = DW(f)

            if (module == 0xFFFF):
                (base, off) = enttable[proc]
            else:
                modulestr = readPASSTR(pStrTab + module)
                if (proc & 0x8000) != 0:  # read by ord
                    ordinal = proc & 0x7FFF
                    procname = modulestr + "_Ordinal" + str(ordinal)
                    if not modulestr in importedmodules:
                        if os.path.isfile(modulestr + ".EXE"):
                            importedmodules[modulestr] = loadExports(
                                modulestr + ".EXE")
                        else:
                            filename = ida_kernwin.ask_file(
                                0, modulestr + ".EXE",
                                "Select file to name exports")
                            if filename is not None and os.path.isfile(
                                    filename):
                                importedmodules[modulestr] = loadExports(
                                    filename)
                            else:
                                importedmodules[modulestr] = None
                    if modulestr in importedmodules and (
                            importedmodules[modulestr] is not None
                    ) and ordinal in importedmodules[modulestr]:
                        procname = importedmodules[modulestr][ordinal]
                else:
                    procname = readPASSTR(pStrTab + proc)
                ida_bytes.create_data(import_ea, ida_bytes.FF_WORD, 2,
                                      ida_idaapi.BADADDR)
                ida_name.force_name(import_ea, procname)
                ida_bytes.set_cmt(import_ea, "Imported from " + modulestr, 1)
                base = 0xF000
                off = import_ea - 0xF0000
                import_ea += 2

            for xx in range(count):
                next = ida_bytes.get_word(segtable[seg].start_ea + relocStart)
                if mode == 0x20:
                    ida_bytes.put_word(segtable[seg].start_ea + relocStart + 2,
                                       base)
                    ida_bytes.put_word(segtable[seg].start_ea + relocStart,
                                       off)
                elif mode == 0x10:
                    ida_bytes.put_word(segtable[seg].start_ea + relocStart,
                                       off)
                elif mode == 0x0:
                    ida_bytes.put_word(segtable[seg].start_ea + relocStart,
                                       base)
                relocStart = next

            #print "import %d: seg %d mode %s count %d relocStart %s module %s proc %s" % (i, seg, hex(mode), count, hex(relocStart), modulestr, hex(proc))

    return 1
Beispiel #9
0
if sid == idaapi.BADADDR:
    print("Structure {} does not exist".format(name))

i=0
lastea=0
names={}
firstcmdid=0
for ea in references:
    nameptr=ida_bytes.get_dword(ea)
    cmdid=ida_bytes.get_word(ea+0xA)
    if firstcmdid==0:
        firstcmdid=cmdid
    name=get_string(nameptr)
    names[cmdid]=name
    ida_bytes.del_items(ea, ida_bytes.DELIT_DELNAMES,0x10)
    ida_bytes.create_struct(ea, 0x10, sid)
    print(f"EA:{hex(ea)} Name:{name} Cmdid:{hex(cmdid)}")
    #idc.set_cmt(ea, str(i),0)
    i+=1
    lastea=ea

create_cmdptr()
sid = ida_struct.get_struc_id("cmd_ptr")
ssize = ida_struct.get_struc_size(sid)
eas=search_ea("FC 3A 00 00","",None,startea-0x3000,lastea)
sea=None
for ea in eas:
    cmdid=ida_bytes.get_dword(ea+8)
    if cmdid==0x3AFD:
        sea=ea
        break
Beispiel #10
0
def update_vtable_struct(
    functions_ea,
    vtable_struct,
    class_name,
    this_type=None,
    get_next_func_callback=get_vtable_line,
    vtable_head=None,
    ignore_list=None,
    add_dummy_member=False,
    pure_virtual_name=None,
    parent_name=None,
    add_func_this=True,
):
    is_first_member = True
    if this_type is None:
        this_type = utils.get_typeinf_ptr(class_name)
    if not add_func_this:
        this_type = None
    func, next_func = get_next_func_callback(
        functions_ea, ignore_list=ignore_list, pure_virtual_name=pure_virtual_name
    )
    dummy_i = 1
    while func is not None:
        new_func_name, is_name_changed = update_func_name_with_class(func, class_name)
        func_ptr = None
        if ida_hexrays.init_hexrays_plugin():
            if is_name_changed:
                func_type = update_func_this(func, this_type)
            else:
                func_type = update_func_this(func, None)
            if func_type is not None:
                func_ptr = utils.get_typeinf_ptr(func_type)
        else:
            func_ptr = make_funcptr_pt(func, this_type)
        if add_dummy_member:
            utils.add_to_struct(vtable_struct, f"dummy_{dummy_i}", func_ptr)
            dummy_i += 1
        if is_first_member:
            # We did an hack for vtables contained in union vtable with one dummy member
            ptr_member = utils.add_to_struct(
                vtable_struct, new_func_name, func_ptr, 0, overwrite=True
            )
            is_first_member = False
        else:
            ptr_member = utils.add_to_struct(
                vtable_struct, new_func_name, func_ptr, is_offset=True
            )
        if ptr_member is None:
            logging.exception(
                "Couldn't add %s(%s) to %d",
                new_func_name,
                str(func_ptr),
                vtable_struct.id,
            )
        ida_xref.add_dref(ptr_member.id, func, ida_xref.XREF_USER | ida_xref.dr_I)
        func, next_func = get_next_func_callback(
            next_func, ignore_list=ignore_list, pure_virtual_name=pure_virtual_name
        )

    vtable_size = ida_struct.get_struc_size(vtable_struct)

    if vtable_head is None:
        vtable_head = functions_ea
    ida_bytes.del_items(vtable_head, ida_bytes.DELIT_SIMPLE, vtable_size)
    ida_bytes.create_struct(vtable_head, vtable_size, vtable_struct.id)
    if parent_name is None and this_type:
        parent = utils.deref_struct_from_tinfo(this_type)
        parent_name = ida_struct.get_struc_name(parent.id)
        if parent_name == class_name:
            parent_name = None
    utils.set_name_retry(vtable_head, get_vtable_instance_name(class_name, parent_name))