點選上方 藍字 江湖評談 設為關註
有小夥伴問: .NET托管入口Main函式可以修改成別的函式,用來作為程式的入口嗎?
答案:當然是可以的。這也算是.NET裏面非常簡單的騷操了。本篇來用最新的.NET8演示下,如何修改Main入口。
1.簡單控制台例子:
namespace ConsoleApp1
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Call Main");
}
static void ABC()
{
Console.WriteLine("Call ABC");
}
}
}
例子裏面有兩個函式:Main和ABC。Main函式是托管入口函式,這裏演示下如何把托管入口函式改為ABC函式。結果是程式啟動會直接打印出 "Call ABC" 字串,而不是 "Call Main" 字串。
以上程式碼執行之後在bin/Debug/net8.0目錄下生成了ConsoleApp1.dll檔,比如我的當前目錄如下:
2.修改
我們需要用到一個工具CFF Explorer_CN(本文底部有這個小工具的下載連結)解析下ConsoleApp1.dll托管動態連結庫。它是類似於PE檢視器的小工具,同時也兼具托管DLL的MSIL數據檢視。如下圖:
把ConsoleApp1.dll拖入到CFF Explorer_CN,展開.NET目錄-】表-】Method表。如下圖所示:
Method表裏面有三個方法,我們只看前兩個方法Main和ABC 。點選下Main,看到Main函式RVA的Value值是0000205E
點選下ABC函式,它的RVA Value值是00002050
知識點來了,JIT編譯MSIL的時候根據RVA的值,進行定位函式頭的位置。既然如此,把Main的RVA Value改成ABC的RVA Value,把ABC的RVA Value改成Main的RVA Value。即可進行Main函式和ABC函式的邏輯調換。
如何改呢?在Main的Value值處雙擊,把Value改成ABC的RVA Value值: 00002050。同樣在ABC的Value值處雙擊,把Value值改成Main的RVA Value值: 0000205E。如下紅框雙擊即可改動數據。
記得關閉ConsoleApp1.dll的時候保存下,不然改動不會生效。
最後cmd切換到ConsoleApp1.dll的目錄,透過dotnet命令執行下下:
dotnet ConsoleApp1.dll
結果如下: