如何从 dump 文件中提取出 C# 源代码?
一:背景
相信有很多朋友在遇到應用程序各種奇葩問題后,拿下來一個dump文件,辛辛苦苦分析了大半天,終于在某一個線程的調用棧上找到了一個可疑的方法,但 windbg 常常是以 匯編 的方式顯示方法代碼的,可惜的是,現如今的匯編,有多少像我們這些速成系碼農還看的懂呢?????????????
接下來尖銳的問題就來了,如何將這些匯編代碼轉成 C# 源代碼,如果轉不成源代碼轉成 IL代碼也好呀,起碼我努努力還是能試著看的懂的。。。
本篇我就來分享下如何把 dump 中的方法源碼提取出來。
二:從 dump 文件中提取源代碼
1. 案例演示
為了能夠演示方便,我用 .netcore 3.1 ?寫了一個簡單的demo,代碼如下:
namespace?ConsoleApp6 {class?Program{static?void?Main(string[]?args){Run();}static?void?Run(){Console.WriteLine("hello?world!");Console.ReadLine();}} }將程序跑起來后,使用 任務管理器, adplus, procdump 隨便哪一個抓取 dump 都可以。
2. 使用 lm + savemodule 命令提取
如果你的程序足夠簡單,可以直接用 lm 獲取程序中所有的模塊,然后使用 savemodule 將模塊導出為 exe/dll 物理文件,如下所示:
使用 lm 提取出所有模塊
可以隱約的看到,我有一個名為 ConsoleApp6_2c2264b0000 的模塊,這就是我要提取的 ConsoleApp6.exe,順便提一下,那個很礙眼的 ConsoleApp6 (deferred) 是 PE 文件,要問我怎么知道的?試一下就好啦????
使用 savemodule 提取
從上面第一行 start 列中可以看到 ConsoleApp6_2c2264b0000 的開始地址為 000002c2264b0000,接下來用 savemodule 導出到 E:\dump。
0:000>?!savemodule?000002c2`264b0000?E:\dump\ConsoleApp6.exe 3?ps?in?file p?0?-?VA=2000,?VASize=6c4,?FileAddr=200,?FileSize=800 p?1?-?VA=4000,?VASize=564,?FileAddr=a00,?FileSize=600 p?2?-?VA=6000,?VASize=c,?FileAddr=1000,?FileSize=200然后就可以看到 E:\dump 里面多了一個 ConsoleApp6.exe ????,有了這玩意看源碼就簡單多了,直接用 ILSpy 對其進行反編譯即可。
3. 使用 dumpdomain/module + savemodule 提取
實際開發中有可能你的程序非常復雜,使用 lm 直接提取模塊是找不到的,最好的辦法就是 按圖索驥 的方式尋找你要的 module,還記得 CLR Via C# 上說過的 AppDomain,Assembly,Module 之間的關系嗎?如果要詳細了解,建議翻看一下,這里我大概簡述一下, Assembly 一般包含若干個 Module + 資源文件, Assembly 就是一個 dll/exe 文件,程序跑起來后,Assembly是被妥善安置在 AppDomain 中的。
有了上面這個思想,是不是就可以通過這個流程 AppDomain -> Assembly -> Module 找到 module 啦?接下來看看如何去實現。
使用 !dumpdomain 找到 ConsoleApp6 所在的程序域
尷尬,記得不錯的話,在 .NET Framework 中默認會有三個應用程序域。
System Domain
Shared Domain
Domain 1
咋到 .NET Core 上就丟了一個 Shard Domain 呢 ????????????,先不管啦,從圖中可以清楚的看到 Domian 1 上有我的dll E:\net5\ConsoleApp3\ConsoleApp6\bin\Debug\netcoreapp3.1\ConsoleApp6.dll,同時還有一個 module 的地址 00007ffa45b5f7d0。
使用 !dumpmodule 獲取 module 詳細信息
從上面的 BaseAddress: 000002C2264B0000 可以看出,module 的start 地址為 000002C2264B0000,是不是和剛才我用 lm 提取出來的地址一致哈,最后用 savemodule 導出一下就可以啦,為了做區分,我取名為 ConsoleApp7.exe, 如下所示:
0:000>?!savemodule?000002C2264B0000?E:\dump\ConsoleApp7.exe 3?ps?in?file p?0?-?VA=2000,?VASize=6c4,?FileAddr=200,?FileSize=800 p?1?-?VA=4000,?VASize=564,?FileAddr=a00,?FileSize=600 p?2?-?VA=6000,?VASize=c,?FileAddr=1000,?FileSize=200哈哈,剩下來的就是用 ILSpy 反編譯 CosoleApp7 啦。
END
工作中的你,是否已遇到 ...?
1. CPU爆高
2. 內存暴漲
3. 資源泄漏
4. 崩潰死鎖
5. 程序呆滯
等緊急事件,全公司都指望著你能解決...? 危難時刻才能展現你的技術價值,作為專注于.NET高級調試的技術博主,歡迎微信搜索: 一線碼農聊技術,免費協助你分析Dump文件,希望我能將你的踩坑經驗分享給更多的人。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的如何从 dump 文件中提取出 C# 源代码?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何在 C# 中使用只读的 Collec
- 下一篇: NET问答: C# 中有哪些 HttpP