Unity3d 反编译破译游戏 简单示例 (使用ildasm反编译DLL修改然后重新编译DLL)

Unity3d 反编译破解游戏 简单示例 (使用ildasm反编译DLL修改然后重新编译DLL)

因为这几天碰到一个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。

Unity3d 反编译破译游戏 简单示例 (使用ildasm反编译DLL修改然后重新编译DLL)


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

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


Unity生成的DLL存储在

\Library\ScriptAssemblies\Assembly-CSharp.dll

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


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


反编译DLL

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

Unity3d 反编译破译游戏 简单示例 (使用ildasm反编译DLL修改然后重新编译DLL)


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

输入命令:

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

如下图:

Unity3d 反编译破译游戏 简单示例 (使用ildasm反编译DLL修改然后重新编译DLL)


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

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

如下图:

Unity3d 反编译破译游戏 简单示例 (使用ildasm反编译DLL修改然后重新编译DLL)


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

Unity3d 反编译破译游戏 简单示例 (使用ildasm反编译DLL修改然后重新编译DLL)


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() 函数

Unity3d 反编译破译游戏 简单示例 (使用ildasm反编译DLL修改然后重新编译DLL)


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


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

直接修改 。如下图

Unity3d 反编译破译游戏 简单示例 (使用ildasm反编译DLL修改然后重新编译DLL)


重新编译为DLL

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

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

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

Unity3d 反编译破译游戏 简单示例 (使用ildasm反编译DLL修改然后重新编译DLL)


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

Unity3d 反编译破译游戏 简单示例 (使用ildasm反编译DLL修改然后重新编译DLL)


更多关于IL 指令的介绍:

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

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