2017-09-23 21:10:22 wuyf88 阅读数 325

一、步骤实现
1、下载反编译工具,目前,我使用的是ILSpy,打开工具,得到如下界面

2、点击File后得到如下界面
这里写图片描述
3、单击 “打开” 按钮,选择Unity3d 安装目录下的dll文件,导入ILSpy中,即可查看所有dll文件内容,截图如下
这里写图片描述

二、效果展示
效果一
这里写图片描述
效果二
这里写图片描述
效果三
这里写图片描述

到这,就可以完全实现unity3d中dll文件的反编译。

2016-06-24 09:37:32 qq_15267341 阅读数 16127
  1. 使用Reflector进行反编译
    Reflector下载地址:http://www.liangchan.net/soft/softdown.asp?softid=6319
    按照压缩包中的破解说明,即可破解
    破解完成后,桌面上如果没有快捷图标,在开始菜单中搜索Reflector,然后将图标拖动到桌面上
    这里写图片描述
    Reflector.FileDisassembler.dll下载地址:http://www.xdowns.com/soft/184/dll/2014/Soft_130597.html

下载完成后,打开Reflector安装软件,Tools-Add-ins…
这里写图片描述
将Reflector.FileDisassembler.dll添加进来
这里写图片描述

此时,你会发现工具菜单最底部出现
这里写图片描述

做完上面的工作,就可以进行反编译工作
这里写图片描述


这里写图片描述


这里写图片描述

这里写图片描述


这里写图片描述


这里写图片描述

接着可以继续反编译!先刷新一下!否则 file disassembler不可用
这里写图片描述

可以选择dll文件,然后整个导出,具体见下图
这里写图片描述


下面讲解另一个反编译工具 ILSpy
软件下载地址:http://www.orsoon.com/Soft/14703.html
下载解压后
这里写图片描述
这里写图片描述

软件左边选择 反编译
这里写图片描述
左边选择反编译的具体目标,软件右窗口就会显示反编译结果,并且可以通过选择 文件-保存代码 可以对整个dll文件进行反编译,还可以对某一部分做代码保存 很是方便
这里写图片描述


两种反编译工具的比较
这里写图片描述

FR:徐海涛(hunk Xu) QQ群:386476712

2017-01-13 11:59:10 jjjjjj123321 阅读数 1302

转载自:http://liweizhaolili.blog.163.com/blog/static/1623074420144313825921/


如果稍微关注过这方面知识的朋友,应该知道Unity3D做出来的项目是非常容易被反编译的,被反编译后你的所有资源和代码都将会毫无遮掩的呈现出来。由于.net本身没什么加密的措施,所以我们一般都是使用混淆代码的方式来对程序进行一定的加密。

接下来2篇博客,阿赵将会简单的讲一下我自己在Unity3D的程序加密做法。首先第一篇,我会简单的说明一下怎样在Unity3D里面使用dll动态链接库,然后第二篇会说明怎样对dll进行混淆。

开始第一篇的内容:
首先,我们需要新建一个类库项目,可以使用Visual Studio或者Monodevelop来做。我这里是使用vs2012来创建:
Unity3D项目程序加密1——在Unity3D里使用自己的dll - 阿赵 - 穷到掉渣的超级奶爸阿赵
 
Unity3D项目程序加密1——在Unity3D里使用自己的dll - 阿赵 - 穷到掉渣的超级奶爸阿赵
选择好项目类型、写好项目名称。
 
新生成的项目里面默认有一个Class1类
Unity3D项目程序加密1——在Unity3D里使用自己的dll - 阿赵 - 穷到掉渣的超级奶爸阿赵
 
可以通过在解决方案资源管理器里面进行重命名改成自己想要的类名,比如我这里改成了Math3D
Unity3D项目程序加密1——在Unity3D里使用自己的dll - 阿赵 - 穷到掉渣的超级奶爸阿赵
 
然后写一个简单的静态方法在里面。这里我写了个最简单的加法(Add)。也可以不写静态方法,写出普通的public方法,用的时候new对象出来调用该方法也可以。这和正常的C#编程没区别。
Unity3D项目程序加密1——在Unity3D里使用自己的dll - 阿赵 - 穷到掉渣的超级奶爸阿赵
 
写好之后,在资源管理器里面选择“生成”,那么在项目的bin/debug 里面就会看到dll文件,比如我这个额项目就是AzhaoDll.dll
Unity3D项目程序加密1——在Unity3D里使用自己的dll - 阿赵 - 穷到掉渣的超级奶爸阿赵
 

接下来在Unity3D里面创建你需要的项目,把刚才的dll文件随便放到项目的Assets文件夹里面。关于这个dll文件的存放位置,网上有些人说是必须放在插件文件夹里面,其实是不需要的,放在任意位置它都能被识别出来。当然,按照良好的项目路径习惯,我们建立一个专门放插件的文件夹来存放dll文件,也是合理的。

然后在Unity3D里面创建一个C#脚本,写一行简单的代码来调用我们刚才写的Math3D.Add方法。
 Unity3D项目程序加密1——在Unity3D里使用自己的dll - 阿赵 - 穷到掉渣的超级奶爸阿赵

这时会发现Math3D类不能识别,我们using AzhaoDll命名空间
Unity3D项目程序加密1——在Unity3D里使用自己的dll - 阿赵 - 穷到掉渣的超级奶爸阿赵

然后在Unity3D里把脚本挂到摄像机上,运行,可以看到打印出正确的结果了,这就证明了dll已经被成功调用了。
 Unity3D项目程序加密1——在Unity3D里使用自己的dll - 阿赵 - 穷到掉渣的超级奶爸阿赵

 回顾刚才我们做的一些小细节,在类库项目的Math3D类里面。我们默认的使用了AzhaoDll命名空间。那么假如我们不使用命名空间,或者使用其他的命名空间行不行?答案是可以的,命名空间可以任意的更改,如果不用命名空间,那么在调用的时候就不需要using,如果使用了其他命名空间,对应的using其命名空间就行了。
以下试试把命名空间删掉:
Unity3D项目程序加密1——在Unity3D里使用自己的dll - 阿赵 - 穷到掉渣的超级奶爸阿赵
 
那么在Unity3D里面调用就直接可以用了:
Unity3D项目程序加密1——在Unity3D里使用自己的dll - 阿赵 - 穷到掉渣的超级奶爸阿赵
 运行的结果也是正常的:
Unity3D项目程序加密1——在Unity3D里使用自己的dll - 阿赵 - 穷到掉渣的超级奶爸阿赵

当然,不太建议不使用命名空间,这样做一个说明,是因为unity3D本身创建的脚本默认没有使用命名空间,只是想说明如果不想麻烦,直接把Unity3D没有命名空间的脚本直接拿来编译也是可以的。

再次回顾细节,刚才我们使用的是原生的C#,假如我们需要在类库项目写调用Unity3D本身功能的方法怎样办呢?
在Unity3D的安装目录Editor\Data\Managed里面,找到UnityEditor.dll和UnityEngine.dll两个文件。 
Unity3D项目程序加密1——在Unity3D里使用自己的dll - 阿赵 - 穷到掉渣的超级奶爸阿赵
 然后在类库项目里面添加引用,把这两个dll添加进来
Unity3D项目程序加密1——在Unity3D里使用自己的dll - 阿赵 - 穷到掉渣的超级奶爸阿赵
 
Unity3D项目程序加密1——在Unity3D里使用自己的dll - 阿赵 - 穷到掉渣的超级奶爸阿赵
 
这时候,我们就可以在类库项目里面using UnityEngine来使用Unity3D的方法了,比如我们这里简单写了个CreateGameObject方法,生成一个名字为“CreateByDll”的gameobject。
Unity3D项目程序加密1——在Unity3D里使用自己的dll - 阿赵 - 穷到掉渣的超级奶爸阿赵
 
 生成dll,放回Unity3D项目里,我们就可以调用这个方法:
Unity3D项目程序加密1——在Unity3D里使用自己的dll - 阿赵 - 穷到掉渣的超级奶爸阿赵
运行,看到这个叫做“CreateByDll”的物体生成出来了。
 Unity3D项目程序加密1——在Unity3D里使用自己的dll - 阿赵 - 穷到掉渣的超级奶爸阿赵
 
通过以上的说明,我们会发现其实生成自己的dll在Unity3D里面用是很简单的事情。我们还可以添加其他自己写好的类进类库项目,然后生成dll来使用。
Unity3D项目程序加密1——在Unity3D里使用自己的dll - 阿赵 - 穷到掉渣的超级奶爸阿赵
 
