我有一个 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:我知道这是一种非标准的做事方式,但请理解,我绝对
必须能够以这种方式为我正在从事的项目获取这些地址。这是一个关键的阻碍。
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 ...*/);