游戏安全实验室 首页 技术入门 查看内容

 阅读目录

Android平台Unity引擎的Mono JIT机制分析

发布于:2016-7-12 11:44   |    199003次阅读 作者: 管理员    |   原作者: TP   |   来自: 原创

一、分析背景

Unity引擎开发游戏采用了C#语言,Unity采用了Mono的Jit机制实现C#逻辑代码动态编译和执行,Mono属于开源的工程,可通过查看Mono源码了解其中的处理。本文针对Mono的Jit动态编译和执行的机制进行分析,更好的了解Unity引擎在Android平台所采用的处理方式。

 

二、Mono Jit相关处理机制

1、MONO主要框架

Mono针对C#代码编译和执行主要框架涉及函数调用过程如下:

mini/main.c: main()
    mono_main_with_options()
        mono_main() 
            mini_init() 
            mono_assembly_open()
            main_thread_handler() // assembly(也就是bytecode)的编译执行
            mini_cleanup()
            
main_thread_handler()
    mono_jit_exec() 
        mono_assembly_get_image() // 得到image信息,如"test.exe"
        mono_image_get_entry_point() // 得到类,方法信息
        mono_runtime_run_main(method, argc, argv, NULL)
            mono_thread_set_main(mono_thread_current()) // 将当前线程设为主线程
            mono_assembly_set_main()
            mono_runtime_exec_main() // 编译及调用目标方法
            
mono_runtime_exec_main()
    mono_runtime_invoke(method, NULL, pa, exc) // 要调用的方法,如"ClassName::Main()"
        default_mono_runtime_invoke() // 实际上是调用了mono_jit_runtime_invoke()
            info->compiled_method = mono_jit_compile_method_with_opt(method) // 编译目标函数
            info->runtime_invoke = mono_jit_compile_method() // 编译目标函数的runtime wrapper
                mono_jit_compile_method_with_opt(method, default_opt, &ex)
            runtime_invoke = info->runtime_invoke
            runtime_invoke(obj, params, exc, info->compiled_method)  // 调用wrapper,wrapper会调用目标方法
            
mono_jit_compile_method_with_opt() 
    mono_jit_compile_method_inner() 
        mini_method_compile(method, opt, target_domain, TRUE, FALSE, 0) // 通过JIT编译给定方法
        mono_runtime_class_init_full() // 初始化方法所在对象
            method = mono_class_get_cctor() // 得到类的构造函数
            if (do_initialization) // 对象需要初始化
                mono_runtime_invoke() // 调用相应构造函数来构造对象,如"System.console:.cctor()"
                    mono_jit_runtime_invoke()

 

 

 

2编译并执行过程

其中mono_runtime_invoke函数在mono源代码object.c中,而其实际调用的mono_jit_runtime_invoke则在mini.c代码中。查看mini.c代码:

可以看到,在该函数中,会先通过查找列表,看是否已创建对应的info信息,若不存在,则先进行编译得到info信息:

编译完成(或之前已编译相同的info信息)后,则调用info自身的runtime_invoke实现对真正函数的调用。

以上是基于对mono的源代码进行的分析,下面将基于以上的分析设想,对实际的android unity游戏进行逆向推定。

 

 compiled_method即为实际的代码。而根据入口参数method也可获取到compile_method的函数名,通过结构分析可以看到,在整个编译和调用的过程中,结构MonoMethod函数都是相当关键的结构,其结构在class_internal.h定义中:

而在该结构中的name属性,应就是对应的函数名,如:

以上是对一般模式下的mono进行的分析。而实际上,mono还支持动态调用的方式:

在mono_jit_runtime_invoke中,还存在代码:

android unity的编译代码正是支持该功能。

在核心代码中,对真正的c#函数进行了编译与调用:

 、总结

    以上针对Unity引擎采用的Mono Jit动态编辑机制进行详细分析和阐述。Unity采用Mono的C#动态编译处理机制更好的实现了跨平台功能,Mono的Jit将C#代码编译为IL指令,在运行过程中动态编译为机制识别指令,了解整个处理机制便于更好的分析Android平台Unity引擎开发的游戏。


*转载请注明来自游戏安全实验室(GSLAB.QQ.COM)

分享到:
踩1 赞0

收藏

上一篇:IOS平台Unity引擎的IL2CPP机制分析及安全性评估

下一篇:IOS平台Unity3D AOT全局模块结构分析

最新评论
B Color Image Link Quote Code Smilies

发表评论