IE浏览器插件开发

.NET
501
0
0
2022-10-10
标签   浏览器

前言

最近需要开发一个新的项目,对接客户的浏览器,拦截他的登录信息,但是只能使用IE浏览器,所以就准备开发一款IE插件。但是网上对chrome的开发教程比较多,IE的教程很少,所以我把我的开发过程记录下来,希望能够给需要的同学一些帮助。这里我们使用的开发语言是C#

Ie的插件有以下几种方式:

  • ActiveX:这种必须在网页内嵌入object对象,本身就已经存在于网页内才能使用,如果网站是自己开发的,可以使用这种方式。
  • BHO:全名浏览器辅助对象,这个是编写独立运行的扩展,和chrome的扩展差不多。
  • 注册表:这种方式可以绑定脚本到IE的右键菜单里,像迅雷或旋风在IE右键里加的“用**下载”就是这种方式

先上效果图:

文件目录结构:

一、开发代码

创建一个包类型的项目,继承Com类实现自己的业务代码,这里省略具体的代码,只需要关注步骤就行
  • 编写代码
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Expando;
using Microsoft.Win32;
using SHDocVw;
using MSHTML;
namespace TrandeIeExtension
{
  [ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
   Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")]
  public interface IObjectWithSite
  {
      [PreserveSig]
      int SetSite([MarshalAs(UnmanagedType.IUnknown)] object site);

      [PreserveSig]
      int GetSite(ref Guid guid, out IntPtr ppvSite);
  }

  public class TradeIeExtension : IObjectWithSite
  {
      public const string BHO_REGISTRY_KEY_NAME =
          "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects";
      private WebBrowser webBrowser;

      public int SetSite(object site){
          // 如果网页为空卸载委托事件 
          if (site == null){
              this.webBrowser.DocumentComplete -= this.OnDocumentComplete;
              this.webBrowser                  =  null;
          }
          // 网页不为空挂载委托事件 
          else{
              webBrowser                  =  (WebBrowser) site;
              webBrowser.DocumentComplete += this.OnDocumentComplete;
          }
          return 0;
      }

      public void OnDocumentComplete(object pDisp, ref object URL){
          HTMLDocument document = (HTMLDocument) this.webBrowser.Document;
          HTMLHeadElement head = (HTMLHeadElement) ((IHTMLElementCollection) document.all.tags("head")).item(null, 0);
          IHTMLScriptElement scriptObject = (IHTMLScriptElement) document.createElement("script");
          scriptObject.type = @"text/javascript";
          scriptObject.text = "alert(1)";
          head.appendChild((IHTMLDOMNode) scriptObject);
      }

      public int GetSite(ref Guid guid, out IntPtr ppvSite){
          IntPtr punk = Marshal.GetIUnknownForObject(this.webBrowser);
          int    hr   = Marshal.QueryInterface(punk, ref guid, out ppvSite);
          Marshal.Release(punk);
          return hr;
      }

      [ComRegisterFunction]
      public static void RegisterBHO(Type type){
          RegistryKey registryKey =
              Registry.LocalMachine.OpenSubKey(BHO_REGISTRY_KEY_NAME, true);
          if (registryKey == null)
              registryKey = Registry.LocalMachine.CreateSubKey(
                  BHO_REGISTRY_KEY_NAME);
          string      guid   = type.GUID.ToString("B");
          RegistryKey ourKey = registryKey.OpenSubKey(guid);
          if (ourKey == null){
              ourKey = registryKey.CreateSubKey(guid);
          }
          ourKey.SetValue("NoExplorer", 1, RegistryValueKind.DWord);
          registryKey.Close();
          ourKey.Close();
      }

      [ComUnregisterFunction]
      public static void UnregisterBHO(Type type){
          RegistryKey registryKey =
              Registry.LocalMachine.OpenSubKey(BHO_REGISTRY_KEY_NAME, true);
          string guid = type.GUID.ToString("B");
          if (registryKey != null)
              registryKey.DeleteSubKey(guid, false);
      }
  }
}
  • 编译dll

编译成dll,打开AssemblyInfo.cs中的Com可见,这个很重要,否则后面不能注册

[assembly: ComVisible(true)]

导入的系统依赖,比如SHDocVw,MSHTML请设置为编译时复制,否则插件可能不会执行。

二、强签名

生成的dll默认没有签名,系统认为是不安全的,我们要手动签名,主要会用到ilasm.exe和ildasm.exe这两个工具
  • Visual Studio

如果你使用的visual studio那么你可以直接在开始菜单打开Developer Command Prompt for VS xxxx控制台,就可以使用这两个工具

  • 系统自带

如果你没有visual studio环境,那可以使用系统自带的这两款工具,所在目录:

ildasm:C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\ildasm.exe

ilasm:C:\Windows\Microsoft.NET\Framework\v4.0.30319\ilasm.exe

  • 签名步骤
这里使用的visual studio控制台,假设我们的dll文件叫main.dll
// 创建snk文件,名字自取
sn -k /your/path/main.snk

// 创建.il文件,请用绝对路径,名字自取
ildasm \your\path\main.dll /out:\your\path\main.il

// 使用snk签名dll并生成新dll,mainEx.dll是签名后新生成的dll名字
ilasm your\path\main.il /res:your\path\main.res /dll /key:your\path\main.snk /out:your\path\mainEx.dll

// 检查一下生成的新dll是否可用
sn -vf mainEx.dll

最终命令行会输出以下内容,表示签名成功

Resolving local member refs: 0 -> 0 defs, 0 refs, 0 unresolved
Writing PE file
Signing file with strong name
Operation completed successfully

三、注册组件

会使用到Regasm.exe这个工具

Regasm是系统自带比较老的Com注册工具,请进入它的目录再使用,所在目录径:

regasm:C:\Windows\Microsoft.NET\Framework\v4.0.30319

执行注册命令

Regasm /codebase your\path\mainEx.dll /u
Regasm /codebase your\path\mainEx.dll

命令行会输出以下内容,表示注册成功

Microsoft .NET Framework 程序集注册实用工具版本 4.7.3190.0
(适用于 Microsoft .NET Framework 版本 4.7.3190.0)
版权所有 (C) Microsoft Corporation。保留所有权利。

成功注册了类型

四、调试

打开IE浏览器,会提示是否加载新插件,点确定。随便访问一个网页,如果成功执行了我们的代码,说明插件运行成功