我正在使用IDA Pro 6.3對Win32.dll進行靜態分析,並使用Hex-Rays反編譯器與IDA反彙編程序一起使用。我想了解這條線是幹什麼的。被反編譯__thiscall表達式指向函數的指針?
v4 = (*(int (__thiscall **)(int, int))(*(_DWORD *)dword_10087418 + 4))(dword_10087418, v11);
它被格式化爲函數調用。這是在子例程調用中使用指向函數的指針時反編譯的代碼的樣子嗎?
謝謝。
我正在使用IDA Pro 6.3對Win32.dll進行靜態分析,並使用Hex-Rays反編譯器與IDA反彙編程序一起使用。我想了解這條線是幹什麼的。被反編譯__thiscall表達式指向函數的指針?
v4 = (*(int (__thiscall **)(int, int))(*(_DWORD *)dword_10087418 + 4))(dword_10087418, v11);
它被格式化爲函數調用。這是在子例程調用中使用指向函數的指針時反編譯的代碼的樣子嗎?
謝謝。
這是將地址* dword_10087418 + 4轉換爲函數並調用它。
所以它將dword_10087418轉換爲dword指針,然後解引用它,然後將4添加到該結果中。得到的地址被轉換爲它的聲明如下功能:
int __thiscall foo(int, int)
的int (__thiscall **)(int, int)
使得雙指針與__thiscall調用約定採用兩個整數參數的函數。然後圍繞所有的將*()
解引用到一個單一的函數指針。所以最後你要把一些結果地址轉換成一個函數指針。
dword_10087418和v11是傳遞給此函數的整數。函數調用的結果保存在v4中。 C代碼是這樣的:
int v4 = foo(dword_10087418, v11);
這很可能是C++,不是純C.這正是VISUAL C++ - 生成的虛擬方法調用的樣子。我會這樣說:
dword_10087418
是一個指向對象的指針。它可以是全局變量或靜態變量,不是本地變量。SomeClass::Instance->func(arg)
。如果你不熟悉C++對象佈局,你應該閱讀C++ Under the Hood,Reversing: Secrets of Reverse Engineering或Inside the C++ Object Model。 IDA Pro Book也有一個關於這個主題的簡短部分。
如果你想要一個簡短的總結,請繼續閱讀。請記住,所有這些都是MSVC的實現細節,其他編譯器會以不同的方式執行,並且可以隨意更改它們。 (另外,我通過不提及虛擬/多重繼承來簡化事物)。當一個類使用虛函數時,編譯器會在該類中構建一個包含所有這些函數的表,並將該表的指針作爲該類的每個對象的第一個隱藏成員。然後,從表中調用虛函數是簡單的:
mov ecx, esi ; pretend that esi contains a pointer
; to the object whose method is being called
; also known as "this"
; __thiscall functions expect to find this pointer in ecx
; and all later arguments on the stack
mov edx, [ecx] ; get the vtable address
push edi ; set up some integer-sized argument
call [edx + 4] ; call the second function in the vtable
這基本上就是該行代碼是這樣做的:
(*(int (__thiscall **)(int, int))(*(_DWORD *)dword_10087418 + 4))(dword_10087418, v11)
^-----------------------^
dereference pointer to get the address of the vtable
(it's the first piece of data in the object)
^-----------------------------^
add 4 bytes to get address of the second function
^------------------------------------------------------------------------------------^
cast that pointer to a particular function pointer and call it
(cast is invisible in assembler code, so it's just a call)
注意,由於成員函數需要訪問this
,編譯器也必須通過它。這是C++中不可見的細節,但this
被視爲函數的附加參數 - 因此您會看到兩個參數,但該函數只需要一個參數(MSVC的thiscall
約定命令this
指針在ecx
中傳遞)。國際開發協會並不打算隱藏那個指針,因爲這會讓人困惑。
更多建議:獲取ms_rtti
腳本IDA並運行它來查找DLL中的虛方法表,然後搜索其它引用dword_10087418
,看看有什麼值寫入它 - 你應該能夠確定哪個vtable與該對象相關聯,然後確定哪個函數正在被調用。
如果爲類和所討論的vtable定義存根結構類型,那麼可以使Hex-Rays以更易讀的方式顯示代碼,然後告訴IDA指針使用該結構類型。
哇..我認爲這是我避免C-Style塑造如此之多的原因之一.. – Brandon