Пользователь
-
Автор темы
- #1
Два скрипта для переименования интерфейсов и кваров, а так же их колббеков. Может переименовать не все интерфейсы, но большинство.
Скрипт для переименования кваров основан на скрипте никсера и обновлен, а так же немного улучшен.
Работает на IDA 8.3, другие версии не проверял, оба скрипта работают для многих дллок игры.


Скрипт для переименования кваров основан на скрипте никсера и обновлен, а так же немного улучшен.
Работает на IDA 8.3, другие версии не проверял, оба скрипта работают для многих дллок игры.


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")
Последнее редактирование: