I was wondering if anyone knows how to assign a struct to a stack variable using IDAPython (like when we do Alt+Q); Doing this for addresses in .data is not a problem, but I can't figure out a way to do it over the stack struct that IDA creates for a given function.
There seems to be two APIs in idaapi
to do this:
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)
The problem is that I don't know how to get a 'type' (type_t
) or 'tif' (tinfo_t
) from the struct I have in my locals. The code I have so far is something like this:
# 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 )
My goal is to assign the _CONFIG
struct I have in my idb local to var_170
. I should call set_member_tinfo2
passing a tinfo_t
of my _CONFIG
struct but I can't figure out how to get it.
In the idc module there is another function called 'SetMemberType' which looks simpler but I've tried this one in several ways without success. For example:
idc.SetMemberType(stack_id, stack_member_offset, idc.FF_STRU|idc.FF_DATA, target_struct_id, 0)
It always returns False.
Thanks @Bambu, I've actually tried your method but it didn't work for me either. What I've finally found that works is to first undefine the stack members that are defined by IDA (except for the ones you already defined and the base 'r' member) and then defining a new bytes member with the size of the struct. After that, change the type with 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)