在之前的研究中,我们接触过多次阿里系算法内容,通常停留在某一点或关键位置的处理方法和策略。此次将探讨闲鱼 App 的 x-sign 生成过程,以及 Native 层的一些关键数据。
unidbg 环境搭建
要想探究 Native 层的奥秘,目前最方便的工具是 Frida 和 unidbg。Frida 倾向于现写现用,而 unidbg 更适合对底层函数进行逆向分析。虽然 XPosed 在 Hook 持久性上有优势,但在 Native 层的灵活调试和算法研究方面存在明显不足。
unidbg 的代码配置较为成熟,这里不再展开说明。
追踪 x-sign 的读写位置
根据生成签名的位置,追踪内存的写入情况。例如以下生成的 x-sign,trace 这块内存的写入记录如下:
azU7Bc002xAAJ1j6L+zCsGD9Ijno51j3Wp3y0dj3WPdbxnL/4W9aBqSdKkp+fh5TrmXZo0wH1f8o/Z+DCO2f8wlDDmdY51j3WOdY91 最后 3 次写入为: // 开始写入 x-sign [23:00:48 332] Memory WRITE at 0x4051e260, data size = 4, data value = 0x37557a61, PC=RX@0x401335d0[libmain.so]0x1335d0, LR=RX@0x40132c68[libmain.so]0x132c68 [23:00:48 332] Memory WRITE at 0x4051e264, data size = 4, data value = 0x30306342, PC=RX@0x401337e8[libmain.so]0x1337e8, LR=RX@0x40132c68[libmain.so]0x132c68 [23:00:48 332] Memory WRITE at 0x4051e268, data size = 4, data value = 0x41417832, PC=RX@0x401337e8[libmain.so]0x1337e8, LR=RX@0x40132c68[libmain.so]0x132c68 0x37557a61 小端序字符即为:azU7 0x30306342 小端序字符即为:Bc00 0x41417832 小端序字符即为:2xAA
查看当前函数,发现是最终的 JNI 函数 (*env)->NewStringUTF。
修改参数类型后,可以更清楚地看出该函数的作用。
方法正确但效率较低。如果能大胆猜测算法中使用的函数(如 MD5),可以通过关键信息、魔数等查找关键位置,过滤无用数据,多试几次即可定位到真正的函数位置。
使用 unidbg trace 工具
unidbg 对于静态逆向跟踪最友好的工具是 trace。它包含三个主要功能:
- traceCode:记录特定位置的机器码及寄存器信息,便于静态阅读。
- traceRead:记录特定位置内存的读取,包括函数位置、地址和内容。
- traceWrite:记录写内存的操作。
配合 setRedirect 方法保存记录到本地,可极大提高逆向效率。
关键位置 Debugger Hook
追踪到关键函数位置后,可以使用 Debugger 来 Hook 并查看入参内容。
attach.addBreakPoint(breakPoint, new BreakPointCallback() {
@Override
public boolean onHit(Emulator<?> emulator, long l) {
count++;
logger.debug("Hit 0x{} - {} 次", Long.toHexString(point), count);
RegisterContext context = emulator.getContext();
int intByRegR0 = context.getIntByReg(Arm_const.ARM_REG_R0);
int intByRegR1 = context.getIntByReg(Arm_const.ARM_REG_R1);
int intByRegR2 = context.getIntByReg(Arm_const.ARM_REG_R2);
...
}
});
获取到 x-sign 的入参(如前面某个函数 16 字节的结果 + 41 个字节的 byte 拼接)后,可以编写代码获取关键位置的字符拼接:
byte[] bytes = UnidbgPointer.pointer(emulator, intByReg).getByteArray(0, 112);
Inspector.inspect(bytes, "x-sign");
经过长时间的学习,将关键函数全部摸清后,核心逻辑已清晰可见。

