C#中COM对象的实际地址

问题描述 投票:0回答:1

我有一个 COM 对象,我试图获取它的实际底层地址,这样我就可以获得 vtable 的地址。我需要这是一个有效的数字地址,因为我需要能够添加它。例如,如果我想调用 vtable 中的第三个函数,我需要能够调用如下内容:

Marshal.GetDelegateForFunctionPointer(vtableaddr + (3 * 8), ...)
;//第3项,64位模式下8字节指针。

调用vtable中的第三个函数。

也就是说,我需要能够对指针地址进行加法。

我在问题标题中指定“实际”的原因是,获取底层对象地址的所有标准方法似乎都没有返回真实地址。 var item = /*... my COM object */; var pUnk = Marshal.GetIUnknownForObject(item); var pVtbl = Marshal.ReadIntPtr(pUnk);

运行此代码时,
pUnk

pVtbl
都会有非常大的数值。类似于 0x1F3110D7948,即 2,143,474,776,392。我的系统肯定没有两万亿字节的 RAM。所以我假设指针在高字节中包含附加信息?
我也尝试过这样的代码:

var gch = GCHandle.Alloc(pUnk, GCHandleType.Pinned); var intptr = gch.AddrOfPinnedObject(); var pVtbl = Marshal.ReadIntPtr(intptr);

并得到同样大的数字。打电话
GCHandle.ToIntPtr(gch)

也没有帮助。

所以我需要知道如何获取内存中底层 COM 对象实际存储位置的

real

地址。 PS:我知道这是一种非标准的做事方式,但请理解,我绝对

必须

能够以这种方式为我正在从事的项目获取这些地址。这是一个关键的阻碍。

c# pointers com interop marshalling
1个回答
0
投票

var item = /*... my COM object */; var pUnk = Marshal.GetIUnknownForObject(item); // Get the address of the vtable IntPtr pVtbl = Marshal.ReadIntPtr(pUnk); // You may want to release the reference to the IUnknown if it's not needed anymore Marshal.Release(pUnk); // Now, you can perform arithmetic on the IntPtr to navigate the vtable IntPtr thirdFunctionAddress = IntPtr.Add(pVtbl, 2 * IntPtr.Size); // Assuming 2 is the index of the third function // Call the function using a delegate var thirdFunction = (YourDelegateType)Marshal.GetDelegateForFunctionPointer(thirdFunctionAddress, typeof(YourDelegateType)); thirdFunction(/*... arguments ...*/);

    IntPtr.Size:IntPtr 的大小取决于平台。在 64 位系统上,通常为 8 字节,在 32 位系统上,通常为 4 字节。通过使用 IntPtr.Size,您的代码变得更加独立于平台。
  1. IntPtr.Add:使用IntPtr.Add方法进行指针运算。此方法旨在与平台的指针大小一起使用。
  2. 释放 IUnknown:在 COM 中,最好在使用完 IUnknown 接口后释放它。这是使用 Marshal.Release 实现的。
© www.soinside.com 2019 - 2024. All rights reserved.