重新定義結構成員以成爲函數指針的普通手動方法是按下它,按'Y'並在彈出框中輸入正確的聲明。 例如,對於struct member fncQuery,我會將字符串更改爲: BOOL(__cdecl * fncQuery)(char * cmdID)通過腳本在結構中設置IDA函數指針
這會有所幫助;當我下一次識別對這個函數指針的調用時,我會將適當的「調用[reg + offset]」行標記爲這個函數指針,並且IDA將 重新分析和評論我的參數。
我有一千個結構,每個結構至少有一個這樣的函數指針成員,以及這些函數的參數和返回值的描述的相應列表。可以理解的是,我想用IDAPython腳本來匹配它們,而不是用手來匹配它們。然而,我找不到對應於腳本的'Y'按鈕:
AddStrucMember並沒有按照我所知的那樣將其剪切 - 我可以聲明一個成員,使其成爲指向結構的指針,方法是給它一個結構ID,但那不是我所需要的。
SetMemberType與前面相同。
SetType需要一個線性地址和一個類型字符串 - 除了線性地址對代碼段是獨佔的,這是完美的,所以我不能用SetType來觸摸結構成員定義。
在我的搜索中,我找到了一個變魔術的人,將低級別的idaapi合併到他的IDAPython腳本中,以檢測結構成員是否與已知函數具有相同的名稱,如果是,則「獲取」該函數的類型並將其「設置」到成員上。 具體地說,這種可怕的電話被視爲(取出其定義的背景下,你就會有,當我說這正常運行,並第一個函數調用填滿它與有意義的值很多outparameters信任我):
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[0] = 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),
)
「get_named_type」背後的幕後工作讓我不知所措,並且尋找它的來源(併爲我的使用製作一些東西)可能過於強硬和過早。
你知道更簡單的方法,我的需求可以實現嗎? 我只需要將結構成員定義爲來自IDAPython腳本的函數指針。 請幫幫忙, 謝謝:)