逆向 x红书 shield
迪丽瓦拉
2025-05-31 18:07:59
0

x红书 shield

版本 7.6.0

charles 抓包 目标字段 shield

在这里插入图片描述

查找调用的so

yang神的 frida_hook_libart

运行 frida -U --pause -f com.xingin.xhs -l hook_art.js
在这里插入图片描述

记录

[NewStringUTF] bytes:XYAAAAAQAAAAEAAABTAAAAUzUWEe0xG1IbD9/c+qCLOlKGmTtFa+lG43EOeuFXTagQk9W2z7Y1Gp2q+rJez8Mj2sR+2fc3RQwbE2eKNbym2Sxh0u1j7GzMl9DV8b5bDqkYIbNd 0xb3986981 libxyass.so!0x73981libxyass.so!0x73981

查找注册函数

运行 frida -U --pause -f com.xingin.xhs -l hook_RegisterNatives.js
在这里插入图片描述

记录

[RegisterNatives] java_class: com.xingin.shield.http.XhsHttpInterceptor name: initializeNative sig: ()V fnPtr: 0xb5594289  fnOffset: 0xb5594289 libshield.so!0x94289  callee: 0xb5510211 libshield.so!0x10211
[RegisterNatives] java_class: com.xingin.shield.http.XhsHttpInterceptor name: intercept sig: (Lokhttp3/Interceptor$Chain;J)Lokhttp3/Response; fnPtr: 0xb55939d9  fnOffset: 0xb55939d9 libshield.so!0x939d9  callee: 0xb5510211 libshield.so!0x10211
[RegisterNatives] java_class: com.xingin.shield.http.XhsHttpInterceptor name: initialize sig: (Ljava/lang/String;)J fnPtr: 0xb55937b1  fnOffset: 0xb55937b1 libshield.so!0x937b1  callee: 0xb5510211 libshield.so!0x10211
[RegisterNatives] java_class: com.xingin.shield.http.XhsHttpInterceptor name: destroy sig: (J)V fnPtr: 0xb5593745  fnOffset: 0xb5593745 libshield.so!0x93745  callee: 0xb5510211 libshield.so!0x10211     initializeNative    fnOffset: 0xb5594289
intercept           fnOffset: 0xb474b465
initialize          fnOffset: 0xb474b279
destroy             fnOffset: 0xb474b225

获取 libxyass.so

libxyass.so 加壳了

yang神的 frida_dump_so

  1. 开启 ./data/local/tmp/frida-server
  2. 运行x红书
  3. 运行 python dump_so.py libxyass.so

在这里插入图片描述

获得 脱壳后的libxyass.so 但是 还是找不到 initializeNative 等函数

向网上大神说的先这样,再那样,可是我就是不行。。。。eom


x红书 shield

版本 6.79.0

查找调用的so

运行 frida -U --pause -f com.xingin.xhs -l hook_art.js记录
[NewStringUTF] bytes:XYAAAAAQAAAAEAAABTAAAAUzUWEe0xG1IbD9/c+qCLOlKGmTtFa+lG43AJdeFURq4Qk9W2z7Y1Gp2q+rJez8Mj2sR+2fc3RQwbE2eKNbym2Sxh0u284QIR/KpIAlrbPG7TIPIl 0xb59929b7 libshield.so!0x109b7libshield.so!0x109b7

查找注册函数

frida -U --pause -f com.xingin.xhs -l hook_RegisterNatives.js记录
[RegisterNatives] java_class: com.xingin.shield.http.XhsHttpInterceptor name: initializeNative sig: ()V fnPtr: 0xb5697289  fnOffset: 0xb5697289 libshield.so!0x94289  callee: 0xb5613211 libshield.so!0x10211
[RegisterNatives] java_class: com.xingin.shield.http.XhsHttpInterceptor name: intercept sig: (Lokhttp3/Interceptor$Chain;J)Lokhttp3/Response; fnPtr: 0xb56969d9  fnOffset: 0xb56969d9 libshield.so!0x939d9  callee: 0xb5613211 libshield.so!0x10211
[RegisterNatives] java_class: com.xingin.shield.http.XhsHttpInterceptor name: initialize sig: (Ljava/lang/String;)J fnPtr: 0xb56967b1  fnOffset: 0xb56967b1 libshield.so!0x937b1  callee: 0xb5613211 libshield.so!0x10211
[RegisterNatives] java_class: com.xingin.shield.http.XhsHttpInterceptor name: destroy sig: (J)V fnPtr: 0xb5696745  fnOffset: 0xb5696745 libshield.so!0x93745  callee: 0xb5613211 libshield.so!0x10211initializeNative fnPtr: 0xb5697289  fnOffset: 0xb5697289 libshield.so!0x94289  callee: 0xb5613211 libshield.so!0x10211
intercept fnPtr: 0xb56969d9  fnOffset: 0xb56969d9 libshield.so!0x939d9  callee: 0xb5613211 libshield.so!0x10211
initialize fnPtr: 0xb56967b1  fnOffset: 0xb56967b1 libshield.so!0x937b1  callee: 0xb5613211 libshield.so!0x10211
destroy fnPtr: 0xb5696745  fnOffset: 0xb5696745 libshield.so!0x93745  callee: 0xb5613211 libshield.so!0x10211

ida

进入 JNI_OnLoad
在这里插入图片描述

进入 sub_1027C
在这里插入图片描述

进入 sub_9342C
在这里插入图片描述

先来分析一下intercept
在这里插入图片描述

进入 sub_939d8 + 1
在这里插入图片描述

进入 sub_40cfc
在这里插入图片描述

进入 sub_40ea8
在这里插入图片描述

frida hook sub_45258

在这里插入图片描述

45258函数的第一个参数的返回值是我们最终的结果,参与计算的是第二个参数v3

function dump(name, addr, legnth) {console.log("======================== " + name + " ============");console.log(hexdump(addr, { length: legnth || 32 }));
}setTimeout(function () {Java.perform(function () {var bptr = Module.findBaseAddress("libshield.so");var ptr_0x45258 = bptr.add(0x45258 + 1);Interceptor.attach(ptr_0x45258, {onEnter: function (args) {this.arg0 = args[0];this.arg2 = args[2];dump("dump 2", args[1], parseInt(args[2]));},onLeave: function (retval) {dump("retval", this.arg0, 200);}})});
}, 100)

查看 sbu_45258

进到45258函数,可以看到很清晰的算法逻辑,先循环后判断,以及byte_A8740的值,可以很容易判断出,这是一个base64
将之前hook到的v3的值做base64,结果与hook到的结果是一致的。

进入 sbu_45258
在这里插入图片描述

进入 byte_a8640
在这里插入图片描述

验证结果
在这里插入图片描述

接下来看一下v3的值是从何而来

回到intercept继续往上看
在这里插入图片描述

进入 sub_406FC
在这里插入图片描述

这里sub_40C74的第三个参数的返回值就是后面传入base64中的值
(少了16位,但是经过不同手机设备不同账号的hook结果,那16位是不变的,所以我就写死了)

进入 sub_40C74
在这里插入图片描述

发现关键函数4A94C,第一个参数是一个很长的值(经过测试,这个值是不变的,换设备和账号也不会变,于是我把它写死。。。)。
第二个参数是一个数(其实就是第三个参数的len),第三个参数是一个拼接的值,里面包含了device_id、build等信息。
第四个参数是用来存储最终结果的。ok进入函数看算法。

没时间弄了,以后有时间再跟

相关内容