Introduction to Cracking .Net Assembly | 一些.NET程序集的破解初探

0. 起因

当然就是要破解Grasshopper插件。但是其实起源于笔者破解另一个C#程序。

1. .NET

.NET是微软开发的一套技术平台,在其上可以方便快捷地搭建各种应用。.NET应用是基于.NET Framework的,后者是一个类库,一个程序的基础框架,包含很多系统和常用的API。.NET框架主要适合于Windows应用的开发,毕竟是自家的操作系统。当然最近好像也开始支持Linux了,这样基于.NET编写的应用就可以跑在linux。

因为.NET框架在Windows系统上非常通用,所以很多软件都是基于.NET开发的,比如建筑学生最常用的Rhinoceros,以及同样的Rhino插件Grasshopper及GH插件。

.NET框架的一个特点是不限定编程语言,使用C#, VB.NET以及F#均可以开发,这些高级语言具有互操作性,也就是不管用什么语言都可以被编译成一套中间语言。这个机器语言就叫做IL(或叫CIL,Common Intermediate Language)。编译成的IL会存成程序集(Assembly),在磁盘上是后缀dll和exe的文件。具体执行的时候,.NET的一个部件CLR(Common Language Runtime)会对IL做一定处理,并让JIT(just-in-time compiler)把IL翻译为机器码供计算机执行。

做个比喻就是一个人用方言控制一个机器。人可以用意大利语、西班牙语和法语(C#, VB.NET, F#)去说一句话(一个程序),一个翻译官(编译器)可以把这句话无损转化为英语(IL)存储起来(程序集)。具体控制机器的时候,另一个翻译官(CLR)会首先检查一下这句话,然后用手(JIT)把这句话转化成机器语言(汇编),让及其执行。

2. 编译与反编译

上面说到高级语言编译了两次,首先变成IL,然后变成机器语言。反汇编就是一个逆向的过程。比如把IL逆向编译为C#语言。IL读起来费劲一点,C#就轻松多了。

这样我们其实是可以看到C#的程序的,因为我们可以看到IL语言的程序集(dll/exe文件),所以破解呢理论上就是反编译一下程序集,看到C#程序的所有源码,然后找到加密函数,再做研究。

.NET的程序比较容易破解,因为高级语言到IL的步骤还是比较固定的,所以基本都能反编译。但是像C++可能就比较难了(我也没试过不清楚),看很多反编译都是要跟踪CPU和内存推算出注册码加密的地方,动态跟踪程序。。。

3. 混淆/反混淆,加壳/脱壳

当然不是所有软件的作者都希望自己的软件被破解,所以会有一些手段来让自己的程序难以被反编译。一般就叫做加壳,对程序做一定压缩和加密,使得破解者难以看懂程序。与之对应相反的操作就是脱壳。一般破解都是要先脱壳再反编译的。

除了加壳外,还可以混淆代码。混淆后的代码可以被CLR执行,但是人类就比较难看懂了,以及用工具反编译出来的代码可能都是乱码。。。与之相反的是反混淆。

4. 工具

对于.NET就用Reflector就可以了。另外有些程序集做了混淆,就需要用de4dot来反混淆一下。另外还需要Reflector的插件Reflexil来做代码注入,有时候要强行patch程序来破解。

5. Talk is Cheap, Show me the CODE!

Of Course.

首先是看到有人破解Visual Micro,才明白.NET程序集如此好破解的。这个是Visual Studio一个插件,用来写Arduino程序的。

开Reflector,果然有一个函数是检查是否激活的。用Reflexil强行注入代码,改成return true就可以了。


可以参考这篇文章

下面是HAL,作者还是有一点反破解意识的。首先得反混淆一下,然后看代码里是没有全局静态检查license的类的,居然检查函数藏在每个dll里,这个强行patch就比较费劲了。代码混淆过所以变量名基本没法看,笔者只好把它的注册码算法逆向重写一下,做了个生成注册码的工具。这大概就是有时候写Keygen更容易的原因吧。

下面这个是Kuka|PRC,反编译就能看,果然有个全局函数。居然还有RSA加密?目测可以注入函数patch的,和Visual Micro一样。

以上。

其实意味着Rhino/Grasshopper的所有插件应该都能破解的。本文是因为机械臂的插件都是收费版,所以以此为突破口练手。

本文仅供技术交流,HAL和KUKA|PRC的正版我系都是买了的,支持正版从我做起。

 

参考:

Wikipedia-.NET Framework

发表评论

邮箱地址不会被公开。 必填项已用*标注