当我进行动态反转时,我看到了ObjectStublessClientXXin 的用法ole32.dll。
那是什么功能?它有什么作用?
有什么方法可以在两个进程之间传输消息?我看到在从1.exeso调用这些函数之后2.exe收到一条消息
当我进行动态反转时,我看到了ObjectStublessClientXXin 的用法ole32.dll。
那是什么功能?它有什么作用?
有什么方法可以在两个进程之间传输消息?我看到在从1.exeso调用这些函数之后2.exe收到一条消息
COM 是面向对象编程 (OOP) 中非常抽象的概念。要很好地理解这一点,您需要深入了解OOP 中的继承、虚拟方法表、单独进程中的 COM以及使用 COM 进行数据编组。
这些子例程是 COM 代理/存根 DLL 的一部分。当 COM 接口在单独的 DLL 文件中定义/实现时,将使用代理 DLL。将这些视为一个简单的函数调用,但使用 COM 虚拟表。在动态链接的情况下,DLL 有导出函数,EXE 文件调用它们。在代理/存根 COM 的情况下,底层函数在单独的 DLL 文件中定义。当可执行文件调用任何方法时,参数通过代理 DLL 被编组(即打包/组装)到所有真实事情发生的主 DLL。代理 DLL 仅包含这些方法的列表,也就是。虚拟方法表(vtable 或 vtbl)中的虚拟函数。因此,“ObjectStublessClient”只是虚函数。在简单的 C 语言中,这可以作为结构中的函数指针进行比较(过度简化)。
在 IDA 中,转到 View --> Open subviews --> Names 或按Shift+F4打开“Names Window”。搜索“ProxyVtbl”,您可以找到定义的虚拟表。下面是Ole32.DLL 文件中IOleCacheControl 接口的示例。
.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
MIDL_INTERFACE("00000129-0000-0000-C000-000000000046")
IOleCacheControl : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE OnRun(
LPDATAOBJECT pDataObject) = 0;
virtual HRESULT STDMETHODCALLTYPE OnStop( void) = 0;
};
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
);
};
前三个函数(QueryInterface、AddRef、Release)继承自(即复制自)IUnknown 接口。然后其他剩余的虚函数用它们的偏移量命名。因此ObjectStublessClient3_0是OnRun()和ObjectStublessClient4_0是OnStop()函数指针。我将调用约定更改为__fastcall因为 Windows 二进制文件通常使用该调用约定。
可以在我的存储库GitHub 中看到此方法的真实示例:WslReverse,其中显示了LxssManager.DLL的隐藏 COM 接口。