idapython - 将结构分配给堆栈变量

逆向工程 艾达 蟒蛇
2021-06-26 03:34:00

我想知道是否有人知道如何使用 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)
2个回答

我最终发现有效的是首先取消定义由 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)

你可以得到tinfo_t你的_CONFIG使用结构parse_decl2然后使用idaapi.set_member_tinfo2.

获得后stack_strucstack_member您可以执行以下操作:

tinfo = idaapi.tinfo_t()
idaapi.parse_decl2(idaapi.cvar.idati, '_CONFIG;', tinfo, idaapi.PT_TYP)
idaapi.set_member_tinfo2(stack_struc, stack_member, 0, tinfo, idaapi.SET_MEMTI_COMPATIBLE)

注意:;末尾的_CONFIG;是必需的。