在c#中访问com对象的vtable

时间:2010-04-22 09:11:43

标签: c# .net com

编辑:

我试图在.net类中封装第三方com对象,同时修复它的错误。我希望通过调用我自己的方法替换com对象的vtable中的方法,这将提供该方法的无错误实现。

我试图在一些非常基本的东西上测试这个,但鉴于下面的答案我完全是错误的轨道。通过创建对我的com对象的引用,我假设我已经创建了一个运行时可调用的包装器,有没有办法获得指向真正的底层com对象的指针?


我正试图在内存中访问com对象的vtable并且无处可去。

根据我的阅读,com对象的内存中的前4个字节应该是指向vtableptr的指针,而vtableptr又是指向vtable的指针。

虽然我不确定我希望在这个com对象的第7个插槽中找到我的测试方法但是我已经尝试了所有这些并且没有看起来像我的函数的地址。

如果有人可以对此示例进行必要的更改以使其工作(目的只是尝试通过访问com对象的vtable并在其出现的任何行中查找方法来调用Tester类上的Test方法)我将非常感激。

我知道很少有人需要这样做,但请接受我需要做一些非常相似的事情并考虑其他选择

提前致谢

[ComVisible(true)]
public class Tester
{
    public void Test()
    {
        MessageBox.Show("Here");
    }

}

public delegate void TestDelegate();

private void main()
{

    Tester t = new Tester();

    GCHandle objectHandle = GCHandle.Alloc(t);

    IntPtr objectPtr = GCHandle.ToIntPtr(objectHandle);

    IntPtr vTable = (IntPtr)Marshal.ReadInt32(objectPtr);

    IntPtr vTablePtr = (IntPtr)Marshal.ReadInt32(vTable);

    IntPtr functionPtr = (IntPtr)Marshal.ReadInt32(vTablePtr, 7 * 4); // 7 may be incorrect but i have tried many different values

    TestDelegate func = (TestDelegate)Marshal.GetDelegateForFunctionPointer(functionPtr, typeof(TestDelegate));

    func();

    objectHandle.Free();
}

2 个答案:

答案 0 :(得分:3)

你完全走错了路。 t对象是不是 COM接口指针,它是.NET对象引用。在非托管代码创建CCW(COM Callable Wrapper)之前,不会创建COM接口指针(及其v表)。 是非托管代码,CLR互操作层不允许托管代码创建CCW。

保持此线程移动的唯一方法是解释您为什么要这样做。

答案 1 :(得分:0)

@Hans有一点意见。 +1。

这不是一个解决方案,只是一个解释:

如果您真的想要访问COM对象,为什么不创建一个简单的COM dll,然后尝试访问它?

Interop有两种方式:

  1. .NET组件调用COM组件
  2. 调用.NET组件的COM组件
  3. 当.NET调用COM时,它需要Runtime Callable Wrapper(Visual Studio将为您创建)和COM Callable Wrapper(需要使用ComVisible装饰.NET成员)。

    要从.NET访问COM对象的vtable,它需要是您正在访问的真实COM组件,否则它只是@Hans提到的对象引用。