最后说一下注意事项了。
刚才生成的dll在Unity3D编辑器里面基本上都是能用的,但不一定能通过编译。有可能在编译成exe或者apk等时会报错。
需要注意的是,类库项目使用的.Net Framework版本。我自己的尝试是,使用.Net 4.0以上版本发布的dll,在Unity3D里面会编译不通过。所以我们可以用2.0或者3.0之类的版本来发布。
Unity3D项目程序加密1——在Unity3D里使用自己的dll - 阿赵 - 穷到掉渣的超级奶爸阿赵
 还有一些情况是某些现成的dll动态库是使用完整的.Net2.0来发布的,所以我们在编译的时候有可能需要选择完整的.Net 2.0来发布。
Unity3D项目程序加密1——在Unity3D里使用自己的dll - 阿赵 - 穷到掉渣的超级奶爸阿赵

到了这一步,我们就可以把Unity3D的整个代码文件夹里面所有的脚本剪切到类库项目里面生成dll,然后放回Unity3D项目里面。这样别人就不能直接的编辑我们项目里面的代码了。

不过dll本身是不安全的,别人可以很容易看到里面的内容。下一篇博客我们再说明怎样去给dll做混淆。
2015-09-23 17:55:14 Kaitiren 阅读数 4738

Unity3D-重新编译Mono加密DLL。安卓应用总是让人头疼,游戏遭到破解与反编译是研发的人最不愿意看到的。自己的辛苦劳动成果被人随意窃取与利用,对这些咬牙切齿的痛恨。所以我们需要加强自身的反破解技术力量。不过这世上没有破解不了的东西,道高一尺魔高一丈,我们做的只是让破解更加困难而已。让那些破解的人付出点代价才能得到他们想要的,如果他们觉得代价太高,看不清前面的道路,他们就有可能放弃,然后我们的目的达到了。

游戏本身加密方式有很多,对apk加壳,防止apk二次打包等。对这些android的加密与破解技术看过比较好的文章参考:《Android安全及病毒分析》 ,其中《Android APK加壳技术方案【2】》最为经典。而本篇文章我们主要来说说针对Unity3D的加密。

闲扯就到这里,我们开始说正事:

Unity3D所有客户端的代码都会以dll文件形式存下来,当游戏应用被开启时c#vm(也就是mono的虚拟机)会去加载所有dll,从而开始运行真正的程序画面了。而破解的很大一部分都是通过解压apk后拿到主逻辑dll,对dll进行反编译,然后修改后重新编译,再放入apk重新签名打包。所以我们需要针对dll进行加密,以防止他们反编译dll。

加密一个dll文件非常容易,无论你用什么算法都行,但是在哪解密呢?答案是libmono.so。libmono.so是mono的核心程序,它承载了加载解析dll和虚拟机运行的功能。所以说libmono.so是关键,我们需要修改mono内核程序并重新编译它。

下面将开始mono的编译过程,别看步骤写得简单明了,其实我花了起码一个多星期的思考,尝试,失败,再思考,再尝试,再失败…..总结其中原因一方面也是自己的愚钝的资质,另一方面是unity mono和mono并不一样,unity mono缺少编译文档并且还混合着原mono的编译文档,导致误判了很多:

1.首先不要认为unity mono 与 原生态mono一样。可以编译mono就可以同样步骤编译unity mono。我在这里尝试了很久,使用configure进行编译,尝试使用不同的编译参数,进行编译,最后发现unity mono使用的是ndk-9下的linux-4.8编译器,所有参数都是根据这个编译器所设定的。

2.unity mono 地址:https://github.com/Unity-Technologies/mono 你需要从这里下载unity mono。

3.mono需要autoconf automake libtool pkg-config这些工具。你最好还是去下载安装了。你可以用brew安装。brew install autoconf automake libtool pkg-config。

4.我一开始使用mac x86_64进行编译,折腾了很久然后建了个linux-x86_64虚拟机来编译,然后又折腾了很久,又建了个linux-i386来重新编译mono,因为我一直认为交叉编译需要加些不同的编译参数和变量。在linux-i386首次编译成功后又开始转化到mac上,进行交叉编译也一样成功,最后发现其实是我没找对路子。这路子就是unity 的mono-build-tool:https://github.com/Unity-Technologies/monobuildtools 它已经在unity mono的项目里了,在mono的external/buildscripts下。

5.buildscripts下的build_runtime_android.sh是编译安卓平台的关键。它是unity制作的一个自动编译 mono 流程的脚本。你需要将这个脚本copy到mono根目录下再执行。

