乐趣区

关于程序员:小红书逆向shield-算法分析研究

加密函数定位

新版的小黄书没有 shield.so 了,先应用 frida hook native 看一下在哪里

yang 神开源的: https://github.com/lasting-ya…
查看日志在 libxyass.so 里,留神这个 so 是加密的,须要先修复

dump libxyass.so
下面的参考文章中应用的是 ida + 动静调试修复,奈何自己太菜鸡只能应用大佬写好的 dump 脚本来修复了

yang 神开源的: https://github.com/lasting-ya…
执行 python3 dump_so.py libxyass.so,修复实现后就能够看到大部分的逻辑了

unidbg
之前龙哥写的脚本复制过去就能用改改 apk so 即可

轻易找个接口验证一下,后果雷同

算法还原
参考龙哥文章: https://blog.csdn.net/qq_3885…
shield 加密算法是 aes + hmac-md5 + rc4 其中 aes + md5 都是魔改的 hmac + rc4 是规范的,咱们一步步跟之前的老版本的算法比拟一下,看看哪里有变动

String traceFile = “”;
PrintStream traceStream = null;
try {

traceStream = new PrintStream(new FileOutputStream(traceFile), true);

} catch (FileNotFoundException e) {

e.printStackTrace();

}
emulator.traceCode(module.base, module.base + module.size).setRedirect(traceStream);
先应用 unidbg trace 所有的指令,保留到文件中

aes 算法
aes 算法是依据 hmac, device_id 进行解密,后果会当做 hmac-md5 的 key。hmac 算法会应用 0x36, 0x5c 先跟 key 进行异或

在 trace log 里间接全局搜寻,0x36 关键词,找到 eor 异或指令

ida 里跳过去,这里的逻辑跟老版本 6.87 的看起来差不多

查看汇编指令,这里的 r2 就是 key 在这里 hook, trace 都是能够的

emulator.traceCode(module.base + 0x2D4A0, module.base + 0x2D4A0).setRedirect(traceStream);
博主这里是 trace 形式

查看 trace log 这里 aes 解密的后果全副 trace 进去

在跟 python 还原的算法比照一下,后果雷同,新版的 aes 算法并没有变动

hmac-md5 算法

同理先去 trace log 里搜寻 md5 算法常量

ida 里跳过去,间接定位到 md5 transform 函数

public void inlineHookMd5Result() {

emulator.getBackend().hook_add_new(new CodeHook() {
    @Override
    public void onAttach(UnHook unHook) { }

    @Override
    public void detach() {}

    @Override
    public void hook(Backend backend, long address, int size, Object user) {if (address == (module.base + 0x2E082)) {Arm32RegisterContext ctx = emulator.getContext();
            long lr = ctx.getLR();

            System.out.println("md5 update a result: 0x" + Long.toHexString(lr));
        }
    }
}, module.base + 0x2E082, module.base + 0x2E082, null);

emulator.getBackend().hook_add_new(new CodeHook() {
    @Override
    public void onAttach(UnHook unHook) { }

    @Override
    public void detach() {}

    @Override
    public void hook(Backend backend, long address, int size, Object user) {if (address == (module.base + 0x2E09C)) {Arm32RegisterContext ctx = emulator.getContext();
            long r2 = ctx.getR2Long();

            System.out.println("md5 update b result: 0x" + Long.toHexString(r2));
        }
    }
}, module.base + 0x2E09C, module.base + 0x2E09C, null);

emulator.getBackend().hook_add_new(new CodeHook() {
    @Override
    public void onAttach(UnHook unHook) { }

    @Override
    public void detach() {}

    @Override
    public void hook(Backend backend, long address, int size, Object user) {if (address == (module.base + 0x2E0A4)) {Arm32RegisterContext ctx = emulator.getContext();
            long r3 = ctx.getR3Long();

            System.out.println("md5 update c result: 0x" + Long.toHexString(r3));
        }
    }
}, module.base + 0x2E0A4, module.base + 0x2E0A4, null);

emulator.getBackend().hook_add_new(new CodeHook() {
    @Override
    public void onAttach(UnHook unHook) { }

    @Override
    public void detach() {}

    @Override
    public void hook(Backend backend, long address, int size, Object user) {if (address == (module.base + 0x2E0AA)) {Arm32RegisterContext ctx = emulator.getContext();
            long r7 = ctx.getR7Long();

            System.out.println("md5 update d result: 0x" + Long.toHexString(r7));
        }
    }
}, module.base + 0x2E0AA, module.base + 0x2E0AA, null);

}
先 hook 最初 abcd 的值

发现 python 的后果跟 unidbg 并不同,看来新版的 md5 算法改了

这里具体是哪里改了,就须要一步步排查了,具体过程就不叙述了,最终排查到是批改了 常数组 T(正弦函数表)

技术交换 ping0206guo

退出移动版