Skip to content

Instantly share code, notes, and snippets.

@otya128
Last active May 20, 2021 13:14
Show Gist options
  • Save otya128/ef78c2ee77b466394f6f4451bb0c03c0 to your computer and use it in GitHub Desktop.
Save otya128/ef78c2ee77b466394f6f4451bb0c03c0 to your computer and use it in GitHub Desktop.
WOW32 COM thunk test

WOW32 COM thunk test

COM16WOW.EXE (16-bit)->COM32WOW.DLL (32-bit)->CoGetClassObject->COM16DLL.DLL (16-bit)

#include <Windows.h>
#include <compobj.h>
#include <stdio.h>
#pragma comment(lib, "compobj")
class CCF : public IClassFactory
{
public:
STDMETHOD( QueryInterface )( THIS_ REFIID, LPVOID FAR * );
STDMETHOD_( ULONG, AddRef )( THIS );
STDMETHOD_( ULONG, Release )( THIS );
/* IClassFactory methods */
STDMETHOD( CreateInstance )( THIS_ LPUNKNOWN, REFIID, LPVOID FAR * );
STDMETHOD( LockServer )( THIS_ BOOL );
};
HRESULT CCF::QueryInterface(REFIID iid, void FAR* FAR* ppvObj)
{
if (IsEqualGUID(iid, IID_IUnknown) || IsEqualGUID(iid, IID_IClassFactory))
{
*ppvObj = this;
AddRef();
return NOERROR;
}
return (HRESULT)E_NOINTERFACE;
}
ULONG CCF::AddRef()
{
return 1;
}
ULONG CCF::Release()
{
return 1;
}
HRESULT CCF::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject)
{
*ppvObject = NULL;
return (HRESULT)E_NOINTERFACE;
}
HRESULT _loadds CCF::LockServer(BOOL fLock)
{
FILE *fp;
fp = fopen("COM16WOW.TXT", "w");
fprintf(fp, "CCF::LockServer! %p %d\n", this, fLock);
fclose(fp);
return S_OK;
}
extern "C" __declspec(dllexport) HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvObj)
{
if (IsEqualGUID(rclsid, CLSID_CCF))
{
CCF *pCF = new CCF();
HRESULT hr = pCF->QueryInterface(riid, ppvObj);
return hr;
}
return (HRESULT)CLASS_E_CLASSNOTAVAILABLE ;
}
extern "C" int CALLBACK LibMain(HINSTANCE hinst, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine)
{
return 1;
}
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{CC371C44-CE81-4A73-8F87-163C3499691C}]
[HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{CC371C44-CE81-4A73-8F87-163C3499691C}\InprocServer]
@="COM16DLL.dll"
#include <Windows.h>
#include <stdio.h>
#include <compobj.h>
#pragma comment(lib, "compobj.lib")
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPCSTR lpCmdLine, int nCmdShow)
{
DWORD(WINAPI*LoadLibraryEx32W)(LPCSTR, DWORD, DWORD) = (DWORD(WINAPI*)(LPCSTR, DWORD, DWORD))GetProcAddress(GetModuleHandle("KERNEL"), "LoadLibraryEx32W");
DWORD(WINAPI*GetProcAddress32W)(DWORD, LPCSTR) = (DWORD(WINAPI*)(DWORD, LPCSTR))GetProcAddress(GetModuleHandle("KERNEL"), "GetProcAddress32W");
DWORD(*CallProcEx32W)(DWORD, DWORD, DWORD, ...) = (DWORD(*)(DWORD, DWORD, DWORD, ...))GetProcAddress(GetModuleHandle("KERNEL"), "_CallProcEx32W");
DWORD hModule;
DWORD test;
CoInitialize(NULL);
hModule = LoadLibraryEx32W("COM32WOW.DLL", 0, 0);
test = GetProcAddress32W(hModule, "_test@0");
CallProcEx32W(0, 0, test);
}
#include <Windows.h>
#include <compobj.h>
#include <stdio.h>
__declspec(dllexport) void WINAPI test()
{
FILE *fp;
CLSID clsid;
IClassFactory *cf;
HRESULT hr;
fp = fopen("COM32WOW.TXT", "w");
hr = CLSIDFromString(L"{CC371C44-CE81-4A73-8F87-163C3499691C}", &clsid);
fprintf(fp, "%08x\n", hr);
hr = CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, &cf);
fprintf(fp, "%08x %p\n", hr, cf);
hr = CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER16, NULL, &IID_IClassFactory, &cf);
fprintf(fp, "%08x %p %p %p\n", hr, cf, cf->lpVtbl, cf->lpVtbl->LockServer);
fflush(fp);
cf->lpVtbl->LockServer(cf, 1);
fprintf(fp, "OK");
fclose(fp);
}
@otya128
Copy link
Author

otya128 commented May 20, 2021

cf->lpVtbl

0:002> ??**(void****)(@ebp-8)
void ** 0x6bb52994
0:002> ln 0x6bb52994
(6bb516a8)   OLETHK32!athopiInterfaceThopis+0x12ec   |  (6bb53878)   OLETHK32!apthopsApiThops
0:002> dd 0x6bb52994
6bb52994  6bb549b3 6bb54a38 6bb54a75 6bb5e6ca
6bb529a4  6bb5e67c 6bb549b3 6bb54a38 6bb54a75
6bb529b4  6bb52ed0 6bb52ec4 6bb52f00 6bb52efc
6bb529c4  6bb52ef0 6bb52ee8 6bb52ee0 6bb52f0c
6bb529d4  6bb52f08 6bb52f28 6bb52f20 6bb52f18
6bb529e4  6bb52f14 6bb52f40 6bb52f34 6bb52f7c
6bb529f4  6bb52f78 6bb52f70 6bb52f68 6bb52f60
6bb52a04  6bb52f58 6bb52f50 6bb52f88 6bb52f84
0:002> ln 6bb549b3 
(6bb549b3)   OLETHK32!QueryInterfaceProxy3216   |  (6bb54a38)   OLETHK32!AddRefProxy3216
Exact matches:
0:002> ln 6bb54a38 
(6bb54a38)   OLETHK32!AddRefProxy3216   |  (6bb54a75)   OLETHK32!ReleaseProxy3216
Exact matches:
0:002> ln 6bb54a75 
(6bb54a75)   OLETHK32!ReleaseProxy3216   |  (6bb54ab5)   OLETHK32!QueryInterfaceOnObj16
Exact matches:
0:002> ln 6bb5e6ca
(6bb5e6ca)   OLETHK32!ThunkMethod3216_0   |  (6bb5e723)   OLETHK32!ThunkCall1632
Exact matches:
0:002> ln 6bb5e67c 
(6bb5e67c)   OLETHK32!ThunkMethod3216_1   |  (6bb5e6ca)   OLETHK32!ThunkMethod3216_0
Exact matches:

@otya128
Copy link
Author

otya128 commented May 20, 2021

cf->lpVtbl->CreateInstance(cf, NULL, <undefined interface id>, &pv);
=>S_OK
pv=IUnknown

TODO: Interface{}\ProxyStubClsid

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment