Гайд IDA interfaces & cvars renamer script

Пользователь
Статус
Оффлайн
Регистрация
22 Июн 2020
Сообщения
183
Реакции[?]
69
Поинты[?]
37K
Два скрипта для переименования интерфейсов и кваров, а так же их колббеков. Может переименовать не все интерфейсы, но большинство.
Скрипт для переименования кваров основан на скрипте никсера и обновлен, а так же немного улучшен.
Работает на IDA 8.3, другие версии не проверял, оба скрипта работают для многих дллок игры.
1712172799641.png1712172804422.png
auto_cvars.py:
import idc
import idautils
import ida_bytes
import ida_segment
import ida_funcs
import ida_ua
import ida_idp


def find_pattern(pattern):
    text_segm = ida_segment.get_segm_by_name(".text")
    start_ea = text_segm.start_ea
    end_ea = text_segm.end_ea

    compiled_pats = ida_bytes.compiled_binpat_vec_t()
    err = ida_bytes.parse_binpat_str(compiled_pats, start_ea, pattern, 16)
    if err:
        print(f"Failed to find pattern {err}!")
        return idc.BADADDR
    return ida_bytes.bin_search(start_ea, end_ea, compiled_pats, 0)


# ConVar register functions
cvar_funcs = {
    "RegisterConVar": find_pattern("48 89 5C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 55 41 54 41 55 41 56 41 57 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B 7D"),
    "RegisterConCommand": find_pattern("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC ? 65 48 8B 04 25 ? ? ? ? 48 8B D9 44 8B 15"),
    "RegisterConVar_Simple": find_pattern("40 53 48 81 EC ? ? ? ? 0F 57 C0 48 C7 41"),
    "RegisterConVar_Float": find_pattern("48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC ? 48 8B DA 0F 29 74 24 ? BA")
}

found_cvars = []
# Rename all functions
for func, addr in cvar_funcs.items():
    if addr == idc.BADADDR:
        print(f"Failed to find function {func}!")
        continue

    idc.set_name(addr, func)
   
    for ref in idautils.CodeRefsTo(addr, 0):
        if ida_ua.ua_mnem(ref) != "call": # Reference is not call
            continue

        initer_func = ida_funcs.get_func(ref)

        cvar_name = None
        cvar_addr = None
        callback_addr = None
        for item in ida_funcs.func_item_iterator_t(initer_func):
            if item >= ref:
                break

            if ida_ua.ua_mnem(item) != "lea":
                continue
           
            if idc.get_operand_type(item, 0) != ida_ua.o_reg:
                continue

            if func == "RegisterConCommand" and idc.get_operand_value(item, 0) == ida_idp.str2reg("rax") and idc.get_segm_name(idc.get_operand_value(item, 1)) == ".text" and callback_addr is None:
                callback_addr = idc.get_operand_value(item, 1)
                continue

            if idc.get_operand_value(item, 0) == ida_idp.str2reg("rcx") and idc.get_segm_name(idc.get_operand_value(item, 1)) == ".data" and cvar_addr is None:
                cvar_addr = idc.get_operand_value(item, 1)
                continue

            if idc.get_operand_value(item, 0) == ida_idp.str2reg("rdx") and idc.get_segm_name(idc.get_operand_value(item, 1)) == ".rdata":
                cvar_name = idc.get_strlit_contents(idc.get_operand_value(item, 1))
                continue


        if cvar_addr is not None and cvar_name is not None:
            name = cvar_name.decode("utf8")
            found_cvars.append(name)
            cnt = found_cvars.count(name)
            if cnt > 1:
                name += "_" + str(cnt - 1)
            if name[0] in "+-":
                name = ("plus_" if name[0] == "+" else "minus_") + name[1:]
            if callback_addr is not None:
                idc.set_name(callback_addr, name + "_callback")
            name = name.rstrip()
            idc.set_name(cvar_addr, name.rstrip())


print(f"Renamed {len(found_cvars)} cvars")
auto_interfaces:
import idc
import idautils
import ida_bytes
import ida_segment
import string


def find_pattern(pattern):
    text_segm = ida_segment.get_segm_by_name(".text")
    start_ea = text_segm.start_ea
    end_ea = text_segm.end_ea

    compiled_pats = ida_bytes.compiled_binpat_vec_t()
    err = ida_bytes.parse_binpat_str(compiled_pats, start_ea, pattern, 16)
    if err:
        print(f"Failed to find pattern {err}!")
        return idc.BADADDR
    return ida_bytes.bin_search(start_ea, end_ea, compiled_pats, 0)


def read_interface_pair(ea):
    if not idc.is_off0(ida_bytes.get_flags(ea)) or not idc.is_off0(ida_bytes.get_flags(ea + 8)):
        return None
    return ida_bytes.get_qword(ea), ida_bytes.get_qword(ea + 8)


def get_interface_list():
    result = []

    interface_list_rel = find_pattern("4C 8D 2D ? ? ? ? 33 ED 4C 8D 35") + 0x3
    interface_list = interface_list_rel + ida_bytes.get_dword(interface_list_rel) + 4

    cur_interface = read_interface_pair(interface_list)
    while cur_interface is not None:
        name = ida_bytes.get_strlit_contents(cur_interface[0], -1, idc.STRTYPE_C)
        result.append((name.decode("utf8"), cur_interface[1]))
        interface_list += 16
        cur_interface = read_interface_pair(interface_list)

    return result


# Generate global var name
def get_interface_instance_name(name):
    result = "g_" + name
    if all([x in string.digits for x in result[-3:]]):
        result = result[:-3]
    result = result.rstrip("_")
    return result


interf_list = get_interface_list()
for interface in interf_list:
    var_name, addr = get_interface_instance_name(interface[0]), interface[1]
    idc.set_name(addr, var_name)
print(f"Renamed {len(interf_list)} interfaces")
 
Последнее редактирование:
Начинающий
Статус
Оффлайн
Регистрация
3 Мар 2021
Сообщения
62
Реакции[?]
14
Поинты[?]
2K
о, вот это действительно полезно. редко встретишь нынче что-либо, кроме конченного гуи со спизженными элементами.
 
Сверху Снизу