紫雨轩 .Net, DNGuard HVM , .Net VMProtect

DNGuard HVM - Advanced .NET Code Protection Technology

常用链接

统计

积分与排名

友情连接

最新评论

某壳对.Net程序加密的原理及解密探讨二

自上次写第一篇文章到现在不知不觉两个月过去了,这篇文章我们将介绍怎么获取解密后的IL字节代码。
我们先回顾一下前文,在上一回我们提到“InFaceMaxtoCode.Startup 正常启动后,在整个程序集中只会运行一次。”。
当时这种说法是很武断的,如果 “InFaceMaxtoCode.C______(num2, num3)” 的返回值总是 false的话,该函数就会被执行多次,
不过根据后来动态调试的结果,我们证实了“InFaceMaxtoCode.C______(num2, num3)” 的返回值为 true,因此上次的说法是正确的。

现在言归正传,怎么取得解密后的代码呢?大概两个方向,
1.正面交锋,直接攻破maxtocode的运行库。
这就将问题直接回到了传统的win32层面,不过这个东西是业内人士写的在这方面的保护工作做得很好,像我这样的菜鸟就很难直接攻破了。
我曾有一个设想,就是通过分析运行库找到解密函数的入口,然后弄一个stub dll,hook这个地方,把解密后的il代码dump出来。
实际跟踪几次后我就放弃了。从跟踪到的信息来看,我猜测,运行库是通过 mscorwks.dll 挂接到 jit,在jit的前面实时解密代码。
理论上我们也可以挂一个到jit前面,在那里dump解密的il代码,不过这个实现的方式,还不清楚,如果弄明白了,也就能写一个同样原理的加密软件了。
这个难度比较大,所以我最终放弃了这个方案。

2.避开运行库,我们直接利用dotNet 2.0的特性获取IL代码。
如是我就试着用2.0写了一个winform程序,加密,运行,发现报错。
maxtocode3.1不支持2.0的winform程序,这就使我的这个方案实验夭折了。
两个月过去了,发现maxtocode升级到3.11了修正了这个bug,今天终于可以继续实验了。

我们来建一个简单的winform程序。一个窗体,然后一个按钮。
代码如下:


 1
 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Data;
 5 using System.Drawing;
 6 using System.Text;
 7 using System.Windows.Forms;
 8 using System.Reflection;
 9 using Spaces;
10 namespace Test5
11 {
12     public partial class Form1 : Form
13     {
14         public Form1()
15         {
16             InitializeComponent();
17         }
18    
19         private void TestMethod()
20         {
21             //  [7/17/2006]
22             int i = 0;
23             i = 1;
24             i++;
25             if(i>0)
26             {
27                 MessageBox.Show("OK");
28             }
29         }
30 
31         private void button1_Click(object sender, EventArgs e)
32         {
33             Type tp = this.GetType();
34 
35             MethodInfo mi = tp.GetMethod("TestMethod",
36                 BindingFlags.NonPublic|BindingFlags.DeclaredOnly|
37                 BindingFlags.Public|BindingFlags.Static
38                 |BindingFlags.Instance);
39             if(mi == null)
40             {
41                 MessageBox.Show("err");
42                 return;
43             }
44             MethodBody mb = mi.GetMethodBody();
45             byte[] bt= mb.GetILAsByteArray();
46             StringBuilder sb = new StringBuilder();
47             for (int i = 0; i < bt.Length; i++)
48             {
49                 sb.Append(bt[i].ToString("X2"));
50                 sb.Append(" ");
51             }
52             string stxt = sb.ToString();
53             MessageBox.Show(stxt);
54                        
55         } 
56      
57     }
58 }


编译运行,我们点击按钮就能看到 TestMethod 的IL字节码。
然后用maxtocode加密在运行,同样能看到 TestMethod 的IL字节码。
两次看到的结果一样的,这个是当然了,如果不一样,maxtocode就破坏了程序的正确性了。

好了,我们的实验成功了。

