日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > C# >内容正文

C#

如何从 dump 文件中提取出 C# 源代码?

發(fā)布時(shí)間:2023/12/4 C# 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何从 dump 文件中提取出 C# 源代码? 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一:背景

相信有很多朋友在遇到應(yīng)用程序各種奇葩問(wèn)題后,拿下來(lái)一個(gè)dump文件,辛辛苦苦分析了大半天,終于在某一個(gè)線程的調(diào)用棧上找到了一個(gè)可疑的方法,但 windbg 常常是以 匯編 的方式顯示方法代碼的,可惜的是,現(xiàn)如今的匯編,有多少像我們這些速成系碼農(nóng)還看的懂呢?????????????

接下來(lái)尖銳的問(wèn)題就來(lái)了,如何將這些匯編代碼轉(zhuǎn)成 C# 源代碼,如果轉(zhuǎn)不成源代碼轉(zhuǎn)成 IL代碼也好呀,起碼我努努力還是能試著看的懂的。。。

本篇我就來(lái)分享下如何把 dump 中的方法源碼提取出來(lái)。

二:從 dump 文件中提取源代碼

1. 案例演示

為了能夠演示方便,我用 .netcore 3.1 ?寫(xiě)了一個(gè)簡(jiǎn)單的demo,代碼如下:

namespace?ConsoleApp6 {class?Program{static?void?Main(string[]?args){Run();}static?void?Run(){Console.WriteLine("hello?world!");Console.ReadLine();}} }

將程序跑起來(lái)后,使用 任務(wù)管理器, adplus, procdump 隨便哪一個(gè)抓取 dump 都可以。

2. 使用 lm + savemodule 命令提取

如果你的程序足夠簡(jiǎn)單,可以直接用 lm 獲取程序中所有的模塊,然后使用 savemodule 將模塊導(dǎo)出為 exe/dll 物理文件,如下所示:

  • 使用 lm 提取出所有模塊

0:000>?lm start?????????????end?????????????????module?name 000002c2`264b0000?000002c2`264b8000???ConsoleApp6_2c2264b0000???(deferred)????????????? 00007ff7`e4a50000?00007ff7`e4a7f000???ConsoleApp6???(deferred)????????????? 00007ffa`a4b50000?00007ffa`a546d000???System_Private_CoreLib???(deferred)????????????? 00007ffa`a5470000?00007ffa`a59df000???coreclr????(deferred)????????????? 00007ffa`df070000?00007ffa`df1b2000???clrjit?????(deferred)????????????? ...

可以隱約的看到,我有一個(gè)名為 ConsoleApp6_2c2264b0000 的模塊,這就是我要提取的 ConsoleApp6.exe,順便提一下,那個(gè)很礙眼的 ConsoleApp6 (deferred) 是 PE 文件,要問(wèn)我怎么知道的?試一下就好啦????

  • 使用 savemodule 提取

從上面第一行 start 列中可以看到 ConsoleApp6_2c2264b0000 的開(kāi)始地址為 000002c2264b0000,接下來(lái)用 savemodule 導(dǎo)出到 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 里面多了一個(gè) ConsoleApp6.exe ????,有了這玩意看源碼就簡(jiǎn)單多了,直接用 ILSpy 對(duì)其進(jìn)行反編譯即可。

3. 使用 dumpdomain/module + savemodule 提取

實(shí)際開(kāi)發(fā)中有可能你的程序非常復(fù)雜,使用 lm 直接提取模塊是找不到的,最好的辦法就是 按圖索驥 的方式尋找你要的 module,還記得 CLR Via C# 上說(shuō)過(guò)的 AppDomain,Assembly,Module 之間的關(guān)系嗎?如果要詳細(xì)了解,建議翻看一下,這里我大概簡(jiǎn)述一下, Assembly 一般包含若干個(gè) Module + 資源文件, Assembly 就是一個(gè) dll/exe 文件,程序跑起來(lái)后,Assembly是被妥善安置在 AppDomain 中的。

有了上面這個(gè)思想,是不是就可以通過(guò)這個(gè)流程 AppDomain -> Assembly -> Module 找到 module 啦?接下來(lái)看看如何去實(shí)現(xiàn)。

  • 使用 !dumpdomain 找到 ConsoleApp6 所在的程序域

