IDA 本地类型有一个本地类型,例如:
struct DEMOTYPE<int>
{
_DWORD dw1;
_DWORD dw2;
}
如何像普通c类型一样使用“DEMOTYPE”(C++类型)?按 Y 无法实现目标,因为里面有“<>”。
我知道目标是否是函数,我们可以使用其损坏的名称来更改函数声明。
总而言之,如何使用局部类型中的c++类型声明来改变局部变量的类型?
下面是我尝试过的代码,但是F5伪代码视图无法更改。
def setVarType(lvname, lti, isptr=False):
addr = idc.here()
c = idaapi.decompile(addr)
for v in c.lvars:
if v.name == lvname:
print("find target variable:", v.name)
idati = ida_typeinf.get_idati()
ti = ida_typeinf.tinfo_t()
if ti.get_numbered_type(idati, lti):
print("find local type:", lti, ":", ti)
if isptr:
ti_ptr = ida_typeinf.tinfo_t()
ti_ptr.create_ptr(ti) # ti_ptr = ti *
bret = v.set_final_lvar_type(ti_ptr)
else:
bret = v.set_final_lvar_type(ti)
print(bret)
这应该有效,但仅适用于局部变量(不适用于函数参数)。
典型用法:
set_lvar_name_type(here(), 'v1', None, 'rage::atArray<int>')
def set_lvar_name_type(ea, src, name, t, vu=None):
"""
Change the name or type of a local variable
@param ea: address of function
@param src: current name of variable
@param name: new name (or None to leave as is)
@param t: new type (str, tinfo_t, or None to leave as is)
@param v: handle to existing pseudocode window (vdui_t, or None)
@note
Will not work with function arguments or global variables
"""
# m = [ea for ea in [pprev(ea, 1) for ea in l if GetFuncName(ea)] if ea]
def get_tinfo_elegant(name):
ti = ida_typeinf.tinfo_t()
til = ti.get_til()
# get_named_type(self, til, name, decl_type=BTF_TYPEDEF, resolve=True, try_ordinal=True)
if ti.get_named_type(til, name, ida_typeinf.BTF_STRUCT, True, True):
return ti
return None
def get_pseudocode_vu(ea, vu=None):
func = idaapi.get_func(ea)
if func:
return idaapi.open_pseudocode(func.start_ea, 0)
if isinstance(t, str):
tif = get_tinfo_elegant(t)
if not tif:
raise ValueError("Couldn't get tinfo_t for type '{}'".format(t))
t = tif
elif isinstance(t, ida_typeinf.tinfo_t) or t is None:
pass
else:
raise TypeError("Unknown type for t '{}'".format(type(t)))
vu = get_pseudocode_vu(ea, vu)
if vu:
lvars = [n for n in vu.cfunc.lvars if n.name == src]
if len(lvars) == 1:
print("changing name/type of {}/{} to {}/{}".format(lvars[0].name, lvars[0].type(), name, str(t)))
if t:
vu.set_lvar_type(lvars[0], t)
if name:
vu.rename_lvar(lvars[0], name, 1)
else:
print("[set_lvar_name_type] couldn't find var {}".format(src))
return False
这个真的让我抓狂……我什至在一个简化的 GCC mangler 中投入了大量的工作,并制作了一个用于重构的 IDA 插件,它会破坏你的名字。最后,事实证明这些都不需要。据我所知,IDA 的网络节点可以使用除
\0
之外的任何字符。您需要做的就是打开 IDA_INSTALL_DIR/cfg/ida.cfg 并将所需的字符添加到 NameChars 中,如下所示
NameChars = "~`.:<>?!/,()[]" // Add special characters for C++/Swift
"$?@" // asm specific character
"_0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz",
// This would enable common Chinese characters in identifiers:
// Block_CJK_Unified_Ideographs,
CURRENT_CULTURE;
瞧,现在您可以使用字符来命名函数和变量
~`.:<>?!/,()[]
然而,IDA 会自动将大多数字符表示为
_
;幸运的是 <>
得到了正确的体现。
这适用于大多数情况,但不适用于本地类型。如果需要使用特殊字符重命名结构,则还需要编辑 TypeNameChars,如下所示:
// the following characters are allowed in type names.
TypeNameChars = "~.<>?!/," // Add special characters for C++/Swift
"_:$()`'{}"
"_0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
现在我们可以在类型名称中使用
~.<>?!/,
!