1

When I do dynamic reversing I saw usage with ObjectStublessClientXX in ole32.dll .

What is that function? What does it do?

Is there any way that it supposed to transfer message between 2 processes? I see that after those function called from 1.exe so 2.exe got a message

  • Is that the actual name or you have a specific number in place of XX? – Igor Skochinsky Aug 16 '18 at 8:42
  • @Keystone I noticed you don't usually accept answers. Is that intentional or are you just unaware of the meaning of accepting answers? May I interest you in accepting Biswapriyo's answer to this post, unless you find it lacking? – NirIzr Aug 29 '18 at 21:08
5

COM is very abstract idea in Object Oriented Programming (OOP). To understand this well, you need some in-depth knowledge of Inheritance in OOP, Virtual Method Table, COM in separate process and Data Marshaling with COM.

Those subroutines are part of a COM Proxy/Stub DLL. Proxy DLL are used when the COM interfaces are defined/implemented in separate DLL files. Think these as a simple function call but with COM virtual tables. In case of dynamic linking, DLL has exported functions and EXE files call them. In case of proxy/stub COM, the underlying functions are defined in a separate DLL files. When an executable call any method the parameters are marshalled (i.e. packed/assembled) through Proxy DLL to the main DLL where all the real things happens. Proxy DLLs contain just the list of those methods, aka. Virtual Functions in Virtual Method Table (vtable or vtbl). So, the "ObjectStublessClient" are the virtual functions only. In simple C language, this can be compared as function pointers in a structure (with oversimplification).

In IDA, go to View --> Open subviews --> Names or press Shift + F4 to open 'Names Window'. Search for 'ProxyVtbl', you can find defined virtual tables. Here is an example of IOleCacheControl interface in Ole32.DLL file.

  • In IDA assembly view:
.rdata:00000001800CE9D0 ; $2F7D790A470334608EE0E1481017719B IOleCacheControlProxyVtbl
.rdata:00000001800CE9D0 _IOleCacheControlProxyVtbl dq offset IOleCacheControl_ProxyInfo; header.piid
.rdata:00000001800CE9D0                                         ; DATA XREF: .rdata:00000001800C9BF8↑o
.rdata:00000001800CE9D0                 db 0D0h, 0AEh, 0Fh, 80h, 1, 3 dup(0); gap8
.rdata:00000001800CE9D0                 dq offset IUnknown_QueryInterface_Proxy, offset IUnknown_AddRef_Proxy; Vtbl
.rdata:00000001800CE9D0                 dq offset IUnknown_Release_Proxy, offset ObjectStublessClient3_0; Vtbl
.rdata:00000001800CE9D0                 dq offset ObjectStublessClient4_0; Vtbl
.rdata:00000001800CEA08                 align 10h
  • In oleidl.h file (C++ interface):
MIDL_INTERFACE("00000129-0000-0000-C000-000000000046")
IOleCacheControl : public IUnknown
{
public:
    virtual HRESULT STDMETHODCALLTYPE OnRun( 
        LPDATAOBJECT pDataObject) = 0;

    virtual HRESULT STDMETHODCALLTYPE OnStop( void) = 0;

};
  • In simple C language:
GUID IID_IOleCacheControl = { 0x00000129, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 };

typedef struct _IOleCacheControl IOleCacheControl, *PIOleCacheControl;

struct _IOleCacheControl {

    //0th IUnknown_QueryInterface_Proxy
    HRESULT (__fastcall *QueryInterface )( 
        PIOleCacheControl* This,
        GUID* riid, 
        PVOID* ppvObject
        );

    //1st IUnknown_AddRef_Proxy
    ULONG (__fastcall *AddRef )( 
        PIOleCacheControl* This
        );

    //2nd IUnknown_Release_Proxy
    ULONG (__fastcall *Release )( 
        PIOleCacheControl* This
        );

    //3rd ObjectStublessClient3_0
    HRESULT (__fastcall *OnRun )( 
        PIOleCacheControl* This,
        IDataObject* pDataObject
        );

    //4th ObjectStublessClient4_0
    HRESULT (__fastcall *OnStop )( 
        PIOleCacheControl* This
        );

};

The first three functions (QueryInterface, AddRef, Release) are inherited from (i.e. copied from) IUnknown interface. Then other remaining virtual functions are named with their offsets. Hence ObjectStublessClient3_0 is the OnRun() and ObjectStublessClient4_0 is the OnStop() function pointers. I changed the calling conventions to __fastcall because Windows binary generally use that calling conventions.

One can see a real example of this method in my repository GitHub: WslReverse where I show the hidden COM interface of LxssManager.DLL.

Further Readings:

  • thank you about your replay, I searched in name windows ProxyVtbl but not found anything, do you say that ObjectStublessClientXX point to some virtual function that implement in another place? I want to find which function is point about. Thank! – Keystone Oct 28 '18 at 22:33
  • @Keystone There are many COM vtable in ole32.dll. See this image. Look at the assembly view first to get the overall idea. If you double click on ObjectSutblessClient in assembly view IDA automatically opens that function. – Biswapriyo Oct 29 '18 at 8:27
  • what do you mean? In my process that I open with ida I dont see in the 'Names Window' anything that contain ProxyVtbl. Do you want me to open ole32.dll with ida? That windows dll, I want to see which function my process will do when ObjectStublessClientXX called. When I tried to debug I see that when my process enter to ObjectStublessClientXX I see there ole32_objectstublessclientXX proc near and then mov ecx xx and jmp address that is again ObjectStublessClientXX – Keystone Oct 31 '18 at 21:13
  • Book: IDA pro 2nd edition chapter 4. – Biswapriyo Oct 31 '18 at 21:30
  • friend, I already read that, and workinf lot with ida, maybe I dont explain myself well, please look on my last replay, if you can please help me to find which function has been called when I see ObjectStublessClientXX I will thank you – Keystone Oct 31 '18 at 21:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.