0:000>?!dumpdomain -------------------------------------- System?Domain:??????00007ffaa59996f0 LowFrequencyHeap:???00007FFAA5999C58 HighFrequencyHeap:??00007FFAA5999CE8 StubHeap:???????????00007FFAA5999D78 Stage:??????????????OPEN Name:???????????????None -------------------------------------- Domain?1:???????????000002c224b6ca80 LowFrequencyHeap:???00007FFAA5999C58 HighFrequencyHeap:??00007FFAA5999CE8 StubHeap:???????????00007FFAA5999D78 Stage:??????????????OPEN Name:???????????????clrhost Assembly:???????????000002c224bf1c00?[C:\Program?Files\dotnet\shared\Microsoft.NETCore.App\3.1.12\System.Private.CoreLib.dll] ClassLoader:????????000002C224B61820Module00007ffa45984020????C:\Program?Files\dotnet\shared\Microsoft.NETCore.App\3.1.12\System.Private.CoreLib.dllAssembly:???????????000002c224bf1980?[E:\net5\ConsoleApp3\ConsoleApp6\bin\Debug\netcoreapp3.1\ConsoleApp6.dll] ClassLoader:????????000002C224BE3F80Module00007ffa45b5f7d0????E:\net5\ConsoleApp3\ConsoleApp6\bin\Debug\netcoreapp3.1\ConsoleApp6.dll

尷尬,記得不錯(cuò)的話,在 .NET Framework 中默認(rèn)會(huì)有三個(gè)應(yīng)用程序域。

  • System Domain

  • Shared Domain

  • Domain 1

咋到 .NET Core 上就丟了一個(gè) Shard Domain 呢 ????????????,先不管啦,從圖中可以清楚的看到 Domian 1 上有我的dll E:\net5\ConsoleApp3\ConsoleApp6\bin\Debug\netcoreapp3.1\ConsoleApp6.dll,同時(shí)還有一個(gè) module 的地址 00007ffa45b5f7d0。

  • 使用 !dumpmodule 獲取 module 詳細(xì)信息

0:000>?!DumpModule?/d?00007ffa45b5f7d0 Name:?E:\net5\ConsoleApp3\ConsoleApp6\bin\Debug\netcoreapp3.1\ConsoleApp6.dll Attributes:??????????????PEFile?SupportsUpdateableMethods? Assembly:????????????????000002c224bf1980 BaseAddress:?????????????000002C2264B0000 PEFile:??????????????????000002C224BF2300 ModuleId:????????????????00007FFA45B5FB98 ModuleIndex:?????????????0000000000000001 LoaderHeap:??????????????0000000000000000 TypeDefToMethodTableMap:?00007FFA45B3C8D0 TypeRefToMethodTableMap:?00007FFA45B3C8E8 MethodDefToDescMap:??????00007FFA45B3C958 FieldDefToDescMap:???????00007FFA45B3C978 MemberRefToDescMap:??????0000000000000000 FileReferencesMap:???????00007FFA45B3C988 AssemblyReferencesMap:???00007FFA45B3C990 MetaData?start?address:??000002C2264B2078?(1304?bytes)

從上面的 BaseAddress: 000002C2264B0000 可以看出,module 的start 地址為 000002C2264B0000,是不是和剛才我用 lm 提取出來(lái)的地址一致哈,最后用 savemodule 導(dǎo)出一下就可以啦,為了做區(qū)分,我取名為 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

哈哈,剩下來(lái)的就是用 ILSpy 反編譯 CosoleApp7 啦。

END

工作中的你,是否已遇到 ...?

1. CPU爆高

2. 內(nèi)存暴漲

3. 資源泄漏

4. 崩潰死鎖

5. 程序呆滯

等緊急事件,全公司都指望著你能解決...? 危難時(shí)刻才能展現(xiàn)你的技術(shù)價(jià)值,作為專(zhuān)注于.NET高級(jí)調(diào)試的技術(shù)博主,歡迎微信搜索: 一線碼農(nóng)聊技術(shù),免費(fèi)協(xié)助你分析Dump文件,希望我能將你的踩坑經(jīng)驗(yàn)分享給更多的人。

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的如何从 dump 文件中提取出 C# 源代码?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。