IE瀏覽器外掛開發

失色天空發表於2022-04-28

前言

最近需要開發一個新的專案,對接客戶的瀏覽器,攔截他的登入資訊,但是隻能使用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瀏覽器,會提示是否載入新外掛,點確定。隨便訪問一個網頁,如果成功執行了我們的程式碼,說明外掛執行成功

本作品採用《CC 協議》,轉載必須註明作者和本文連結
失色天空

相關文章