Baby unity3D

Baby unity3D

IL2CPP就是将Unity3D等转换为IL中间语言,IL中间语言再转换为CPP,CPP为静态语言,运行效率更高。

assets/bin/Data/Managed/etc/global-metadata.dat

发现文件被加密了,利用Frida脚本根据文件头"AF 1B B1 FA "进行dump但是没有找到

源码解密

用IDA搜索了一下global-metadata.dat查找LoadMetaData没有发现字符串

顺着源码Runtime.cpp找到可疑字符串且发现了metadata字符串定位到了关键加密函数进行解密

import struct
f = open('global-metadata.dat', 'rb')
a = ""
a = f.read()
key = [0xF83DA249, 0x15D12772, 0x40C50697, 0x984E2B6B, 0x14EC5FF8, 0xB2E24927,
       0x3B8F77AE, 0x472474CD, 0x5B0CE524, 0xA17E1A31, 0x6C60852C, 0xD86AD267, 0x832612B7, 0x1CA03645, 0x5515ABC8,
       0xC5FEFF52, 0xFFFFAC00, 0x0FE95CB6, 0x79CF43DD, 0xAA48A3FB, 0xE1D71788, 0x97663D3A, 0xF5CFFEA7, 0xEE617632,
       0x4B11A7EE, 0x040EF0B5, 0x0606FC00, 0xC1530FAE, 0x7A827441, 0xFCE91D44, 0x8C4CC1B1, 0x7294C28D, 0x8D976162,
       0x8315435A, 0x3917A408, 0xAF7F1327, 0xD4BFAED7, 0x80D0ABFC, 0x63923DC3, 0xB0E6B35A, 0xB815088F, 0x9BACF123,
       0xE32411C3, 0xA026100B, 0xBCF2FF58, 0x641C5CFC, 0xC4A2D7DC, 0x99E05DCA, 0x9DC699F7, 0xB76A8621, 0x8E40E03C,
       0x28F3C2D4, 0x40F91223, 0x67A952E0, 0x505F3621, 0xBAF13D33, 0xA75B61CC, 0xAB6AEF54, 0xC4DFB60D, 0xD29D873A,
       0x57A77146, 0x393F86B8, 0x2A734A54, 0x31A56AF6, 0x0C5D9160, 0xAF83A19A, 0x7FC9B41F, 0xD079EF47, 0xE3295281,
       0x5602E3E5, 0xAB915E69, 0x225A1992, 0xA387F6B2, 0x7E981613, 0xFC6CF59A, 0xD34A7378, 0xB608B7D6, 0xA9EB93D9,
       0x26DDB218, 0x65F33F5F, 0xF9314442, 0x5D5C0599, 0xEA72E774, 0x1605A502, 0xEC6CBC9F, 0x7F8A1BD1, 0x4DD8CF07,
       0x2E6D79E0, 0x6990418F, 0xCF77BAD9, 0xD4FE0147, 0xFEF4A3E8, 0x85C45BDE, 0xB58F8E67, 0xA63EB8D7, 0xC69BD19B,
       0xDA442DCA, 0x3C0C1743, 0xE6F39D49, 0x33568804, 0x85EB6320, 0xDA223445, 0x36C4A941, 0xA9185589, 0x71B22D67,
       0xF59A2647, 0x3C8B583E, 0xD7717DED, 0xDF05699C, 0x4378367D, 0x1C459339, 0x85133B7F, 0x49800CE2, 0x3666CA0D,
       0xAF7AB504, 0x4FF5B8F1, 0xC23772E3, 0x3544F31E, 0x0F673A57, 0xF40600E1, 0x7E967417, 0x15A26203, 0x5F2E34CE,
       0x70C7921A, 0xD1C190DF, 0x5BB5DA6B, 0x60979C75, 0x4EA758A4, 0x078FE359, 0x1664639C, 0xAE14E73B, 0x2070FF03]
with open('decrypt', 'wb') as fp:
    n = 0
    while n < len(a):
        num = struct.unpack("<I", a[n:n + 4])[0]
        num = num ^ key[(n + n // 0x84) % 0x84]
        d = struct.pack('I', num)
        fp.write(d)
        n = n + 4

frida hook 解密

程序在运行时,解密完成利用Frida进行Hook

frida -U -l 2.js com.nu1l.crack

function frida_Memory(pattern)
{
Java.perform(function ()
{
    console.log("头部标识:" + pattern);
    var addrArray = Process.enumerateRanges("r--");
    for (var i = 0; i < addrArray.length; i++)
    {
        var addr = addrArray[i];
        Memory.scan(addr.base, addr.size, pattern,
        {
            onMatch: function (address, size)
            {
                console.log('搜索到 ' + pattern + " 地址是:" + address.toString());
                console.log(hexdump(address,
                    {
                        offset: 0,
                        length: 64,
                        header: true,
                        ansi: true
                    }
                    ));
                //0x108,0x10C如果不行,换0x100,0x104
                var DefinitionsOffset = parseInt(address, 16) + 0x108;
                var DefinitionsOffset_size = Memory.readInt(ptr(DefinitionsOffset));

                var DefinitionsCount = parseInt(address, 16) + 0x10C;
                var DefinitionsCount_size = Memory.readInt(ptr(DefinitionsCount));

                //根据两个偏移得出global-metadata大小
                var global_metadata_size = DefinitionsOffset_size + DefinitionsCount_size
                    console.log("大小:", global_metadata_size);
                var file = new File("/data/data/" + get_self_process_name() + "/global-metadata.dat", "wb");
                file.write(Memory.readByteArray(address, global_metadata_size));
                file.flush();
                file.close();
                console.log('导出完毕...');
            },
            onComplete: function ()
            {
                //console.log("搜索完毕")
            }
        }
        );
    }
}
);
}
setImmediate(frida_Memory("AF 1B B1 FA")); //global-metadata.dat头部特征

解密后的用IDA.py去导入函数名称和字符串。。最终AES解密得到flag

可以通过frida来hook参数,记录一下

Java.perform(function(){
    var soAdrr = Module.findBaseAddress("libil2cpp.so");
   
    var ptrAESEncrypt = soAdrr.add(0x518b54);

    Interceptor.attach(ptrAESEncrypt,{
        onEnter: function(args){
            console.log(("enter ptrAESEncrypt args[0]-> " + args[0]));
            console.log(("enter ptrAESEncrypt args[1] text->\n" + hexdump(args[1])));
            console.log(("enter ptrAESEncrypt args[2]-> password\n" + hexdump(args[2],{
                offset: 12,
                length: 12+16 * 2
            })));
            console.log(("enter ptrAESEncrypt args[3]-> iv\n" + hexdump(args[3],{
                offset: 12,
                length: 12+16 * 2
            })));
        },
        onLeave: function(args){
        }
    })
})

riru-il2cppdumper解密

原理

阅读了一下源码,发现其对dlopen函数进行了hook,判断根据调用的dlopen参数是否为il2cpp.so获取其句柄,根据句柄获得版本,使用反射进行dump

gradlew :module:assembleRelease编译riru-il2cppdumper

注意需要设置ndk版本为21.4版本否则会出错Execution failed for task ‘:module:externalNativeBuildRelease’

其次Riru版本要设置为v21.2从网上下了一个

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值