没想到上一篇文章有这么多师傅观看,因此有了这一篇。上一篇讲解了纯静态解决global-metadata.dat的各类问题,并且提到了利用il2cpp_api(未混淆)动态dump CS文件这一方法。也就是下方这个项目。cebK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6b7k6i4u0X3j5i4u0W2i4K6u0r3h3Y4W2Y4K9i4y4C8i4K6u0V1d9h3H3J5b7%4m8H3c8s2g2E0M7r3g2J5所以这一篇就分享一下我解决il2cpp_api混淆的解决方法。通过源码了解Zygisk-Il2CppDumper做了什么,因代码过长,所以后续仍旧截取片段。打开il2cpp_dump.cpp,找到il2cpp_dump函数。我们可以看到几个由il2cpp命名的函数,il2cpp_domain_get il2cpp_domain_get_assemblies il2cpp_assembly_get_image等等。索引il2cpp_domain_get查看它的实现,会来到il2cpp-api-functions.h。会发现整个头文件是一个规范由DO_API宏定义的函数。跳转到DO_API看看它都做了什么。r:返回的类型n:函数的名字p:指针地址通过xdl_sym去获取符号名n的地址并定义成返回类型为r的函数。DO_API宏遍历了所有的API声明,并为每个API解析函数地址。既然如此,我们打开任意一个il2cpp.so来查看一下。
打开导出表,搜索il2cpp_,可以看见大量的函数名。而这些函数有什么作用呢?我们截取dump_method,cs文件中的方法是怎么导出的。所以我们可以知道unity底层就是通过这些api去获取各类class field等。因此我们也可以通过这些api去获取。拿出例子,观看混淆后的样子。
我们去导出表搜索il2cpp字符串没有一个相对应的api函数,函数名被混淆为长度11的乱序字符。1.特征码。2.api的顺序是否规律。3.找到游戏上个未混淆的版本,进行对比。这是作者最先想到,并且尝试的方法,先说第一种。看到以上两个函数,它们仅仅只有ret,除了这两个还有其余许多汇编一摸一样的函数。因此特征码是不行的。第二种api的顺序是否规律。这里作者直接给出答案,大致是规律的。例如,如果你确认某个混淆函数是il2cpp_property_get_name,那么它的下一个混淆函数大概率就是il2cpp_property_get_get_method,以此类推。这个方法的隐患就是如果有变动了,你也不确定,当某个重要api地址错误时,程序会崩溃。第三个方法找到游戏上个未混淆的版本,进行对比。这个方法当版本更新越接近越好用。所以将以上三个方法一起搭配使用,应该是最美味的。不知道你否注意到过这个so呢?任意将这个libunity.so名字丢入ai,说明它的作用。它应该都会给你诸如此类的回答。我们可以特别注意到这两行回答。提供 Unity C# 脚本与底层原生代码之间的桥梁和包含游戏的核心逻辑(特别是使用 IL2CPP 时)。我们任意打开一个未混淆il2cpp_api包的libunity.so,发现导出表也没有跟il2cpp相关的函数啊?那试试字符串呢?
我们赶紧索引字符串,看看谁在调用它们。可以发现所有的il2cpp_api相关的字符串都只索引了这一个函数,并且观察规律,这些api是按照一定顺序进行初始化的。按照这个思路,马萨卡?难道说?赶紧打开混淆的libunity.soohhhhhhhhhh,通过比较我们可以知道GdnPlVZEdxf对应的就是il2cpp_init,接着往下的函数都是一样。众所周知,我是一个懒狗。既然有这么好用的映照函数,当然是赶紧编写一些idapython脚本做一套映射表。1.获取il2cpp_api对照表通过汇编观察规律,字符串不是在ADRL就是ADRP语句上。众所周知,我是一个懒狗,懒狗就要有懒狗的样子!我都发现这个规律了,凭什么还要写脚本?派出AI大将。
一通批评ai后,哐当!我们得到一个ida插件(顺便让它帮忙写了一个ui,不然每次都要点加载脚本,累死哥们了),运行一下DumpIl2cppFuction.py得到了一个按照正确顺序的il2cpp函数表。注意unity的版本不同,这里的函数表也不一样,大家做游戏的时候,可以收集一下各个版本的il2cpp_functions表,其实也没几个版本差距特别大,也就4-5个。顺手再dump一个混淆的表。最后再映射成一个表。怎么将我们的混淆函数名和代码中的函数名映射上呢?你问我?我怎么知道?肯定是继续让ai写啊!后续可以让dump脚本映射成{"il2cpp_init", "EEHqqEpNwom"},的样式。但是我太懒了,连让ai修改一下的动力都没有了...最后在game.h填上你最爱的游戏包名,编译导入手机面具加载模块即可。额...看了一眼上一篇文章,有师傅在底下问我问题,然后我记得我好像扣了几百字回复了,然后就...发现竟然没有发出!!!然后就不管了...一想到要重新扣那么多字就心累~因此,我在这里留一个球球好了,OTYyNTY0ODM5。如果添加第一时间没通过...本人虽然真得很懒,但那一定是在睡觉。还有如果没有帮助到师傅你完成通杀的话...我是个标题党哈哈哈哈最后,临近元旦,祝师傅们一定要多笑,苹果肌尽量不要保持扁平,我知道这很困难!但这是命令!毕竟,搞技术身体最重要!嗯@-@void il2cpp_dump(const char *outDir) {
---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-289623.htm
[原创]解决Il2cppapi混淆,通杀DumpUnityCs文件
212 浏览
9 回复
为你点赞!
火钳刘明
好文
yyds
qword_122F6A0 = sub_2933C8(qword_122FDC0, "il2cpp_init_utf16", 0);
if ( !qword_122F6A0 )
sub_819C78("il2cpp: function il2cpp_init_utf16 not found\n");
v2 = 0;
何必这么麻烦,直接调用这个sub_2933C8不就拿到api了?
if ( !qword_122F6A0 )
sub_819C78("il2cpp: function il2cpp_init_utf16 not found\n");
v2 = 0;
何必这么麻烦,直接调用这个sub_2933C8不就拿到api了?
非常好
过来瞧瞧
学习了
好东西。学习了。