讀者骨董修復菜鳥問了一個有趣問題 - ASP.NET 網站的 .js 以內嵌資源(Embedded Resource)方式存在 .dll 裡,若沒有原始碼或無法重新編譯專案,要如何修改?

我猜想世界或許有某個軟體工具可優雅地完成這項工作,但 .NET 有 ildasm.exeilasm.exe CIL(MSIL) 反組譯及編譯工具就能處理。該花時間尋找現成工具,還是直接用 .NET 內建工具搞定?好問題。只要 .NET 做法不複雜,我通常會選擇後者,花的時間還比較少。

用 ildasm 跟 ilasm 直接修改 dll/exe 省去重新編譯的技巧之前用過(例如:處理 ODP.NET 參照版號),原理單純程序還算簡單,但改 Embedded Resource 我就沒玩過了,試試也好。

先做一個測試用的 .NET 4.5.2 Console Application 小專案,內嵌一個 embd-text.txt 文字檔:(文字檔隨便寫入「text embedded as resouce」)

Porgram.cs 內容很簡單,GetManifestResourceNames() 查到 embd-text.txt 的完整名稱(或者直接寫死 Namespace.embd-text.txt 也成),然後 GetManifestResourceStream(...) 取得 Stream 讀取內容並顯示:

using System;
using System.IO;
using System.Linq;

namespace EmbTextDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            var asm = typeof(Program).Assembly;
            var resFullName = asm.GetManifestResourceNames()
                .SingleOrDefault(o => o.EndsWith("embd-text.txt"));
            Console.WriteLine("Embedded Resounce Name = " + resFullName);
            using (var sr = new StreamReader(asm.GetManifestResourceStream(resFullName)))
            {
                var text = sr.ReadToEnd();
                Console.WriteLine("Embedded Test = " + text);
            }
        }
        //ildasm EmbTextDemo.exe /output=EmbTextDemo.il
        //ilasm EmbTextDemo.il /exe /output=EmbTextDemo-fixed.exe (若為 dll 則用 /dll)

    }
}

執行程式,順利得到預期結果:

接下來示範在只有 EmbTextDemo.exe 的情況下修改內嵌的 embd-text.txt 內容。

ilasm 與 ildasm 會隨 Visual Studio 一起安裝,但需設定 PATH 環境變數才找到得。要執行它最簡單的方法是從開啟程式集點開Visual Studio Developer Command Prompt 或 Developer PowerShell

或是在 Visual Studio 專案按右鍵選「Open in Terminal」:

修改操作程序如下:

  1. ildasm EmbTextDemo.exe /output=EmbTextDemo.il 反組譯出 EmbTextDemo.il 及 EmbTextDemo.embd-text.txt 兩個檔案。
  2. 在 EmbTextDemo.il 可以看到以下內容,標示有段資源在 EmbTextDemo.embd-text.txt 資源檔:
    .mresource public 'EmbTextDemo.embd-text.txt'
    {
    // Offset: 0x00000000 Length: 0x00000020
    // WARNING: managed resource file 'EmbTextDemo.embd-text.txt' created
    }
    
  3. 修改 EmbTextDemo.embd-text.txt 內容
  4. 重新將 EmbTextDemo.il 編譯成 .exe ilasm EmbTextDemo.il /exe /output=EmbTextDemo-fixed.exe
  5. 搞定收工

來個一鏡到底的展示:

  1. 原本 .exe 執行顯示 text embedded as resouce
  2. ildasm 反組譯
  3. 檢查 EmbTextDemo.embd-text.txt 內容
  4. 用 echo >> 技巧在 EmbTextDemo.embd-text.txt 附加一段文字
  5. 確認 EmbTextDemo.embd-text.txt 已加料
  6. ilasm 重新編譯存成 EmbTextDemo-fixed.exe
  7. 修改版 .exe 成功輸出加料文字

Example of using ildasm and ilasm to change embedded resouce in .dll/.exe without source code.


Comments

# by wish

有個工具叫做dnspy 可以試試

# by Jeffrey

to wish, 謝謝回饋。dnSpy 可以檢視及抽換內嵌資源檔,但好像沒法直接修改。一併附上推坑文 「沒有原始碼也能改程式? .NET 除錯神器 - dnSpy」https://blog.darkthread.net/blog/dnspy/

Post a comment