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
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)