browser icon
You are using an insecure version of your web browser. Please update your browser!
Using an outdated browser makes your computer unsafe. For a safer, faster, more enjoyable user experience, please update your browser today or try a newer browser.

控制 IE 中 ActiveX 控件的初始化

Posted by on 2009 年 09 月 02 日

你可以任意转载本文,但请在转载后的文章中注明作者和原始链接。
媒体约稿请联系 titilima_AT_163.com(把“_AT_”换成“@”)。

网页内嵌的 ActiveX 通常是通过 HTML 的 <param> 标签来进行初始化的,例如:

1
2
3
4
<object classid=clsid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx>
    <param name="param1" value="value1" />
    <param name="param2" value="value2" />
</object>

虽然由 <param> 指定的各种属性可以在运行时通过 ActiveX 对象接口中相应的 put/get 方法进行存取,但这种方法并不是对所有的属性都有效。例如,IShockwaveFlash 的 WMode 属性。
为了能够完全控制 IE 之中 ActiveX 控件的初始化,也就是以指定的属性来初始化 ActiveX 控件,就必须在 ActiveX 创建之前做出相应的处理。在这之前,让我们先看一看 Trident 内核之中 ActiveX 控件的创建和初始化机制:

  1. 调用 CoGetClassObjectFromURL 创建目标对象的类厂;
  2. 调用类厂的 CreateInstance,创建目标对象;
  3. 从目标对象接口中查询 IPersistPropertyBag 接口,并调用 IPersistPropertyBag::Load 加载由 Trident 内核解析出来的属性包;
  4. 根据属性包初始化 ActiveX 控件。

这个过程虽然只有简单的 4 个步骤,但探究的过程却是十分漫长的,在此略过不叙。
针对这 4 个步骤,我们可以相应地使用以下策略来最终控制目标对象的初始化:

  1. 挂钩 CoGetClassObjectFromURL,捕获目标 ActiveX 的类厂,替换或挂钩类厂的 CreateInstance 方法;
  2. 在调用类厂的 CreateInstance 创建出 ActiveX 实例对象之后,查询其 IPersistPropertyBag 接口,并挂钩该接口的 Load 方法;
  3. 当执行的流程进入到 IPersistPropertyBag::Load 之后就可以接管由 Trident 传入的 IPropertyBag 接口了,挂钩其 Read 方法;
  4. 在挂钩后的 IPropertyBag::Read 方法中处理感兴趣的属性和属性值。

代码就不给出了,几个钩子而已。套用一句去年蛮流行的歌词,曰:

有挂钩就会有奇迹。

订阅本站

8 Comments

  • At 2009.09.14 11:25, 初学者 said:

    不知道在哪留言合适,想请教一个问题,windows mobile 开发选什么书入门比较合适。
    从当当网上看了很多,感觉没有合适的。准备用C++开发,开发工具是VS 2008 ,有桌面程序开发经验3年

    • At 2009.09.14 12:25, 李马 said:

      既然有桌面开发的经验,Windows Mobile 可以很快上手。最好的办法是到书店自己选一下,选自己适合的书。

      • At 2012.03.28 15:51, 匿名 said:

        你好,我想请问下,怎么hook 对象的interface中的一个function(查询其 IPersistPropertyBag 接口,并挂钩该接口的 Load 方法),可不可以把代码发给我下,我的邮箱是kelean@126.com

        • At 2012.03.28 15:57, 李马 said:

          查到接口指针之后,根据虚表中的槽位就可以定位到 Load 的地址了。代码被用于工作,因保密原因而不能提供,请见谅。

          • At 2012.03.30 16:56, 匿名 said:

            多谢,我尝试一下

            • At 2012.04.09 15:39, 匿名 said:

              多谢,我试了一下,成功了,还想请教下,IE 和Flash.ocx之间的交互流程大概是怎么样的,比如创建、传递参数给Flash.ocx?

              • At 2012.04.10 09:33, 李马 said:

                可以自己写一个简单的 ActiveX,然后在各个入口下断点跟踪一下。

        • At 2012.03.30 16:58, fantasy said:

          看了你写的blog,与我们目前的项目相关,问下最近有换工作的意愿么?

          (Required)
          (Required, will not be published)