我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

如何从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 提取出所有模块

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)             
...

可以隐约的看到,我有一个名为 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 sections in file
section 0 - VA=2000, VASize=6c4, FileAddr=200, FileSize=800
section 1 - VA=4000, VASize=564, FileAddr=a00, FileSize=600
section 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 所在的程序域

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:        000002C224B61820
  Module
  00007ffa45984020    C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.12\System.Private.CoreLib.dll

Assembly:           000002c224bf1980 [E:\net5\ConsoleApp3\ConsoleApp6\bin\Debug\netcoreapp3.1\ConsoleApp6.dll]
ClassLoader:        000002C224BE3F80
  Module
  00007ffa45b5f7d0    E:\net5\ConsoleApp3\ConsoleApp6\bin\Debug\netcoreapp3.1\ConsoleApp6.dll

尴尬,记得不错的话,在 .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 详细信息

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 提取出来的地址一致哈,最后用 savemodule 导出一下就可以啦,为了做区分,我取名为 ConsoleApp7.exe, 如下所示:

哈哈,剩下来的就是用 ILSpy 反编译 CosoleApp7 啦。

以上就是如何从dump文件中提取出C#源代码的详细内容,更多关于dump 文件中提取出 C# 源代码的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

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

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

C++如何从文件中提取英文单词

本篇内容主要讲解“C++如何从文件中提取英文单词”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++如何从文件中提取英文单词”吧!思路:1.打开文件2.读取每一行3.找到特殊的标点符号的位置,进
2023-07-02

c语言如何从文件中读取数据

在C语言中,我们可以使用以下步骤从文件中读取数据:1. 打开文件:使用`fopen()`函数打开文件,它接受两个参数,一个是文件名,另一个是打开方式(如"r"表示只读模式)。```cFILE *file = fopen("filename.
2023-09-20

Linux中如何从ISO镜像提取和复制文件

这篇文章给大家分享的是有关Linux中如何从ISO镜像提取和复制文件的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。在 Linux 系统下提取 ISO 镜像文件为了完成该测试,你得有一个 ISO 镜像文件(我使用
2023-06-27

如何提高Android从文件中读取图像的效率

本篇文章给大家分享的是有关如何提高Android从文件中读取图像的效率,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。方法一start_time = System.current
2023-05-31

如何将文本数据从HTML或其他格式中提取出来

这篇文章主要介绍了如何将文本数据从HTML或其他格式中提取出来的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇如何将文本数据从HTML或其他格式中提取出来文章都会有所收获,下面我们一起来看看吧。一、使用strip
2023-07-05

TS如何从目录中提取所有指定扩展名的文件

.ts是一种高清视频封装格式文件,全称为MPEG2-TS,TS表示TransportStream,这篇文章主要介绍了TS如何从目录中提取所有指定扩展名的文件,需要的朋友可以参考下
2023-05-20

如何描述Python代码加密中源码保护的pyc文件字节码

如何描述Python代码加密中源码保护的pyc文件字节码,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。pyc文件字节码关于Python代码加密这一Python的
2023-06-17

如何用sed从mysqldump全备文件中取出某张表的表结构

如何用sed从mysqldump全备文件中取出某张表的表结构,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。 如何获用sed取mysqldump文件里面的表结构内
2023-06-05

在浏览器中如何展示PHP代码源文件而不让其运行?

标题:如何在浏览器中展示PHP代码源文件而不让其运行?PHP是一种广泛使用的服务器端脚本语言,常用于开发动态网页。然而,在某些情况下,我们可能希望在浏览器中展示PHP代码源文件,而不让其运行。这篇文章将介绍如何实现这一目标,以及提供具体的
在浏览器中如何展示PHP代码源文件而不让其运行?
2024-03-09

C语言如何返回已删除 PHP 注释以及空白字符的源代码文件

本文介绍了一种使用C语言从包含PHP注释和空白字符的代码中恢复原始源代码的方法。该方法涉及打开输入文件、移除注释、移除空白字符,最后写入输出文件。示例代码展示了如何使用正则表达式实现这些步骤。此方法可应用于从带注释的HTML文档中提取嵌入式PHP代码等场景。
C语言如何返回已删除 PHP 注释以及空白字符的源代码文件
2024-04-02

C#中如何使用程序集和DLL文件解决代码模块化问题及解决方法

C#中如何使用程序集和DLL文件解决代码模块化问题及解决方法在C#开发中,代码模块化是很重要的,它可以将代码分成较小的可重用模块,提高代码的可读性和维护性。为了实现代码模块化,C#提供了程序集和DLL文件的概念。程序集是一组相关的代码文件的
2023-10-22

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录