6.脚本里写些内容,如果你懒得看,我帮你稍微解释下。它会去检查你当前的ANDROID_NDK_ROOT环境变量是否是指向ndk-9,所以你需要去下ndk-9版本,放到机子上,然后编辑环境变量ANDROID_NDK_ROOT指向它,如果你没有它会通过perl模块lwp-download去下载ndk-9,但是你必须要要有这个perl模块才行,我劝你还是老老实实自己去下吧。ndk版本下载地址参考这里:《android-sdk-ndk-studio-下载列表和构建说明》。如果是linux下编译环境变量设定参考这里:《linux环境变量简介》 。然后呢,它会用git去clone一个编译时用到的库,这个也是unity自己改编过的一个库,地址为:https://github.com/Unity-Technologies/krait-signal-handler ,这个库有个坑说下:perl脚本build.pl头部有个命令是#!/usr/bin/env perl -w,这个在部分机子上并不兼容,如果你有错误停在这里这个文件上,你可以将env去除再尝试手动perl build.pl 运行构建一遍没问题再重新编译,原因参考:http://abloz.com/2011/01/13/why-use-usr-bin-env.html 。最后就先make clean && make distclean 清除前面编译的内容,然后进行预编译configure,参数都在脚本里设置好了,你不需要关心了。预编译后就开始make编译了。

7.执行build_runtime_android.sh后terminal基本都是刷屏的节奏。刷刷刷的编译输出,你根本来不及看清到底做到哪了做了些什么内容。而config.log这个文件记录所有的编译输出,包括哪行错误了,哪行通过了。调试基本也考这个log文件,如果关键部位错误它会停止,然后你就可以针对性的查了。这里提醒一点,编译时它很多地方都是在检测编译器是否正常,因为它要确认编译器对错误的编译内容是否能够检测到,所以很多错误内容只是测试内容-你需要省略掉。

8.如果编译成功,那就恭喜你了。windows下我没有测试过,有可能会增加不少坑,我建议还是用linux或者mac编译吧,因为我搜集资料的时候不少人对windows下编译mono都抱怨不少。那么我们开始迈入下一个坑吧:)

下面介绍加解密DLL部分:

加密算法自己选我不多说了,但我这里要引用一篇同样介绍mono的dll加密的文章,我觉得也写得满不错的,但是文章描述不够详尽。我这篇文章弥补了他的不足,将细节补充得更加细致。你大可以两篇文章加起来参考。http://www.unitymanual.com/home.php?mod=space&uid=7672&do=blog&id=1440 不知道地址是不是原作者的,如果不是我再更换吧。

1.首先找到dll解密入口。mono下/mono/metadata/image.c里mono_image_open_from_data_with_name是关键方法,参数中的data是dll传入的数据。你要做的就是将它解密后传给datac,这个方法程序你必须看下,因为你要了解下解密程序放在哪才合适。

2.大部分dll都会通过mono_image_open_from_data_with_name这个方法进行加载,但不是所有dll,例如mscorlib.dll和System.Core.dll就不会,可能还有其他dll,我并不确定还有哪些。所以你还是得辨别下哪些dll会通过这个方法,这样你才能确定哪个dll可以加密。如何判断data属于哪个dll呢,参数name就是data的路径名,name打印出来后就像:/data/app/com.xx.xx.apk/assets/bin/Data/Managed/xxx.dll 这样。

3.打印调试。你可以使用g_message例如:g_warning(“dll name: %s \n”, name); 其他的打印调试你可以查看源码中的它写的代码。很容易找到,查关键字LOG吧。

4.改完后重新编译mono,找到libmono.so(find . -name libmono.so),完成编译后libmono.so的平台有好几个,你可以根据自己的平台来选。有人拷贝这些mono重新编译过的文件去覆盖了unity编辑器的原来mono文件,这样也可行。但我选择在打包android时再从外部复制libmono.so,这样就可以绕过编译器重新编译后无法读取无加密dll的麻烦,可以少做一层无意义的编辑器状态下的加解密工作。

5.mono解密部分就到这里了。其他部分的关键就是你的加解密程序了,是否能够加密和解密都是ok的并且都是不改变size。你需要的参数有data和data_len,mono_image_open_from_data_with_name方法里面都有。

6.为了安全起见我使用c来编写加密程序,因为我认为c#和c的编译器对于变量内存的存储机制不一样,怕引起不必要的麻烦。

这里要非常感谢一个人,全程都在提供帮助:炽乐@宗树 

转载请注明出处:http://www.luzexi.com

2015-06-20 14:07:19 cp790621656 阅读数 20613

