简体   繁体   English

C# - EasyHook CoCreateInstance

[英]C# - EasyHook CoCreateInstance

I'm working the open source library EasyHook . 我正在使用开源库EasyHook

What I'm trying to do, is hook into when a VB6 app calls CoCreateInstance from ole32.dll on a particular CLSID, return my own C# implementation for the object rather than the true COM object. 我正在尝试做的是,当VB6应用程序从特定CLSID上的ole32.dll调用CoCreateInstance时返回,返回我自己的对象而不是真正的COM对象的C#实现。 My C# implementation derives from the same interface that tlbimp.exe spits out for the COM object I want to replace. 我的C#实现源自tlbimp.exe为我想要替换的COM对象吐出的相同接口。

My hook works, and I'm able to hook into calls, log data about the call, and then p/invoke CoCreateInstance from C# to allow the VB6 application to run as normal. 我的钩子工作,我能够挂钩调用,记录有关调用的数据,然后从C#调用CoCreateInstance以允许VB6应用程序正常运行。

I'm noticing that the COM object that I want to replace isn't passed through my hook. 我注意到我要替换的COM对象没有通过我的钩子传递。

Does anyone know how VB6 loads ocx files under the hood? 有谁知道VB6如何在引擎盖下加载ocx文件? Am I hooking into the proper native api call? 我是否正在接听正确的原生api电话?

Or is what I'm trying to do impossible due to the nature of .Net? 或者由于.Net的性质,我正在努力做什么?

UPDATE: An alternate solution is to write a COM object to replace the old one, but we cannot get this to work. 更新:另一种解决方案是编写一个COM对象来替换旧对象,但我们无法使其工作。 Here is an old post that I closed on the subject: Replace COM object 这是我关于主题的旧帖子: 替换COM对象

UPDATE: After further inspection, we are able to regsvr32 /u the old ocx file and use regasm to register our .Net dll. 更新:进一步检查后,我们能够regsvr32 / u旧的ocx文件并使用regasm注册我们的.Net dll。 We put a MessageBox in the constructor of our COM object and the VB6 app loads and pops the box, but it crashes as soon as it makes the first method call on the object. 我们在我们的COM对象的构造函数中放置一个MessageBox,并且VB6应用程序加载并弹出框,但是一旦它对对象进行第一次方法调用就会崩溃。

I suspect that we have some method signatures wrong, also we are using what tlbimp.exe gave us when we ran it on the target ocx we want to replace. 我怀疑我们有一些方法签名错误,我们也正在使用tlbimp.exe在我们想要替换的目标ocx上运行时给我们的内容。 Is it possible that tlbimp is making changes to the signatures that is preventing VB6 apps from loading our assembly? 是否有可能tlbimp正在对阻止VB6应用加载我们的程序集的签名进行更改?

For example sometimes COM signature will look like: 例如,有时COM签名看起来像:

HRESULT MyMethod(IUnknown* ppv);

And tlbimp.exe will give C# something like: 并且tlbimp.exe会给C#这样的东西:

IUnknown MyMethod();

Which looks much cleaner to a C# developer. 这对C#开发人员来说看起来更干净。 Does anyone know about this, or a good article that could explain how to write a "binary compatible" COM assembly from C# to replace an ocx file? 有没有人知道这个,或者一篇好文章可以解释如何从C#编写“二进制兼容”COM程序集来替换ocx文件?

Couple of comments: First, VB6 does not use CoCreateInstance on "local" classes, ie classes from the same project -- it calls "constructor" directly. 几点评论:首先,VB6不对“本地”类使用CoCreateInstance,即来自同一项目的类 - 它直接调用“构造函数”。 Second, you have to hook CoCreateInstance on the import section of every dll/ocx the CLSID can be cocreated from. 其次,你必须在每个dll / ocx的导入部分挂钩CoCreateInstance,CLSID可以从中进行处理。

A better way is just to register you "upgraded" COM component with the same coclass CLSID. 更好的方法是使用相同的coclass CLSID注册“升级”的COM组件。 This way it will be automagically used by the client app. 这样,它将由客户端应用程序自动使用。

Edit: Or take a look at CoTreatAsClass function. 编辑:或者看看CoTreatAsClass函数。

If you have the source code for the original component, apparently VBMigration Partner can upgrade a VB6 COM component to a VB.Net component that has binary compatibility with the original VB6 component . 如果你有原始组件的源代码,显然VBMigration Partner 可以将VB6 COM组件升级到与原始VB6组件具有二进制兼容性的VB.Net组件 I don't know whether it supports OCXs. 我不知道它是否支持OCX。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM