1

Interface is obtained and method is called:

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

In assembly it is:

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

That is ecx is pointer to VMT, [ecx + offset_Show] is method Show. How to get offset_Show, desirably as in high level as possible. pFileOpen->Show as pointer is not compilable.

  • Use Microsoft's offsetof() macro. https://msdn.microsoft.com/en-us/library/dz4y9b9a.aspx – Joseph Willcoxson Apr 20 '17 at 13:53
  • You would have to #define CINTERFACE before #including shobjidl.h, then you can get access to the vtbl declaration and offsetof(IFileDialogVtbl, Show) will work. But that is highly disruptive to the rest of the program. Google "c++ get offset of virtual function in vtbl" for the hacks. – Hans Passant Apr 21 '17 at 07:45

2 Answers2

1

Solution found.For compilability need separate C source to get offset in VMT.

C++ source:

#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 source

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

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

To get an address to a normal function, you can use function pointers. See also this Stackoverflow post on getting a function pointer to a class method.

The address of the pointer to the interface istelf is exactly what you did in your code: &pFileOpen

Community
  • 1
  • 1
adanmoran
  • 69
  • 4
  • 1
    This does not work with interfaces, at least with MSVC10. void *pShow = &pFileOpen->Show; causes "error C2276: '&' : illegal operation on bound member function expression". Intellisence: "Bound functions can be used only for call". The address is actually calculated as above just before call and not known in advance, but offset is hardcoded! Please suggest exact syntax that could work. – user3874158 Apr 20 '17 at 14:55
  • int offs = offsetof(IFileOpenDialog,Show); - same error. Similar article and they write that this is impossible: http://stackoverflow.com/questions/2125862/virtual-functions-table-offset. – user3874158 Apr 20 '17 at 15:04
  • If I understand your problem correctly, the answers to [this question](http://stackoverflow.com/questions/24649208/get-the-real-addressor-index-in-vtable-of-virtual-member-function) may lead you to a solution. – adanmoran Apr 21 '17 at 18:21
  • Also, keep in mind that **if** it is possible, a function pointer to a member function is retrieved with `&IFileOpenDialog::Show`, not `&pFileOpen->Show`. – adanmoran Apr 21 '17 at 18:28