某壳对.Net程序加密的原理及解密探讨三(实例解密)

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 上一回我们试验了通过反射的方式获取method的源代码。这次我们就用一个实例来演示dump一个程序集中的所有类型和方法的IL源代码。首先打开VS2005 新建一个C#的windows程序:在窗体添加添加一个2个 button,2个label,一个textbox,一个 checkbox,一个savefiledialog。
上一回我们试验了通过反射的方式获取method的源代码。
这次我们就用一个实例来演示dump一个程序集中的所有类型和方法的IL源代码。

首先打开VS2005 新建一个C#的windows程序:
在窗体添加添加一个2个 button,2个label,一个textbox,一个 checkbox,一个savefiledialog。
界面如下:


事件代码如下:
  1    public   class  Form1 : Form
  2        {
  3               //  Methods
  4               // 选择IL字节码保存文件
  5               private   void  button1_Click( object  sender, EventArgs e)
  6  {
  7         if  ( this .saveFileDialog1.ShowDialog()  ==  DialogResult.OK)
  8        {
  9               this .textBox1.Text  =   this .saveFileDialog1.FileName;
 10        }
 11  }
 12                // 点击开始dump。
 13               private   void  button3_Click( object  sender, EventArgs e)
 14  {
 15         this .button3.Enabled  =   false ;
 16         this .DumpAssembly(Assembly.GetExecutingAssembly(),  this .textBox1.Text);
 17        MessageBox.Show( " dump ok " );
 18         this .button3.Enabled  =   true ;
 19  }
 20               // 这个函数将一个Assembly全部dump到path中。
 21               private   void  DumpAssembly(Assembly ass,  string  path)
 22  {
 23        StreamWriter writer1  =   new  StreamWriter(path,  false );
 24        Type[] typeArray1  =  ass.GetTypes();
 25         for  ( int  num1  =   0 ; num1  <  typeArray1.Length; num1 ++ )
 26        {
 27               this .DumpType(typeArray1[num1], writer1);
 28        }
 29        writer1.Flush();
 30        writer1.Close();
 31  }
 32 
 33               // dump单个类型,由dumpassembly调用
 34                private   void  DumpType(Type tp, StreamWriter sw)
 35  {
 36        BindingFlags flags1  =  BindingFlags.NonPublic  |  BindingFlags.Public  |  BindingFlags.Static  |  BindingFlags.Instance  |  BindingFlags.DeclaredOnly;
 37         string  text1  =  tp.ToString();
 38        sw.Write( " TYPE:  "   +  text1  +   " \r\n " );
 39         if  (tp.IsEnum)
 40        {
 41              sw.Write( " IsEnum  " );
 42        }
 43         if  (tp.IsImport)
 44        {
 45              sw.Write( " IsImport  " );
 46        }
 47         if  (tp.IsNested)
 48        {
 49              sw.Write( " IsNested  " );
 50        }
 51         if  (tp.IsClass)
 52        {
 53              sw.Write( " IsClass " );
 54        }
 55        sw.Write( " \r\n " );
 56         if  ((text1  !=   " InFaceMaxtoCode " ||   ! this .checkBox1.Checked)
 57        {
 58              sw.Write( " **********Begin MemberInfo**********\r\n " );
 59              MemberInfo[] infoArray1  =  tp.GetMembers(flags1);
 60               for  ( int  num1  =   0 ; num1  <  infoArray1.Length; num1 ++ )
 61              {
 62                    MemberInfo info1  =  infoArray1[num1];
 63                    sw.Write(info1.MemberType.ToString()  +   " \t "   +  infoArray1[num1].ToString()  +   " \r\n " );
 64                     if  ((info1.MemberType  ==  MemberTypes.Method)  ||  (info1.MemberType  ==  MemberTypes.Constructor))
 65                    {
 66                           this .DumpMethod((MethodBase) info1, sw);
 67                    }
 68              }
 69              sw.Write( " **********  End MemberInfo**********\r\n " );
 70              sw.Write( " \r\n\r\n " );
 71        }
 72  }
 73 
 74   
 75 
 76           // dump单个方法,由dumptype调用
 77            private   void  DumpMethod(MethodBase mb, StreamWriter sw)
 78  {
 79        MethodBody body1  =  mb.GetMethodBody();
 80         if  (body1  !=   null )
 81        {
 82               byte [] buffer1  =  body1.GetILAsByteArray();
 83               try
 84              {
 85                    sw.Write( " \tMaxStackSize:  "   +  body1.MaxStackSize.ToString());
 86                    sw.Write( " \tCodeSize:  "   +  buffer1.Length.ToString());
 87                    sw.Write( " \r\n " );
 88              }
 89               catch  (Exception exception1)
 90              {
 91                    MessageBox.Show( " 1: "   +  mb.ToString()  +   " \r\n "   +  exception1.ToString());
 92              }
 93               foreach  (LocalVariableInfo info1  in  body1.LocalVariables)
 94              {
 95                    sw.Write( " LocalVar:  "   +  info1.ToString());
 96                    sw.Write( " \r\n " );
 97              }
 98              sw.Write( " \r\n\r\n " );
 99              StringBuilder builder1  =   new  StringBuilder();
100               foreach  ( byte  num1  in  buffer1)
101              {
102                    builder1.Append(num1.ToString( " X2 " ));
103              }
104              sw.Write(builder1.ToString());
105              sw.Write( " \r\n\r\n " );
106               foreach  (ExceptionHandlingClause clause1  in  body1.ExceptionHandlingClauses)
107              {
108                    sw.Write(clause1.ToString());
109                    sw.Write( " \r\n " );
110              }
111              sw.Write( " \r\n " );
112        }
113  }
114 
115   
116 
117              
118       
119        }
120 
121 

 

编译这个程序,运行,dump出il字节码,
然后拿 maxtocode加密。再运行,dump出il字节码,然后找一个method 如 button1_click,比较一下他们的IL字节码是否一样。
当然结果应该是一样的。

这里主要有三个关键函数
            private void DumpAssembly(Assembly ass, string path);
            private void DumpMethod(MethodBase mb, StreamWriter sw);
            private void DumpType(Type tp, StreamWriter sw);
这三个就是一个例子演示如何dump整个程序集。

如要dump 一个加密的dll,我们就可以直接用这个程序来改,
首先添加引用,引用那个dll,然后随便实例话一个该dll中的type。
然后获取该dll的 Assembly 对象,再调用DumpAssembly函数即可。

好了,今回就到这里,下回再讲解怎么理解、查看IL字节码。

目录
相关文章
|
3月前
|
存储 数据安全/隐私保护
.NET Core 究竟隐藏着怎样的神秘力量,能实现强身份验证与数据加密?
【8月更文挑战第28天】在数字化时代,数据安全与身份验证至关重要。.NET Core 提供了强大的工具,如 Identity 框架,帮助我们构建高效且可靠的身份验证系统,并支持高度定制化的用户模型和认证逻辑。此外,通过 `System.Security.Cryptography` 命名空间,.NET Core 还提供了丰富的加密算法和工具,确保数据传输和存储过程中的安全性。以下是一个简单的示例,展示如何使用 .NET Core 的 Identity 框架实现用户注册和登录功能。
40 3
|
1月前
|
Java Maven 数据安全/隐私保护
如何实现Java打包程序的加密代码混淆,避免被反编译?
【10月更文挑战第15天】如何实现Java打包程序的加密代码混淆,避免被反编译?
45 2
|
1月前
|
存储 安全 算法
网络安全与信息安全:构建数字世界的防线在数字化浪潮席卷全球的今天,网络安全与信息安全已成为维系现代社会正常运转的关键支柱。本文旨在深入探讨网络安全漏洞的成因与影响,剖析加密技术的原理与应用,并强调提升公众安全意识的重要性。通过这些综合性的知识分享,我们期望为读者提供一个全面而深刻的网络安全视角,助力个人与企业在数字时代中稳健前行。
本文聚焦网络安全与信息安全领域,详细阐述了网络安全漏洞的潜在威胁、加密技术的强大防护作用以及安全意识培养的紧迫性。通过对真实案例的分析,文章揭示了网络攻击的多样性和复杂性,强调了构建全方位、多层次防御体系的必要性。同时,结合当前技术发展趋势,展望了未来网络安全领域的新挑战与新机遇,呼吁社会各界共同努力,共筑数字世界的安全防线。
|
1月前
|
存储 开发框架 .NET
浅析.NET6中的await原理
浅析.NET6中的await原理
43 1
|
1月前
|
XML 存储 安全
C#开发的程序如何良好的防止反编译被破解?ConfuserEx .NET混淆工具使用介绍
C#开发的程序如何良好的防止反编译被破解?ConfuserEx .NET混淆工具使用介绍
60 0
|
2月前
|
Ubuntu 持续交付 API
如何使用 dotnet pack 打包 .NET 跨平台程序集?
`dotnet pack` 是 .NET Core 的 NuGet 包打包工具,用于将代码打包成 NuGet 包。通过命令 `dotnet pack` 可生成 `.nupkg` 文件。使用 `--include-symbols` 和 `--include-source` 选项可分别创建包含调试符号和源文件的包。默认情况下,`dotnet pack` 会先构建项目,可通过 `--no-build` 跳过构建。此外,还可以使用 `--output` 指定输出目录、`-c` 设置配置等。示例展示了创建类库项目并打包的过程。更多详情及命令选项,请参考官方文档。
195 11
|
2月前
|
存储 运维
.NET开发必备技巧:使用Visual Studio分析.NET Dump,快速查找程序内存泄漏问题!
.NET开发必备技巧:使用Visual Studio分析.NET Dump,快速查找程序内存泄漏问题!
|
2月前
|
自然语言处理 C# 图形学
使用dnSpyEx对.NET Core程序集进行反编译、编辑和调试
使用dnSpyEx对.NET Core程序集进行反编译、编辑和调试
|
3月前
|
存储 算法 Java
深入理解.NET中的托管堆及其工作原理
【8月更文挑战第31天】
43 1
|
3月前
|
存储 算法 网络安全
二进制加密PHP Webshell原理及简单实现
二进制加密PHP Webshell原理及简单实现
117 8
下一篇
无影云桌面