我的unity3d il2cpp 5里,怎么没有IL2CPP选项

#Unity技术#IL2CPP Internals:测试框架_游戏蛮牛-爱微帮
&& &&& 【Unity技术】IL2CPP Inte…
这是IL2CPP Internals系列的第八篇文章,也是这个系列的最后一篇。这篇文章和之前文章主题会有些不同,不会去讨论IL2CPP在编译时或运行时的相关原理。相反,我们将会简要概述如何开发和测试IL2CPP。测试优先于开发IL2CPP团队具有很强的测试优先意识。很多IL2CPP代码都是使用测试驱动开发(TDD)方案编写的,很少有不经过测试就被合并到 IL2CPP 代码的提交请求。因为IL2CPP有一个有限(虽然相当大)输入集-- ECMA 335规范,所以它的开发流程很符合TDD理念。大部分的测试都在产品代码之前完成,这些测试是为了在代码通过之前检查代码的不足之处。这个流程不但有助于驱动IL2CPP的设计,还可以为项目开发团队提供大量的测试用例可以快速、准确的对几乎所有的 IL2CPP 现有行为进行测试。作为一个开发团队,此测试套件有两个很重要的好处:  1.信心: 有很大信心对 IL2CPP 大多数代码进行重构。如果测试用例通过,不太可能引发代码回退。  2.故障排除: 由于 IL2CPP 代码如期正常执行,bug 通常存在于未实现的代码部分或尚未完成的功能测试。通过不断缩小可能引起既定错误的范围,我们可以更快地纠正 bug。测试统计我们把 IL2CPP 代码运行的各种类型测试用例分成几个不同级别。下面是我们当前已有的每个级别的测试编号(我们之后会讨论每种类型的测试)。单元测试C#: 472C++: 44集成测试C#: 1735IL: 173如果所有这些测试都通过,我们确信可以立即发布IL2CPP。我们维护了一个 IL2CPP的主开发分支,这个分支与unity前驱分支保持进度一致,属于Unity整体的一个部分。这些测试在这个主开发分支上总是绿色的(测试通过)。当测试中断(这确实发生过一次,中断了一会) 时,通常会有人在几分钟内修复。因为我们团队的开发人员经常要从这个主分支Fork个人开发分支,所以,这个主分支需要在任何时候都是绿色(红色表示分支有测试没有通过)。主开发分支和个人分支的build和测试状态都在Katana上维护,Katana是Unity的内部编译管理系统。我们使用NUnit运行所有测试用例,NUnit以以下三种不同方式的一种运行:  Windows: ReSharper  OSX: Xamarin Studio  Windows和 OSX 编译机器上的命令行: 自定义的 Perl 脚本测试类型上面我提到了四种不同的测试类型,但是没有给太多的解释。每一个测试类型的有不同的用途,他们一起工作保证IL2CPP 稳步向前发展。单元测试用于检验一段很小的被测代码或者方法的功能是否正确。他们设置条件、 执行测试,最终判断执行结果是否符合预期。IL2CPP集成测试实际上是在程序集中运行il2cpp.exe,首先将生成的C++代码编译为可执行文件,然后运行。既然我们已经有个不错的IL2CPP参考 (已有Unity使用的Mono版本),这些集成测试也以相同方式集成于Mono(Windows的.Net)。我们的测试运行器然后对转储到标准输出的两个 (或三个) 运行结果进行比较,并报告任何差异。所以 IL2CPP 集成测试没有明确的预期值,或者类似于单元测试的断言存在于测试代码中。C# 单元测试我们写的这些测试是最快的、最底层的。它们用于验证il2cpp.exe的许多执行行为,IL2CPP 的 AOT 编译器功能等。由于 il2cpp.exe 完全用 C# 编写的,我们可以使用快速C#单元测试获取更多周转时间作出改变。所有 C# 单元测试都能在很好的开发机器上几秒内完成。C++单元测试绝大多数的IL2CPP (称为 libil2cpp)运行时代码是用C++写的。对于这部分不是很容易从一个公共 API 访问的代码,我们使用C++单元测试。这种测试用例我们相对很少,因为大部分libil2cpp 的代码行为可以通过我们更大的集成测试套件进行。这些测试需要更多的时间来进行单元测试,因为它们需要运行 il2cpp.exe 本身来设置固定的数据。C# 集成测试IL2CPP 的C# 集成测试套件是最大的也是最全面的测试套件。这些测试用例划分为更小的模块,用于测试验证具体模块,比如:icalls的行为、代码生成、 p/invoke,和通用的行为。套件中的测试代码大多相当短,大约只有5~10行代码。整个套件在大多数机器上执行所需时间为不到一分钟,但是我们可以通过使用不同 IL2CPP 选项来运行测试,例如剥离和代码生成等相关的选项。IL 集成测试这些测试在toolchain方面类似于 C# 集成测试。然而,我们不是用C#来写测试代码,而是使用ILGenerator类来直接创建一个IL汇编。虽然这些测试花费时间会比使用 C# 编写测试多一些,但是他们的灵活性更好。我们经常遇到无效或不是由我们当前 Mono C# 编译器生成的 IL 代码的问题。在这些情况下,我们经常可以使用IL 代码编写一个好的测试用例。这些测试也有利于对像conv.i (和其类似的opcodes) 的opcodes进行全面测试,他们有很多细微变化的清除行为。所有的IL 测试在一分钟内可以完成端到端测试。我们通过许多差异性和不同选项在Katana上运行所有这些测试。源码的Clean pull完成测试实例,我们看到大约需要 20-30 分钟,运行时间取决于build farm的负载。为什么需要这么多集成测试?基于以上那些描述,可能看起来像是我们的IL2CPP的测试金字塔本末倒置了。事实上,end-to-end集成测试 (近金字塔的顶端) 构成了我们的大部分测试。根据 TDD 实践,测试时间超过几秒钟也很困难。我们努力通过允许集成测试套件的各模块独立运行,和通过执行测试套件中生成的C++代码增量building (这也向我们证明了Unity工程的IL2CPP增量building的可能性,很是期待) 来减少时间。然后为单个测试的周转时间是合理的(虽然仍不如我们期望的那样快)。也许重度使用集成测试是个理智的决定。很多 IL2CPP 中的代码看起来和以前有些不同,和我们在2015年1月初次公开发布的差别更大。我们进步了很多,在初始IL2CPP 代码基础上实现细节也改变了许多,但我们仍然有很多几年前编写的原始测试代码。在尝试多个不同层面 (包括甚至验证生成的 c + + 源代码内容)的测试之后, 我们的决定是这些集成测试给了我们最好的运行时测试稳定性比。当改变的 IL2CPP 代码时我们几乎不用修改现有的集成测试。这一事实给了我们巨大的信心,修改代码将导致测试失败问题。它也让我们不用害怕在重构和改进IL2CPP代码。更大的测试除了IL2CPP本身, IL2CPP 代码适合很多Unity测试生态系统。对于添加IL2CPP支持的各个平台,我们都会执行Unity player运行时测试。这些测试建立在包含1000 多个场景的单个Unity项目之上,然后执行每个场景和通过断言验证预期执行行为。我们通常不会因为更改IL2CPP 添加新的测试到此套件中(这些测试通常最终在较低级别)。此套件在我们可能会引入指定平台的IL2CPP进行回归测试。此套件还可以在把IL2CPP 集成到Unity个个平台交叉编译时测试。一个典型的运行时测试套件完成需要约 60-90 分钟,但是我们经常在本地执行单个测试这样要快得多。我们用于IL2CPP最大也最慢的测试就是Unity编辑器集成测试。每个测试实际运行在不同的Unity 编辑器实例。大部分的 IL2CPP 编辑器集成测试重点在一个项目构建一个运行实例,通常包含多种编辑器build设置。我们使用这些测试来验证:复杂编辑器集成、 错误消息报告和项目生成大小 (还有许多其它)。根据所选平台,集成测试套件需要运行几个小时,如果不是很经常的话,通常在晚上执行。这些测试的影响是什么?在Unity,我们的指导原则之一是”解决难题&。在面对程序故障时我喜欢思考有挑战的难题。要解决的困难越难,我需要找到更多故障的解决办法。创建一个高性能、 高度可移植 AOT 编译器和虚拟机能够作为Unity脚本后端是一个难题。不用说,我们之前已经克服了上万个不足。但是还有更多的问题要解决,所以也会有更多的不足需要完善。但通过全面、快速的测试套件从几乎所有这些故障中捕捉有用的信息,我们可以非常快速地迭代产品。对于 IL2CPP 的开发人员,我们的测试套件没有这么多手段验证无bug的代码(虽然它确实捕捉bug),或帮助移植IL2CPP 到多个平台上 (也是如此),而是,它是一个工具,我们可以快速发现故障,然后解决难题,这样我们的用户可以集中精力创建美好的东西。总结我们希望你喜欢IL2CPP内部揭秘系列文章。我们很高兴分享实现细节,并尽力提供调试和性能分析技巧。如果你想了解更多关于IL2CPP设计与实现的其他相关主题,请告诉我们!本文来源:,转载请注明出处~
点击展开全文
悄悄告诉你
更多同类文章
还可知道有多少人阅读过此篇文章哦
阅读原文和更多同类文章
可微信扫描右侧二维码关注后
还可知道有多少人阅读过此篇文章哦
游戏蛮牛 --- 中国最大的手机游戏开发者技术社区!
您的【关注和订阅】是作者不断前行的动力
本站文章来自网友的提交收录,如需删除可进入
删除,或发送邮件到 bang@ 联系我们,
(C)2014&&版权所有&&&|&&&
京ICP备号-2&&&&京公网安备34我的unity 5里,怎么没有IL2CPP选项_百度知道Gad-腾讯游戏开发者平台
IOS平台Unity引擎的IL2CPP机制分析及安全性评估
版权所有,禁止匿名转载;禁止商业使用;禁止个人使用。
该文章来自用户转载
研究背景Iphone5S以上(包括5S以上的机型)的机器中都采用了64位的CPU,苹果为了更好发挥64位CPU运行速度,APP Store发布规定:全新App必须在15年2月1日支持64位CPU,已经上架的游戏必须在15年6月1日更新的时候支持64位,否则不能通过苹果官方的审核。Unity引擎4.6.2之前的版本采用Mono的AOT机制提前将C#代码编译为机器识别的二进制代码,Unity官方为了支持IOS平台下64位的APP游戏,4.6.2之后的版本采用IL2CPP机制编译和处理IOS平台下的游戏。Unity的IL2CPP并不是对整个.NET或者Mono工具进行重新改写,依然支持继续使用Mono的C#编译过程,唯一不同点为:IOS平台的Unity在4.6.2之后的版本不在使用Mono的AOT编译机制,重新实现一套预编译程序,可在预编译将中间层的IL指令转换为C++代码,然后在利用标准的C++编译程序来产生原生二进制文件。IL2CPP同时实现虚拟机,虚拟机负责处理函数之间调度、管理调度所需内存等。本文主要分析如下几个点:Unity引擎 IOS版本中C#代码和转换之后的C++代码对应关系、以三剑豪IOS为例分析其中的C#逻辑函数调用方式和关键信息分析、IL2CPP机制的游戏安全性评估。 实现原理Unity引擎作为目前最为主流的3D游戏开发引擎,游戏平台移植性非常好,Unity引擎4.6.2之后的版本采用了IL2CPP机制支持IOS平台64位游戏编译,针对IL2CPP机制进行深入分析之后有利于评估IOS平台的Unity游戏安全性。一、IOS平台Unity引擎IL2CPP机制生成代码对比Unity引擎提供了支持苹果Mac系统的版本,测试过程中下载了Unity引擎的最新版本(5.1.2f1版本),安装好Mac版的Unity引擎之后便可创建游戏工程。Unity引擎通过File菜单Build&run项可编译IOS版的Unity游戏代码,点击之后会弹出下图所示的框:需要点击PlayerSetting选项设置编译方式和代码框架,对应设置选项内容如下图所示:
上图界面信息中需要重点关注两项设置,首先需要将“Scripting BackEnd”设置为IL2CPP方式,之后需要将“Architecture”设置为Universal(表示同时支持ArmV7和Arm64两种指令集)。设置完之后便可点击Build按钮编译工程,编译成功之后会生成一个XCode工程,以供游戏开发方在Mac平台的XCode工具中编译生成最终的APP文件。Unity引擎采用IL2CPP机制在Mac平台成功编译之后,会生成一个完整的XCode工程,Unity游戏逻辑代码采用C#编写,游戏开发方的C#代码最终会生成在/Classes/Native目录中,对应文件结构如下图所示:Unity会将使用的C#库代码编译为Bulk_Name.cpp的文件,对应截图如下:
同时Unity会生成IL2CPP转换之后的相关结构、初始化、调用等信息,文件名以L2CPP命令,对应截图如下所示:
以上为Unity在Mac平台中针对IOS版本利用IL2CPP机制编译生成C#代码。下面针对Unity的IL2CPP机制,对比并分析C#逻辑代码经过IL2CPP机制生成的CPP文件代码,测试原始的C#代码如下所示:测试代码中C#代码的ActivateTrigger类有一个OnTriggerEnter函数和几个成员变量,对应生成的代码如下:其中C#类的成员变量被定位为结构体成员,类的成员函数被定义为C导出的函数,例如ActivateTrigger::OnTriggerEnter 成员函数被IL2CPP机制编译为ActivateTrigger_OnTriggerEnter_m409函数名,同时增加了两个参数,两个参数为:所属的类结构指针(类似每个类的This指针)、MethodInfo结构体指针,方便函数内部调用类的成员变量。通过以上方法可知Unity所采用的IL2CPP机制实际利用C语言的方式表示C#对象的成员变量和成员函数。其中ActivateTrigger::OnTriggerEnter函数内部调用了DoActivateTrigger函数,由于DoActivateTrigger上层由C#调用,所以该函数在编译编译生成XCode工程时以直接调用方式编入ActivateTrigger_OnTriggerEnter_m409函数代码中。 二、逆向分析IL2CPP机制中C#函数调用方式第一部分以正向的方式分析Unity引擎IL2CPP机制将IL指令转换为CPP的方式及代码结构。该部分以逆向的方式分析Unity3D游戏(三剑豪游戏采用Unity引擎的4.6.2f版本)中所采用的IL2CPP处理机制。<span style='font-family:&微软雅黑&,&sans-serif&;color:#、IL2CPP机制中C#函数调用处理方式三剑豪游戏采用Unity引擎开发,IOS平台中采用Unity的IL2CPP机制支持64系统,其中Android平台依然采用Unity的Mono Jit编译机制。三剑豪游戏中C#函数FDynamicSceneTrigger::OnTriggerEnter对应代码如下图所示:FDynamicSceneTrigger::OnTriggerEnter函数C#代码经过Unity的IL2CPP机制转换并在XCode工程编译之后生成的汇编代码如下所示: _FDynamicSceneTrigger_OnTriggerEnter_m25168为IL2CPP机制转换之后C#函数对应的函数名,_FDynamicSceneTrigger_OnTriggerEnter_m25168函数对应地址为:0x43A824,通过交叉引用发现该函数并无直接调用的函数,交叉引用只有一处,及属于该函数对应的MethodInfo结构,该函数对应的MethodInfo结构如下所示: 其中FDynamicSceneTrigger::OnTriggerEnter函数经过IL2CPP机制转换之后对应生成的MethodInfo变量名为:_FDynamicSceneTrigger_OnTriggerEnter_m25168_MethodInfo,MethodInfo结构中详细记录函数相关所有信息,其中包括C#函数上层调用函数。MethodInfo定义如下所示:通过上图MethodInfo结构可知C#函数方法对应的函数名字,所属类信息,方法对应地址、上层调用等信息,其中几个重要的变量解释如下: Name:为C#函数名; Method:为C#函数代码地址; Declaring_type:为C#函数所属类信息,其中包括类名、命名空间等信息。 Invoker_method:为C#函数对应的上层调用函数地址,Unity的IL2CPP机制按照不同C#函数参数定义了不同的上层C调用函数(其中调用方式为间接调用)。通过_FDynamicSceneTrigger_OnTriggerEnter_m25168_MethodInfo结构可知_FDynamicSceneTrigger_OnTriggerEnter_m25168函数的上层调用RuntimeInvoker_Void_t2689_Object_t(MethodInfo const*, void *, void **),其中对应的间接调用代码如下图所示:上图中R3为MethodInfo 结构变量,R3+4对应C#函数经过编译处理之后的函数代码地址,上层通过间接的方式调用C#函数。其中RuntimeInvoker_Void_t2689_Object_t函数的上层调用也是通过间接方式实现,对应调用接口函数为:il2cpp::vm::Runtime::Invoke(该函数定义为:il2cpp::vm::Runtime::Invoke(MethodInfo const*, void *, void **, Il2CppObject **)),该函数为Unity为实现IL2CPP机制而添加的VM虚拟机,该函数负责调度处理C#函数,其中il2cpp::vm::Runtime::Invoke函数间接调用RuntimeInvoker_Void_t2689_Object_t函数代码如下图所示:其中R6为MethodInfo变量,MethodInfo+0x10偏移对应C#函数的上层调用函数地址,在获取每个C#函数对应的RuntimeInvoker函数之后,便通过间接的方式进行调用。Unity引擎采用的IL2CPP机制为每个C#函数生成上层的RuntimeInvoker间接调用函数,生成的函数规则为:RuntimeInvoker_+函数返回类型+_函数编号_+函数参数信息,通过为每类C#函数生成上层调用函数并填入对应C#函数的MethodInfo结构中,从而实现间接动态动用方式。Unity引擎的IL2CPP机制中VM虚拟机针对C#函数调用方式的调用如下所示:il2cpp::vm::Runtime::Invoke
-& RuntimeInvoker 函数 -& C#函数代码(C#函数经过IL2CPP转换之后的C++代码函数) 三、IOS平台Unity IL2CPP机制安全性分析通过以上两节的分析可了解到Unity引擎采用IL2CPP机制编译代码方式及调度处理C#函数代码方式,分析过程中提到的重点结构为MethodInfo,每个C#函数编译之后会生成MethodInfo结构,该结构中揭露详细的函数信息,包括函数名、参数名、所属类名、函数地址、命名空间等信息。IOS平台Unity引擎采用的IL2CPP为每个C#函数编译生成MethodInfo结构,通过逆向方法可推测出每个C#函数对应的函数名、类型等信息,如下图所示为部分函数名信息:通过函数名交叉引用可确认C#函数名对应MethodInfo结构,通过MethodInfo可获取C#函数所有相关重要信息,包括函数所属类名、函数地址、函数参数等信息。IL2CPP为每个C#函数生成的Methodinfo结构相当于为逆向分析者提供一份Map文件,逆向分析者可根据字符串搜索快速定位到函数地址,从而大大降低了游戏分析难度。通过以上分析得出结论:IOS平台中Unity引擎采用的IL2CPP机制会大大降低游戏逆向的分析难度,给游戏带来较大的安全隐患。 总结以上对IOS平台Unity引擎IL2CPP新机制进行相关分析,其中包括C#的IL指令转换为CPP的代码生成规则、IL2CPP的VM虚拟机针对C#函数的调用方式,同时针对Unity引擎的IL2CPP机制安全性进行分析,最终得出结论为:Unity所采用的IL2CPP机制会大大降低逆向分析的难度,通过搜索关键字便可快速找到函数名和函数地址对应关系,从而分析清楚相关功能处理方式。
分类:(转载)游戏安全圈
登录后参与讨论。点击
请勿发表无意义的内容请勿发表重复内容请勿发表交易类内容禁止发表广告宣传贴请使用文明用语其它
淫秽色情政治倾向人身攻击抄袭剽窃广告刷屏恶意挖坟冒充他人其它}

我要回帖

更多关于 unity il2cpp mono2x 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信