本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2024-11(1)

教你使用IL2CppDumper从Unity il2cpp的二进制文件中获取类型、方法、字段等(反编译)

发布于2021-05-11 05:48     阅读(2327)     评论(0)     点赞(1)     收藏(0)


一、前言

点关注不迷路,持续输出Unity干货文章。
嗨,大家好,我是新发。
Unity使用Mono方式打出来的apk,我们可以直接从包内拿到Assembly-CSharp.dll,如果开发者没有对Assembly-CSharp.dll进行加密处理,那么我们可以很方便地使用ILSpy.exe对其进行反编译。
如果使用IL2CPP方式出包,则没有Assembly-CSharp.dll,不过,有一个IL2CppDumper工具,通过它,我们可以逆向得到Assembly-CSharp.dll,下面就教大家如何使用这个IL2CppDumper吧。

二、下载IL2CppDumper

IL2CppDumper是一个开源工具,在GitHub上可以直接下载到。
地址:https://github.com/Perfare/Il2CppDumper
点击右边的Releases下面的版本进行下载即可。
在这里插入图片描述
在这里插入图片描述
下载后解压,文件如下,可以看到Il2CppDumper.exe
在这里插入图片描述

三、Unity Demo工程

为了进行测试,我们创建个Unity Demo工程,创建两个脚本,如下:
在这里插入图片描述
Main.cs脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Main : MonoBehaviour
{
    enum TEST_ENUM
    {
        E1,
        E2,
        E3
    }

    public int test_int = 0;
    protected float test_float = 0.0f;
    private string test_string = "hello world";
    public int[] test_int_array;
    protected List<string> test_string_list;
    private TEST_ENUM test_enum;
    private Hello hello = new Hello();

    private void Awake()
    {
        Init();
    }

    private void Init()
    {
        test_int = 1;
        test_float = 2.0f;
        test_int_array = new int[3] { 4, 5, 6 };
        test_string_list = new List<string>() { "il2cpp", "test" };
        test_enum = TEST_ENUM.E2;
    }

    private void Start()
    {
        hello.SayHello();
        test_string = "Hi, I am linxinfa";
        hello.Say(test_string);

        StartCoroutine(TestCoroutine());
    }

    private IEnumerator TestCoroutine()
    {
        for (int i = 0; i < 100; ++i)
        {
            ++test_int;
            Debug.Log("TestCoroutine, test_int: " + test_int);
            yield return new WaitForSeconds(1);
        }
    }
}

Hello.cs脚本

using UnityEngine;

public class Hello 
{
    public void SayHello()
    {
        Debug.Log("Hello, IL2CPP");
    }

    public void Say(string text)
    {
        Debug.Log(text);
    }
}

四、IL2CPP打包

使用IL2CPP方式,打出apk包。
在这里插入图片描述
打出的apk如下。
在这里插入图片描述

五、拿到libil2cpp.so与global-metadata.dat

test.apk改为test.zip,解压进入目录中,拿到libil2cpp.soglobal-metadata.dat
\lib\armeabi-v7a\libil2cpp.so
\assets\bin\Data\Managed\Metadata\global-metadata.dat
在这里插入图片描述

六、执行Il2CppDumper.exe

回到Il2CppDumper.exe所在的目录,创建input目录和output目录。
在这里插入图片描述
libil2cpp.soglobal-metadata.dat拷贝到input目录中。
在这里插入图片描述
创建一个il2cpp_decompilation.bat文件。
在这里插入图片描述
il2cpp_decompilation.bat文件内容如下:

..\Il2CppDumper.exe libil2cpp.so global-metadata.dat ..\output

双击执行il2cpp_decompilation.bat,如下:
在这里插入图片描述
进入output目录,可以看到生成了如下文件:
在这里插入图片描述

七、查看反编译后的文件

1、dump.cs

这个文件会把C#dll代码的类、方法、字段列出来。比如我们写的Main.csHello.cs

// Namespace: 
public class Hello // TypeDefIndex: 1834
{
	// Methods

	// RVA: 0x46BAC8 Offset: 0x46BAC8 VA: 0x46BAC8
	public void SayHello() { }

	// RVA: 0x46BB4C Offset: 0x46BB4C VA: 0x46BB4C
	public void Say(string text) { }

	// RVA: 0x46BBC8 Offset: 0x46BBC8 VA: 0x46BBC8
	public void .ctor() { }
}

// Namespace: 
public class Main : MonoBehaviour // TypeDefIndex: 1835
{
	// Fields
	public int test_int; // 0xC
	protected float test_float; // 0x10
	private string test_string; // 0x14
	public int[] test_int_array; // 0x18
	protected List<string> test_string_list; // 0x1C
	private Main.TEST_ENUM test_enum; // 0x20
	private Hello hello; // 0x24

	// Methods

	// RVA: 0x46BBD0 Offset: 0x46BBD0 VA: 0x46BBD0
	private void Awake() { }

	// RVA: 0x46BBD4 Offset: 0x46BBD4 VA: 0x46BBD4
	private void Init() { }

	// RVA: 0x46BD44 Offset: 0x46BD44 VA: 0x46BD44
	private void Start() { }

	[IteratorStateMachineAttribute] // RVA: 0x155444 Offset: 0x155444 VA: 0x155444
	// RVA: 0x46BDF0 Offset: 0x46BDF0 VA: 0x46BDF0
	private IEnumerator TestCoroutine() { }

	// RVA: 0x46BE9C Offset: 0x46BE9C VA: 0x46BE9C
	public void .ctor() { }
}

2、il2cpp.h

生成的cpp的头文件,从头文件里我们也可以看到相关的数据结构。

struct Hello_Fields {
};


struct Main_Fields : UnityEngine_MonoBehaviour_Fields {
	int32_t test_int;
	float test_float;
	struct System_String_o* test_string;
	struct System_Int32_array* test_int_array;
	struct System_Collections_Generic_List_string__o* test_string_list;
	int32_t test_enum;
	struct Hello_o* hello;
};

3、script.json

json格式显示类的方法信息:

{
  "Address": 4635336,
  "Name": "Hello$$SayHello",
  "Signature": "void Hello__SayHello (Hello_o* __this, const MethodInfo* method);"
},
{
  "Address": 4635468,
  "Name": "Hello$$Say",
  "Signature": "void Hello__Say (Hello_o* __this, System_String_o* text, const MethodInfo* method);"
},
{
  "Address": 4635592,
  "Name": "Hello$$.ctor",
  "Signature": "void Hello___ctor (Hello_o* __this, const MethodInfo* method);"
},
{
  "Address": 4635600,
  "Name": "Main$$Awake",
  "Signature": "void Main__Awake (Main_o* __this, const MethodInfo* method);"
},
{
  "Address": 4635604,
  "Name": "Main$$Init",
  "Signature": "void Main__Init (Main_o* __this, const MethodInfo* method);"
},
{
  "Address": 4635972,
  "Name": "Main$$Start",
  "Signature": "void Main__Start (Main_o* __this, const MethodInfo* method);"
},
{
  "Address": 4636144,
  "Name": "Main$$TestCoroutine",
  "Signature": "System_Collections_IEnumerator_o* Main__TestCoroutine (Main_o* __this, const MethodInfo* method);"
},
{
  "Address": 4636316,
  "Name": "Main$$.ctor",
  "Signature": "void Main___ctor (Main_o* __this, const MethodInfo* method);"
},

4、stringliteral.json

json的格式显示所有的字符串信息:

 {
    "value": "equal",
    "address": "0x63D158"
  },
  {
    "value": ")V",
    "address": "0x63DED4"
  },
  {
    "value": "Hello, IL2CPP",
    "address": "0x63E668"
  },
  {
    "value": "il2cpp",
    "address": "0x63BB24"
  },
  {
    "value": "test",
    "address": "0x63D0D8"
  },
  {
    "value": "Hi, I am linxinfa",
    "address": "0x63D06C"
  },
  {
    "value": "hello world",
    "address": "0x63D670"
  },
  {
    "value": "TestCoroutine, test_int: ",
    "address": "0x63E0A8"
  },
  {
    "value": "Return type <Byte> for Java method call is obsolete, use return type <SByte> instead",
    "address": "0x63D9E8"
  },
  {
    "value": "JNI: Unknown return type '",
    "address": "0x63DF80"
  },

5、DummyDll/Assembly-CSharp.dll

进入DummyDll目录,可以看到很多dll,其中就有Assembly-CSharp.dll,我们可以使用ILSpy.exe对其进行反编译。
可以看到,与刚刚的dump.cs文件内容是一致的。
在这里插入图片描述
在这里插入图片描述

八、结束语

完毕。
喜欢Unity的同学,不要忘记点击关注,如果有什么Unity相关的技术难题,也欢迎留言或私信~

原文链接:https://blog.csdn.net/linxinfa/article/details/116572369



所属网站分类: 技术文章 > 博客

作者:下班了快跑

链接:http://www.phpheidong.com/blog/article/71193/0d4a4d2824b587c08211/

来源:php黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

1 0
收藏该文
已收藏

评论内容:(最多支持255个字符)