2017-04-20 112 views
1

接口獲得和方法被稱爲:如何在C++中查找指向接口的指針地址?

IFileOpenDialog *pFileOpen; 
CoCreateInstance(__uuidof(FileOpenDialog), NULL, CLSCTX_INPROC_SERVER,IID_PPV_ARGS(&pFileOpen)); 
pFileOpen->Show(NULL); 

在組件,它是:

mov   eax,pFileOpen 
mov   ecx,dword ptr [eax] 
mov   edx,pFileOpen 
push  edx 
mov   eax,dword ptr [ecx+ offset_Show] 
call  eax 

也就是說ECX是指針VMT,[ECX + offset_Show]是顯示方法。 如何獲得offset_Show,理想情況下儘可能高。 pFileOpen->顯示爲指針不可編譯。

+0

使用微軟的offsetof()宏。 https://msdn.microsoft.com/en-us/library/dz4y9b9a.aspx –

+0

你將不得不#包括shobjidl.h之前#定義CINTERFACE,那麼你就可以訪問到VTBL聲明和offsetof(IFileDialogVtbl,展)將工作。但是這對程序的其他部分有很大的破壞性。谷歌的「C++獲得虛擬函數在vtbl中的偏移量」。 –

回答

0

要獲得正常功能的地址,你可以使用function pointers。有關獲取指向類方法的函數指針,另請參閱this Stackoverflow post

的指針接口istelf的地址正是你在你的代碼做了什麼:&pFileOpen

+1

這不適用於接口,至少使用MSVC10。 void * pShow =&pFileOpen-> Show;導致「錯誤C2276:'&':綁定成員函數表達式上的非法操作」。 Intellisence:「綁定功能只能用於通話」。地址實際上是在調用之前按照上面的方式計算的,並且事先不知道,但偏移量是硬編碼的!請建議可以工作的確切語法。 – user3874158

+0

INT權衡= offsetof(IFileOpenDialog,顯示); - 同樣的錯誤。類似的文章,他們寫的,這是不可能的:http://stackoverflow.com/questions/2125862/virtual-functions-table-offset。 – user3874158

+0

如果我正確理解你的問題,答案爲[這個問題](http://stackoverflow.com/questions/24649208/get-the-real-addressor-index-in-vtable-of-virtual-member-function)可能會導致您找到解決方案。 – adanmoran

1

解決方案found.For compilability需要單獨的C源代碼,以獲得VMT偏移。

C++源:

#include <shobjidl.h> 
#include <atlbase.h> 
extern "C" int getOffsetIFileDialogVtblShow(); 
IFileOpenDialog *pFileOpen = ...; //get from somewhere 
//pointer to VMT 
unsigned char *pcFileOpen = (unsigned char *)(*(DWORD*)(unsigned char *)pFileOpen); 
pcFileOpen = (unsigned char *)(*(DWORD*)pcFileOpen); 
int offs = getOffsetIFileDialogVtblShow(); 
//pointer to Show() at pcFileOpen + offs, put hook here 
fprintf(fLog,"\nFileOpenDialog::IFileOpenDialog->Show at %.8X value %.8X",pcFileOpen + offs,*(DWORD*)(pcFileOpen + offs));  

C源

#include <stddef.h> //for offsetof 
#define CINTERFACE 
#include <shobjidl.h> 

int getOffsetIFileDialogVtblShow() 
{ 
    return = offsetof(IFileDialogVtbl, Show); 
}