簡體   English   中英

成員函數指向整數?

[英]Member function pointer to integer?

是否可以將虛擬地址作為成員函數指針的整數?

我努力了。

void (AClass::*Test)();
Test = &AClass::TestFunc;
int num = *(int*)&Test;

但所有這一切都是讓我獲得函數的jmp的虛擬地址。 我需要實際的功能虛擬地址。

我知道這是舊的,但由於沒有有意義的主題答案,我走了。

有些事情需要先考慮。 C ++中的成員函數調用約定稱為__thiscall。 該公約幾乎是相同的__stdcall,唯一的顯著的區別在於,是由有效通話前, ECX被設置為指針this對象的其中的方法被調用。

為了說明這一點,並在同一時間回答你的問題,讓我們說,該類AClass宣布這樣一個成員函數: int AClass::myFunction(int a, int b)並且我們有一個實例AClass稱為aClassObject 這是一個相當hackish的方式做你最初要求和'模擬' AClass::myFunction上的aClassObject AClass::myFunction調用一旦你獲得原始指針:

// declare a delegate, __stdcall convention, as stated above
typedef int (__stdcall *myFunctionDelegate)(int a, int b);
// here's the 'hackish' solution to your question
char myFunctionPtrString[10];
sprintf(myFunctionPtrString, "%d", &AClass::myFunction);
int myFunctionPtr = atoi(myFunctionPtrString);
// now let's call the method using our pointer and the aClassObject instance
myFunctionDelegate myFunction = (myFunctionDelegate)myFunctionPtr;
// before we make the call, we must put a pointer to aClassObject
// in ECX, to finally meet the __thiscall calling convention
int aClassObjectPtr = (int)&aClassObject;
__asm{
     mov ecx, aClassObjectPtr
}
// make the call!
myFunction(2, 3);

當然,實例可以是AClass類型的任何實例。

不,成員函數指針可以有多種大小 (從4-16字節或更多,取決於平台,請參閱文章中的表),並且不能可靠地適合整數的空間。 這是因為虛函數和繼承可以使編譯器存儲多條信息以調用正確的函數,因此在某些情況下沒有簡單的地址。

雖然我不能肯定地說是否有可行的方法來執行此操作,但我通常建議使用靜態包裝函數來提供對類方法的此類外部訪問。 否則,即使您成功,您也會創建應用程序與該類實現的緊密耦合。

如果這是我懷疑它,只需關閉增量鏈接。 與此同時,你得到了正確的答案。

我懷疑是TestFunc可能是virtual 對於其地址采用的虛函數,VC ++偽造了一個執行vtable查找的thunk,並給出了一個指向該thunk的指針作為地址。 (這確保當實際對象是更派生的類型時找到正確的派生函數。還有其他方法可以做到這一點,但這允許這樣的指針成為單個指針並簡化調用代碼,代價是雙倍當它們被調用時跳轉。)打開程序的匯編語言輸出,並查看結果; 它應該足夠清楚發生了什么。

在這里,你得到的是正確的答案,並且無法找到“實際”功能的地址。 實際上,虛函數沒有命名一個單獨的實際函數,它命名哪個派生函數適合於所討論的對象。 (如果您不喜歡此行為,請將該函數設置為非虛擬。)

如果你真的需要實際功能的真實地址,你有兩個選擇。 令人討厭的是編寫一些代碼來掃描thunk以找出函數的vtable索引。 然后查看相關對象的vtable以獲取該函數。

(但請注意,獲取非虛函數的地址將為您提供要調用的實際函數的地址,而不是thunk - 因此您也必須滿足這種可能性。虛擬指針的類型函數和指向非虛函數的指針是相同的。)

更容易的是創建包含每個虛函數的代碼的非虛函數,然后讓每個虛函數調用非虛函數。 這給你的行為和以前一樣。 如果要查找代碼的位置,請使用非虛函數的地址。

(在任何一種情況下,這都很難讓工作變得很好,這會很煩人,而且它會特別是VC ++ - 但如果你願意付出努力,你可能會成功。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM