发布于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
是一个开源工具,在GitHub上可以直接下载到。
地址:https://github.com/Perfare/Il2CppDumper
点击右边的Releases
下面的版本进行下载即可。
下载后解压,文件如下,可以看到Il2CppDumper.exe
。
为了进行测试,我们创建个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
方式,打出apk
包。
打出的apk
如下。
奖test.apk
改为test.zip
,解压进入目录中,拿到libil2cpp.so
与global-metadata.dat
。
\lib\armeabi-v7a\libil2cpp.so
\assets\bin\Data\Managed\Metadata\global-metadata.dat
回到Il2CppDumper.exe
所在的目录,创建input
目录和output
目录。
将libil2cpp.so
与global-metadata.dat
拷贝到input
目录中。
创建一个il2cpp_decompilation.bat
文件。
il2cpp_decompilation.bat
文件内容如下:
..\Il2CppDumper.exe libil2cpp.so global-metadata.dat ..\output
双击执行il2cpp_decompilation.bat
,如下:
进入output
目录,可以看到生成了如下文件:
这个文件会把C#
的dll
代码的类、方法、字段列出来。比如我们写的Main.cs
和Hello.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() { }
}
生成的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;
};
以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);"
},
以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"
},
进入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黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 php黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-4
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!