因为这几天碰到一个Unity的Bug,不得不去反编译DLL看看C#代码的生成中间件代码。这也用到了一些反编译以及重新编译DLL的一些知识,意味到Unity是如此的不安全。


首先我们新建一个工程,创建一个脚本,写一句很简单的代码:

using UnityEngine;
using System.Collections;

public class crack1 : MonoBehaviour {

	// Use this for initialization
	void Start () {
		Debug.Log("123");
	}
	
	// Update is called once per frame
	void Update () {
	
	}
}

代码逻辑就是输出一个字符串 "123" ,这次的目的就是修改掉 这个字符串,改成其它的。

好了。先运行一下,让Unity把代码编译成DLL。



很好,输出了代码中的字符串 123 。

然后停掉游戏。我们来修改Unity 生成的DLL。


Unity生成的DLL存储在

\Library\ScriptAssemblies\Assembly-CSharp.dll

打包之后存储在Data/Manager 文件夹。


下面开始反编译&&破解&&重新编译


反编译DLL

在开始菜单找到Visual Studio,然后在子目录找到 开发人员命令提示 ,如下图:


然后切换目录到 Unity 生成的 DLL 文件夹

输入命令:

cd C:\Users\Administrator\Documents\Crack\Library\ScriptAssemblies

如下图:



然后输入以下命令来反编译 DLL 为 il 文件:

ildasm Assembly-CSharp.dll /output:Assembly-CSharp.il

如下图:


然后在我们的文件夹中可以看到生成的 il  文件和 res 文件


OK,下面开始我们的破解步骤


破解

用文本编辑器打开生成的 il 文件 Assembly-CSharp.il

内容如下:

//  Microsoft (R) .NET Framework IL Disassembler.  Version 4.0.30319.33440




// Metadata version: v2.0.50727
.assembly extern UnityEngine
{
  .ver 0:0:0:0
}
.assembly extern mscorlib
{
  .publickeytoken = (7C EC 85 D7 BE A7 79 8E )                         // |.....y.
  .ver 2:0:5:0
}
.assembly 'Assembly-CSharp'
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx
                                                                                                             63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.
  .hash algorithm 0x00008004
  .ver 0:0:0:0
}
.module 'Assembly-CSharp.dll'
// MVID: {7D0848C2-160C-47E9-84F0-C61E5C59B615}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003       // WINDOWS_CUI
.corflags 0x00000001    //  ILONLY
// Image base: 0x00220000


// =============== CLASS MEMBERS DECLARATION ===================

.class public auto ansi beforefieldinit crack1
       extends [UnityEngine]UnityEngine.MonoBehaviour
{
  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    // 代码大小       7 (0x7)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  call       instance void [UnityEngine]UnityEngine.MonoBehaviour::.ctor()
    IL_0006:  ret
  } // end of method crack1::.ctor

  .method private hidebysig instance void 
          Start() cil managed
  {
    // 代码大小       11 (0xb)
    .maxstack  8
    IL_0000:  ldstr      "123"
    IL_0005:  call       void [UnityEngine]UnityEngine.Debug::Log(object)
    IL_000a:  ret
  } // end of method crack1::Start

  .method private hidebysig instance void 
          Update() cil managed
  {
    // 代码大小       1 (0x1)
    .maxstack  8
    IL_0000:  ret
  } // end of method crack1::Update

} // end of class crack1


// =============================================================

// *********** 反汇编完成 ***********************
// 警告: 创建了 Win32 资源文件 Assembly-CSharp.res

如果代码很多而生成的这个 il 文件太大,可以直接搜索 类名 然后再到类里面查找 函数名

我们看到 Start() 函数


il 代码还是具有一定可读性,就算不写上注释大家也能把意思猜的一半,这段代码的 大意就是引用一个字符串,然后调用方法去输出。


那么我们的目的就是修改 代码中指定的字符串 123 ,修改为其它的,这里就修改为 "you have been cracked!"。

直接修改 。如下图


重新编译为DLL

保存下上面的修改,然后继续在 控制台中执行以下命令

ilasm /dll /res:Assembly-CSharp.res Assembly-CSharp.il /out:Assembly-CSharp.dll

编译DLL成功,会覆盖掉原来的 DLL。可以通过DLL的修改时间来判断。


再次运行 游戏,查看输出的Log,发现已经被修改了。


更多关于IL 指令的介绍:

http://blog.csdn.net/huutu/article/details/46573435

http://blog.csdn.net/huutu/article/details/46573417


没有更多推荐了,返回首页