我想知道是否有人知道如何使用 IDAPython 将结构分配给堆栈变量(就像我们做Alt+时那样Q);对 .data 中的地址执行此操作不是问题,但我无法想出一种方法来通过 IDA 为给定函数创建的堆栈结构来执行此操作。
似乎有两个 APIidaapi
可以做到这一点:
def set_member_tinfo2(*args):
"""
set_member_tinfo2(sptr, mptr, memoff, tif, flags) -> smt_code_t
"""
def set_member_tinfo(*args):
"""
set_member_tinfo(til, sptr, mptr, memoff, type, fields, flags) -> bool
"""
return _idaapi.set_member_tinfo(*args)
问题是我不知道如何从本地人的结构中获取“类型”( type_t
) 或“tif”( tinfo_t
)。我到目前为止的代码是这样的:
# 00000000167ED lea r8, [rbp+190h+var_170]
lea_addr = 0x167ED
# Get the stack struct
current_func = idaapi.get_func(lea_addr)
stack_id = idc.GetFrame(current_func)
stack_struc = idaapi.get_struc(stack_id)
# Get the stack operand offset value and stack member
stack_member_offset = idc.GetOperandValue(lea_addr, 1)
stack_member = stack_struc.get_member(stack_member_offset)
target_struct_id = idaapi.get_struc_id("_CONFIG")
target_struc = idaapi.get_struc(target_struct_id )
我的目标是将_CONFIG
我在 idb local 中的结构分配给var_170
. 我应该调用set_member_tinfo2
传递一个tinfo_t
我的_CONFIG
结构,但我不知道如何获得它。
在 idc 模块中有另一个名为“SetMemberType”的函数,它看起来更简单,但我已经尝试了几种方法,但没有成功。例如:
idc.SetMemberType(stack_id, stack_member_offset, idc.FF_STRU|idc.FF_DATA, target_struct_id, 0)
它总是返回 False。
谢谢@Bambu,我实际上已经尝试过你的方法,但它对我也不起作用。我最终发现有效的是首先取消定义由 IDA 定义的堆栈成员(除了您已经定义的堆栈成员和基 'r' 成员),然后定义一个具有结构大小的新字节成员。之后,使用 更改类型SetMemberType
。
def delete_all_function_stack_members(func_ea):
members, base = retrieve_stack_members(func_ea)
stack_id = idc.GetFrame(func_ea)
for k, v in members.items():
if k != base:
idc.DelStrucMember(stack_id, k)
g_functions_stack.add(func_ea)
delete_all_function_stack_members(current_func)
AddStrucMember(stack_id, "config", stack_member_offset, FF_BYTE|FF_DATA, -1, GetStrucSize(target_struct_id))
idc.SetMemberType(stack_id, stack_member_offset, idc.FF_STRU|idc.FF_DATA, target_struct_id, 1)