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

简介: 上一回我们试验了通过反射的方式获取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字节码。

目录
相关文章
|
10月前
|
安全 算法 网络协议
解析:HTTPS通过SSL/TLS证书加密的原理与逻辑
HTTPS通过SSL/TLS证书加密,结合对称与非对称加密及数字证书验证实现安全通信。首先,服务器发送含公钥的数字证书,客户端验证其合法性后生成随机数并用公钥加密发送给服务器,双方据此生成相同的对称密钥。后续通信使用对称加密确保高效性和安全性。同时,数字证书验证服务器身份,防止中间人攻击;哈希算法和数字签名确保数据完整性,防止篡改。整个流程保障了身份认证、数据加密和完整性保护。
|
7月前
|
Go
在golang中发起http请求以获取访问域名的ip地址实例(使用net, httptrace库)
这只是追踪我们的行程的简单方法,不过希望你跟着探险家的脚步,即使是在互联网的隧道中,也可以找到你想去的地方。接下来就是你的探险之旅了,祝你好运!
395 26
|
7月前
|
数据采集 监控 API
加密货币 Pump 监测刮刀工具开发原理及实现路径
开发Pump监测刮刀工具需综合运用高频数据采集、波动率建模、跨平台对冲三大核心技术,2025年的技术瓶颈已从基础数据获取转向超低延迟执行与合规适配。建议采用模块化开发策略,优先实现核心监控功能,再逐步接入AI决策与链上套利模块。代码示例需根据最新交易所API文档动态调整,并严格遵守所在地监管法规。
|
存储 数据安全/隐私保护
.NET Core 究竟隐藏着怎样的神秘力量,能实现强身份验证与数据加密?
【8月更文挑战第28天】在数字化时代,数据安全与身份验证至关重要。.NET Core 提供了强大的工具,如 Identity 框架,帮助我们构建高效且可靠的身份验证系统,并支持高度定制化的用户模型和认证逻辑。此外,通过 `System.Security.Cryptography` 命名空间,.NET Core 还提供了丰富的加密算法和工具,确保数据传输和存储过程中的安全性。以下是一个简单的示例,展示如何使用 .NET Core 的 Identity 框架实现用户注册和登录功能。
163 3
|
12月前
|
安全 算法 网络协议
【网络原理】——图解HTTPS如何加密(通俗简单易懂)
HTTPS加密过程,明文,密文,密钥,对称加密,非对称加密,公钥和私钥,证书加密
|
Java Maven 数据安全/隐私保护
如何实现Java打包程序的加密代码混淆,避免被反编译?
【10月更文挑战第15天】如何实现Java打包程序的加密代码混淆,避免被反编译?
2576 2
|
存储 安全 算法
网络安全与信息安全:构建数字世界的防线在数字化浪潮席卷全球的今天,网络安全与信息安全已成为维系现代社会正常运转的关键支柱。本文旨在深入探讨网络安全漏洞的成因与影响,剖析加密技术的原理与应用,并强调提升公众安全意识的重要性。通过这些综合性的知识分享,我们期望为读者提供一个全面而深刻的网络安全视角,助力个人与企业在数字时代中稳健前行。
本文聚焦网络安全与信息安全领域,详细阐述了网络安全漏洞的潜在威胁、加密技术的强大防护作用以及安全意识培养的紧迫性。通过对真实案例的分析,文章揭示了网络攻击的多样性和复杂性,强调了构建全方位、多层次防御体系的必要性。同时,结合当前技术发展趋势,展望了未来网络安全领域的新挑战与新机遇,呼吁社会各界共同努力,共筑数字世界的安全防线。
|
存储 开发框架 .NET
浅析.NET6中的await原理
浅析.NET6中的await原理
209 1
|
存储 算法 Java
深入理解.NET中的托管堆及其工作原理
【8月更文挑战第31天】
209 2
|
存储 算法 网络安全
二进制加密PHP Webshell原理及简单实现
二进制加密PHP Webshell原理及简单实现
389 8