看到这里大家应该知道怎么获取解密后的IL代码了吧。

这种方式比在内存里面找代码或者hook到maxtocode解密后dump代码的方式要优越很多,
因为内存dump的方式你还要担心运行时的函数覆盖率,没有运行到的就dump不到。

这种方式我们利用 DotNet的反射机制,可以枚举出程序集中的所有类型,以及每个类型的所有方法,成员,字段,构造函数等。


初步实验了一下,对于加了密的dll文件还是比较好弄的,2.0的、1.1的都能弄出IL代码来。
对于exe文件还有一关需要解决,那就是如何将我们的DotNet dll程序集插入到exe的运行空间中去。


今回就先到这里了,下回再实际写程序演练获取解密后的IL字节代码。

ps:不知道大家手上是否有破解到的 Reflector 的源代码,如果有丢一份给我,感激不尽。

posted on 2006-09-14 20:26 紫雨轩 .Net 阅读(2360) 评论(14)  编辑 收藏 所属分类: 破文

评论

#1楼  2006-09-15 09:41 9527 [未注册用户]

有Reflector源代码的也发给我一份吧,感激不尽
netbird@gmail.com   回复  引用    

#2楼  2006-09-26 15:05 skywalker [未注册用户]

请教一下,是否每解出一段method的il代码,都必须初始化一个实例对象?这样做会不会很麻烦?我试着用你的方法,初始化了一个实例对象,但每次都产生Exception,无法断续下去,该怎么办?   回复  引用    

#3楼 [楼主] 2006-09-26 19:07 瑞克      

不用的。
可以直接使用放射技术枚举所有类型。
下次我会给出一个实例代码演示这个过程。   回复  引用  查看    

#4楼  2006-09-27 14:36 skywalker [未注册用户]

谢谢!这样的话,Exe文件中的类也能恢复出来?   回复  引用    

#5楼 [楼主] 2006-09-27 14:53 瑞克      

exe的需要先解决dll注入的问题,如果能成功将我们的dotnet的dll注入进去,就没有问题了。
  回复  引用  查看    

#6楼  2006-09-27 15:14 skywalker [未注册用户]

不好意思,不太明白。是不是这个意思?如果是DLL的话,用VS新建一项目引用该DLL,然后用上面的方法把对象解出来,而EXE就无法这样做了?   回复  引用    

#7楼 [楼主] 2006-09-27 15:52 瑞克      

是的,无法用新建项目引用exe的方法来这样做。
只能是把我们的功能包含在一个dll中,想办法然这个exe或者该exe引用的某个dll调用我们的dll。   回复  引用  查看    

#8楼 [楼主] 2006-09-27 15:54 瑞克      

对于既有exe有又dll的,我们可以先突破dll,然后通过修改dll来调用我们的代码。
  回复  引用  查看    

#9楼  2006-09-27 17:35 skywalker [未注册用户]

呵呵,有意思   回复  引用    

#10楼  2006-09-28 21:55 skywalker [未注册用户]

期待获取DLL解密后的IL字节代码,到源程序的整个过程的演示   回复  引用    

#11楼  2006-09-29 16:32 Wisdom-zh      

新思路,新思维。
我原先就反对那种类似 Win32 加壳的那种硬加密,倾向于混淆的这种软加密,这种才真正的不可逆啊!
并且没有性能问题。   回复  引用  查看    

#12楼 [楼主] 2006-09-29 16:49 瑞克      

呵呵是啊,这种硬加密的,不管加密强度多大,在这个方法面前都没有作用了。。
这种方法对于同类加密型的保护都通吃。
  回复  引用  查看    

#13楼  2006-12-28 17:28 sss      

其实dump一个exe也不需要注入dll的,我在我的blog上讨论了下这个问题,欢迎交流:
http://www.cnblogs.com/workflow/archive/2006/12/28/606278.html   回复  引用  查看    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-04-09 19:48 编辑过
"五向定位"职业成长路线公开课(上海、南京、大连)
Google站内搜索


相关链接: