从C#访问COM vtable
有没有办法在C#中访问COM对象的虚方法表以获取函数的地址?
经过大量的搜索和拼凑不同的部分解决方案,我想出了如何做到这一点。
首先,您需要为要尝试访问的对象定义COM coclass:
[ComImport, Guid("..."), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface ISomeCOMInterface { // Define interface methods here, using PInvoke conversion between types }
接下来,您需要实例化COM对象。 有几种方法可以做到这一点。 由于我对DirectSound感兴趣,我用过:
[DllImport("dsound.dll", EntryPoint = "DirectSoundCreate", ...] static extern void DirectSoundCreate(IntPtr GUID, [Out, MarshalAs(UnmanagedType.Interface)] out IDirectSound directSound, IntPtr pUnkOuter); IDirectSound directSound; DirectSoundCreate(IntPtr.Zero, out directSound, IntPtr.Zero);
因为我现在有了我的COM对象,所以我可以使用Hans对Marshal.GetComInterfaceForObject()
的建议:
IntPtr comPtr = Marshal.GetComInterfaceForObject(directSound, typeof(IDirectSound)); IntPtr vTable = Marshal.ReadIntPtr(comPtr);
作为额外的奖励,您可以像这样迭代vtable函数:
int start = Marshal.GetStartComSlot(typeof(IDirectSound)); int end = Marshal.GetEndComSlot(typeof(IDirectSound)); ComMemberType mType = 0; for (int i = start; i <= end; i++) { System.Reflection.MemberInfo mi = Marshal.GetMethodInfoForComSlot(typeof(IDirectSound), i, ref mType); Console.WriteLine("Method {0} at address 0x{1:X}", mi.Name, Marshal.ReadIntPtr(vTable, i * Marshal.SizeOf(typeof(IntPtr))).ToInt64()); }
额外阅读/参考:
您无法从RCW中挖掘本机接口指针。 但是你可以调用Marshal.GetComInterfaceForObject(),只要你要求正确的界面就应该是好的。 从那里,您可以使用Marshal.ReadIntPtr()来获取v表条目。 Offset 0是QueryInterface,4是AddRef,8是Release,12是第一个接口方法,等等。对于x64代码是双倍的。 Marshal.GetComSlotForMethodInfo()是一个选项。
实际调用该方法需要Marshal.GetDelegateForFunctionPointer(),您需要使用COM接口方法的确切签名声明该委托。 当你正常调用这个方法时,它不会是它的签名,它是[PreserveSig]签名。 换句话说,返回HRESULT的函数和返回值的ref参数。
轰炸你的计划的机会很多。
更新后:您需要Marshal.GetFunctionPointerForDelegate和Marshal.WriteIntPtr来修补v表插槽条目。
我能想到的最接近的是Marshal.GetFunctionPointerForDelegate
,尽管这至少是从非托管COM方法中删除的一个级别(因为COM调用将包装在.NET委托中)。
你需要这些信息是什么?
你确定你在询问C#吗?
无论方法是否为虚拟,您都不需要在C#中获取函数地址。 您可以实例化一个委托 ,该委托包含对该方法的托管引用。 如果使用虚方法实例化委托,则将虚拟调用该方法,即它将调用最派生的覆盖。
C#中没有必要读取像原始vtable那样的系统内部。
上述就是C#学习教程:从C#访问COM vtable分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注---计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1010600.html