The ordinary, manual way of redefining a
struct member to become a function pointer would be to press on it, hit 'Y', and enter the proper declaration in the popup box. For example, for
fncQuery, I would change the string to:
BOOL (__cdecl *fncQuery)(char *cmdID)
This would be helpful; When I next identify a call to this function pointer, I would mark the appropriate
call [reg+offset] line as this function pointer, and IDA will re-analyze and comment the parameters for me.
I have a thousand
struct each with at least one such function pointer member, and corresponding lists of the descriptions of these functions' parameters and return values. Understandably, I want to match them up by an IDAPython script rather than by hand. However, I can't find an equivalent for the 'Y' button for scripts:
AddStrucMemberdoes not cut it as far as I know - I can declare a member to become a pointer to a
structby giving it a
structID, but that's not what I need.
SetMemberTypeis the same as the previous.
SetTyperequires a linear address and a type string - which would be perfect except linear addresses are exclusive to the code section, so I can't touch structure member definitions with
In my search I've found someone who conjured up dark magic, incorporating low level
idaapi into his IDAPython script, to detect if a
struct member has the same name as a known function, and if it does, "gets" the type of that function and "sets" it onto the member. Specifically, such horrible calls are seen (taken out of context of its definitions, you'll have to trust me when I say this runs properly and the first function call fills up its many outparameters with meaningful values):
get_named_type = g_dll.get_named_type get_named_type.argtypes = [ ctypes.c_void_p, #const til_t *ti, ctypes.c_char_p, #const char *name, ctypes.c_int, #int ntf_flags, ctypes.POINTER(ctypes.POINTER(ctypes.c_ubyte)), #const type_t **type=NULL, ctypes.POINTER(ctypes.POINTER(ctypes.c_ubyte)), #const p_list **fields=NULL, ctypes.POINTER(ctypes.POINTER(ctypes.c_ubyte)), #const char **cmt=NULL, ctypes.POINTER(ctypes.POINTER(ctypes.c_ubyte)), #const p_list **fieldcmts=NULL, ctypes.POINTER(ctypes.c_ulong), #sclass_t *sclass=NULL, ctypes.POINTER(ctypes.c_ulong), #uint32 *value=NULL); ] get_named_type( til, funcname, idaapi.NTF_SYMM, ctypes.byref(typ_type), ctypes.byref(typ_fields), ctypes.byref(typ_cmt), ctypes.byref(typ_fieldcmts), ctypes.byref(typ_sclass), ctypes.byref(value) type_arr = ctypes.create_string_buffer(0x400) type_arr = chr(idaapi.BT_PTR) manualTypeCopy(type_arr, 1, len(type_arr), typ_type) ret = g_dll.set_member_tinfo( til, struc, memb, ctypes.c_uint(0), type_arr, typ_fields, ctypes.c_uint(0), )
The work behind the scenes on "
get_named_type" eludes me, and looking into its source (and fashioning something from it for my use) may be strong headed and premature.
Do you know of an easier way my need can be fulfilled ? I just need to define structure members as function pointers from an IDAPython script. Please help !