本文最后更新于 2024-07-06,文章内容可能已经过时。

这部分其实主要工作量还是在前端JS解密,实际上也可以说整个log校验的工作百分之八九十都在解密JS上面了。

解密前端JS

同样是先解密前端的JS,调用getBlog获取blog参数,解密后方法如下:

image-20230116223536223

转到Jadx逆向App

方法调用

简单的追一下方法的调用:

image-20230116224503961

调用到最后一个方法突然有点懵,三个参数第一个可以直接确定为京东账号的pin值,但是第二个参数无法确定。直接上frida打印一下吧。

import frida

jscode = """
    Java.perform(function(){
        let BlogUtil = Java.use("com.jd.stat.bot.BlogUtil");
        BlogUtil["getBlog"].implementation = function (str, str2, z) {
            console.log('getBlog is called' + ', ' + 'str: ' + str + ', ' + 'str2: ' + str2 + ', ' + 'z: ' + z);
            let ret = this.getBlog(str, str2, z);
            console.log('getBlog ret value is ' + ret);
            return ret;
        };
    })
"""

process = frida.get_device_manager().add_remote_device("127.0.0.1:38567").attach("京东")
script = process.create_script(jscode)
script.load()
input()

中间的代码也不用自己写,可以直接使用Jadx生成,最终打印出str2参数为:com.miui.home,额,有点意外,居然还记录了打开App的来源,jdkey参数中进程ID也参加了计算...参数来源有点多啊,不过搞定入参就可以继续扒了。

image-20230116225726726

d()方法追踪

image-20230116230005613

d()方法即为初始化静态变量a和静态变量f7050b,向下继续追,就会发现这两个变量最终初始化的值为固定的,所以可以直接继续通过frida打印出来。不过吐槽一下,追到后面居然发现东哥还判断了一下用户是否root,就离谱。

image-20230116230409193

c()方法追踪

image-20230116230811105

这里就是初始化了一下JoyyTokenBean对象,然后后面还调用一个k().c(JSONObject.class)方法,点进去追一下瞅瞅。

image-20230116231150205

这个network关键字一看就是调用网络请求,那么第一个匿名函数return的应该就是请求体,下面的匿名函数进行解密,将JoyyToken解密放入BlogUtil方法。

这里可以直接告诉大家,经过测试,JoyyToken完全不用去获取和解密。实测京东程序员应该也是偷懒了,或者说其实校验也没有这么严。

代码实现

将反编译的代码都拷贝,将入口处的变量完成初始化就可以了。

image-20230116231819626