app edata 参数 so aes 加密分析破解|unidbg

android 逆向 6 / 38

仅供学习研究 。请勿用于非法用途,本人将不承担任何法律责任。

前言

本次主要分析,某品会 app 添加购物车接口的 edata 加密参数
版本 7.45.6 低一点的版本没有这个加密参数

charles 抓包

1-charles-01.png

就是这个 edata 参数

apk 反编译 分析 java

具体流程就不说了,还是比较简单的,反编译出来之后直接全局搜索 edata 即可

2-jeb-01.png

最后会跟踪到 com.vip.vcsp.KeyInfo.esNavnative 函数,在 libkeyinfo.so

ida 分析

3-ida-01.png

打开 ida 之后,到 exports 窗口搜索 java 关键字,就能看到一些静态注册的函数,其中就包括今天主角 esNav,双击点进去

4-ida-02.png

if 判断的 j_Utils_ima 函数应该是判断 apk 签名之类的直接跳过查看主函数 j_Functions_es

5-ida-03.png

函数的前半段看起来是初始化一些常量数据

6-ida-04.png

后面的话就是通过反射获取 java 的标准 aes 算法,最后在 base64 编码

frida hook

先使用 frdai hook 一下 esNav 函数的输入输出是啥,上代码

function main() {
    Java.perform(function () {
        var KeyInfo = Java.use('com.vip.vcsp.KeyInfo');

        KeyInfo.esNav.implementation = function (a, b, c, d, e) {
            console.log('b: ', b);
            console.log('c: ', c);
            console.log('d: ', d);
            console.log('e: ', e);

            var res = this.esNav(a, b, c, d, e);
            console.log('res: ', res);

            return res;
        }

    })
}

setImmediate(main);

执行命令 frida -UF -l script1.js | tee ss1.log,查看 ss1.log 文件

7-frida-01.png

参数 b 应该是请求参数, c d e 写死就行,最后返回了 aes 加密结果
刚开的想法是使用 frida 直接 hook 出,aes key 但是奈何技术有限,hook 出来的结果一直是乱码也不知道咋解决
就准备使用 unidbg 直接执行 so

unidbg

package com.xiayu;

import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.LibraryResolver;
import com.github.unidbg.Module;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.AbstractJni;
import com.github.unidbg.linux.android.dvm.DalvikModule;
import com.github.unidbg.linux.android.dvm.VM;
import com.github.unidbg.memory.Memory;

import java.io.File;
import java.io.IOException;

public class WeiPinHuiAes extends AbstractJni {
    private final AndroidEmulator emulator;
    private final VM vm;

    public String apkPath = "apk 文件路径";
    public String soPath = "libkeyinfo.so 路径";

    private static LibraryResolver createLibraryResolver() {
        return new AndroidResolver(23);
    }

    private static AndroidEmulator createARMEmulator() {
        return AndroidEmulatorBuilder.for32Bit().setProcessName("com.achievo.vipshop").build();
    }

    WeiPinHuiAes() {
        emulator = createARMEmulator();
        final Memory memory = emulator.getMemory();
        memory.setLibraryResolver(createLibraryResolver());

        vm = emulator.createDalvikVM(new File(apkPath));
        vm.setJni(this);
        vm.setVerbose(true);

        DalvikModule dm = vm.loadLibrary(new File(soPath), true);
        Module module = dm.getModule();
        dm.callJNI_OnLoad(emulator);
    }

    private void destroy() throws IOException {
        emulator.close();
        System.out.println("destroy");
    }

    public static void main(String[] args) throws IOException {
        WeiPinHuiAes wph = new WeiPinHuiAes();
        wph.destroy();
    }
}

8-idea-01.png

先把框架搭建起来,执行没问题,成功输出,开始掉用 esNav 函数

9-idea-02.png

添加个调用函数,执行跑起来

10-idea-03.png

这里报了个环境错误,补起来
这里有个建议推荐使用 java 标准的 aes 加密套件,不然后面的问题还是蛮多的,补完继续跑起来

11-idea-04.png

12-idea-05.png

13-idea-06.png

14-idea-07.png

以上补了几个环境之后,就来到了最后一个,这里要注意 doFinal 之后一定要返回,不然后面的结果不对

15-idea-08.png

补完之后,在跑起来,结果就成功出来了,结果博主是测试过的可用,有啥问题可以联系博主一起讨论


想学习 unidbg 的伙伴,可点击加入星球,星主是一位全能的傻宝,每天都会分享各种姿势骚操作

暂无评论
本文作者:
本文链接: https://www.qinless.com/?p=341
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 qinless 的博客!
100

发表评论

返回顶部