Android逆向-分析只因光视频加载动画

查看 144|回复 10
作者:debug_cat   
typora-copy-images-to: ./images
背景
同事需要这个动画,我就静悄悄的帮他写一个,打开极光,打卡一个视频,获取极光的视频加载动画,查看如何实现。就是这个金黄色的动画。


screen_cap_20230228_144408.png (180.29 KB, 下载次数: 0)
下载附件
2023-2-28 16:10 上传

定位控件
通过AS的Layout Inspector选择极光的进程(需要root的设备),等待一段时间就可以把页面的布局dump出来。


Xnip2023-02-03_14-11-52.png (1.1 MB, 下载次数: 0)
下载附件
2023-2-28 16:10 上传

这个抓取的过程有点麻烦,需要刚好加载中的时候抓比较好定位,可以通过自己开一个360WiFi限制网速来模拟,网络太好可能就看不到了。但是看是看不到了,布局中肯定还是存在这个view的组件,就是不方便定位,同样ddms的页面dump也可以。
通过分析可以得到,这个动画组件的对象是Lottie,着就好办了。
如果你不是做开发的,甚至做开发的可能都没听过这个东西。

https://github.com/airbnb/lottie-android,Lottie is a mobile library for Android and iOS that parses Adobe After Effects animations exported as json with Bodymovin and renders them natively on mobile!

从ae,pr这种软件做出啦的特效这个库可以加载,导出来的产物就是图片,json字符串(特效)。
学习Lottie的使用
想拿到这个动画,或者我们想把它扣出来,先学习Lottie是怎么在Android上使用的。
这是使用文档:http://airbnb.io/lottie/#/android
文档中重要的部分是:
特效文件的存在位置可以是。
Lottie can load animations from:
  • A json animation in src/main/res/raw.
  • A json file in src/main/assets.
  • A zip file in src/main/assets. See images docs for more info.
  • A dotLottie file in src/main/assets.
  • A url to a json or zip file.
  • A json string. The source can be from anything including your own network stack.
  • An InputStream to either a json file or a zip file.

    项目导入Lottie之后,在页面中增加组件即可:
    这里可以配置特效对应的文件,就是这么简单?
    也可以通过animationView.setAnimation方法动态设置特效json文件,animationView.playAnimation主动开启动画。
    分析动画的加载和定位资源
    知道这些之后,这个组件的用法也有了,反过来猜测,组件源头应该是一个
      public void setAnimation(final String assetName) {
        this.animationName = assetName;
        animationResId = 0;
        setCompositionTask(fromAssets(assetName));
      }
    字符串!直接hook它拿到字符串,再写个demo要验证。
    var com_airbnb_lottie_LottieAnimationView_clz =
        Java.use('com.airbnb.lottie.LottieAnimationView');
    // hook设置特效json
    var com_airbnb_lottie_LottieAnimationView_clz_method_setAnimation_0996 = com_airbnb_lottie_LottieAnimationView_clz.setAnimation.overload('java.lang.String');
        com_airbnb_lottie_LottieAnimationView_clz_method_setAnimation_0996.implementation = function(v0) {
            var executor = this.hashCode();
            var beatText = 'public void com.airbnb.lottie.LottieAnimationView.setAnimation(java.lang.String)';
            var beat = newMethodBeat(beatText, executor);
            console.log("设置动画json:" + v0);
            com_airbnb_lottie_LottieAnimationView_clz_method_setAnimation_0996.call(this, v0);
            printBeat(beat);
    };
    // hook启动动画
    var com_airbnb_lottie_LottieAnimationView_clz_method_playAnimation_1116 = com_airbnb_lottie_LottieAnimationView_clz.playAnimation.overload();
    com_airbnb_lottie_LottieAnimationView_clz_method_playAnimation_1116.implementation = function() {
            var executor = this.hashCode();
            var beatText = 'public void com.airbnb.lottie.LottieAnimationView.playAnimation()';
            var beat = newMethodBeat(beatText, executor);
            com_airbnb_lottie_LottieAnimationView_clz_method_playAnimation_1116.call(this);
            printBeat(beat);
    };
    通过hook发现有多个调用,但是没有关系,丢进demo里面去跑一跑看看效果。
    其中有一个是这样的。


    Xnip2023-02-28_15-14-41.png (9.91 KB, 下载次数: 0)
    下载附件
    2023-2-28 16:10 上传

    是一个彩色的,但是不是金色的,还送了个彩蛋~~~~(经过分析猜测是vip才显示这个动画)
    通过上面hook时候打印的堆栈信息,很快就定位到启动位置:


    Xnip2023-02-03_16-06-54.png (406.24 KB, 下载次数: 0)
    下载附件
    2023-2-28 16:10 上传

    启动动画前设置了一个资源文件夹setImageAssetsFolder("lottieAni/"),这个文件可以在assets目录中找到。
    查看图片居然发现了这个:


    Xnip2023-02-28_15-23-23.png (49.22 KB, 下载次数: 0)
    下载附件
    2023-2-28 16:10 上传

    离开答案又近了一点。
    继续回到代码,设置的不是string类型的特效,是一个setComposition(lottieCompsition),上面刚好也有一个getComposition的方法,进去看看具体实现:


    Xnip2023-02-03_16-06-49.png (422.13 KB, 下载次数: 0)
    下载附件
    2023-2-28 16:10 上传

    从方法实现来看,如果没有缓存,就从fromRawFile中加载出来。开发的小伙伴知道答案在哪里了。
    开发知识:我们放资源文件到App中,如果你丢进去的目录是assets或者raw目录,会原封不动的复制进去,不会修改,通常都是放assets目录,但是在使用的时候不能通过语法糖R.xx获取,如果你存放在raw目录可以通过R.raw.xx获取到资源引用。这里的操作就是从raw下取资源。把raw目录下的资源一个个加载,最后发现mediaplayer_loading_vip_layout.json是我们需要的特效。文件的命名也可以猜出是播放器的资源。


    Xnip2023-02-28_15-33-47.png (9.55 KB, 下载次数: 0)
    下载附件
    2023-2-28 16:10 上传

    demo加载的代码也比较简单。
    LottieAnimationView animationView = (LottieAnimationView) findViewById(R.id.animation_view);
    animationView.setAnimation("lottieAni/mediaplayer_loading_vip_layout.json");
    animationView.setImageAssetsFolder("lottieAni/");
    animationView.loop(true);
    animationView.playAnimation();
    代码也不多,给出结构和代码预览:


    Xnip2023-02-28_16-15-25.png (542.81 KB, 下载次数: 0)
    下载附件
    2023-2-28 16:19 上传

    样本地址:https://wwsk.lanzouy.com/iZVI60otn6pi
    总结
    我们需要的设备和熟悉的技能。
    准备好设备root的手机,debuggable = 1。
    布局dump进行分析。
    熟悉Android的各种主流开发组件。
    反编译定位和hook调试,代码分析。

    下载次数, 动画

  • debug_cat
    OP
      


    peiwithhao 发表于 2023-3-3 08:51
    只因(警觉)

    小鸡子哦
    Rolanju   

    支持支持支持
    goda   

    感谢分析
    clovert   

    看看再说、、、、、、、、、、
    YongerCTO   

    666 学习了
    空欢   

    学到了 牛蛙牛蛙
    svip6868   

    这思路挺棒,学习了
    xixicoco   

    厉害了,逆向工程真的好帅
    a3322a   

    不错的额,分析的很到位
    您需要登录后才可以回帖 登录 | 立即注册

    返回顶部