2014-06-29 49 views
3

重新定義結構成員以成爲函數指針的普通手動方法是按下它,按'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腳本的函數指針。 請幫幫忙, 謝謝:)

回答

3

這是老問題,但我發現別人的解決方案:

SetType(GetMemberId(id, offset), "__int64 (__fastcall *)(ClassName *this)"); 
  • ID - 結構(值由AddStrucEx返回)的ID
  • 偏移 - 是結構成員的偏移量,如果您需要按會員名稱更改類型 - GetMemberOffset可以用於它