为了给即将结束的学生生涯留下印记,把学校用的所有APP全部分析一边,进行一个记录。这个样本可以作为so层的入门教程进行参考学习。
一、样本基本信息
接口信息:https://*****/330000/v8/circle/feed/list
样本信息:

image.png (153.55 KB, 下载次数: 2)
下载附件
样本名称
2025-9-30 17:15 上传
逆向核心参数:sig

image.png (92.85 KB, 下载次数: 2)
下载附件
接口数据
2025-9-30 17:18 上传

image.png (104.67 KB, 下载次数: 3)
下载附件
指纹信息
2025-9-30 17:18 上传
其中还包括大批量的设备指纹信息,也可以作为一个入门阶段的学习,非常优质的样本
二、逆向思路
1、java层分析
样本app无壳,直接拖入jadx,搜索https://*****/330000/v8/circle/feed/list接口信息(脱敏一下,大佬们抓包可以看到整个接口信息)

image.png (101.79 KB, 下载次数: 3)
下载附件
jadx
2025-9-30 17:21 上传
用的是okhttp框架,继续进去分析

image.png (68.7 KB, 下载次数: 2)
下载附件
入参
2025-9-30 17:22 上传
这里我们可以看到请求接口传入的headers和params参数,我们利用快捷键x查询C0函数引用位置
、

image.png (315.65 KB, 下载次数: 3)
下载附件
c0函数
2025-9-30 17:23 上传
对照入参我们知道,第一个是headers,第二个是params,我们需要处理的核心参数sig就在headers当中。

image.png (306.88 KB, 下载次数: 2)
下载附件
生成位置
2025-9-30 17:25 上传
a10是c0289a.a()产生,直接跟进去看看

image.png (414.57 KB, 下载次数: 3)
下载附件
指纹位置
2025-9-30 17:26 上传
这里有大量的指纹生成,但是不是我们分析的核心,大佬们感兴趣可以试试,非常优质的样本。

image.png (242.48 KB, 下载次数: 3)
下载附件
sig位置
2025-9-30 17:27 上传
这里就找到一个sig的生成位置,跟进去看看,这里我们可以看到第二个参数是null,这里可以作为一个过滤点,方便我们定位需要的入参,以及后续的分析

image.png (290.95 KB, 下载次数: 3)
下载附件
so层加载
2025-9-30 17:30 上传
然后我们就可以找到so文件加载,明显知道是一个so层的加密,先hook一下入参情况
[JavaScript] 纯文本查看 复制代码function hook_socall() { Java.perform(function () {
let a = Java.use("sa.a");
var TreeMap = Java.use('java.util.TreeMap');
a["cscd130065c407"].implementation = function (treeMap, str) {
if (str == null) {
console.log(`a.a is called: treeMap=${treeMap}`);
let result = this["cscd130065c407"](treeMap, str);
console.log(`a.a result=${result}`);
return result;
}
};
});
}
function main() {
hook_socall()
}
setImmediate(main)
// frida -Uf com.sohu.sohuhy -l .\hy_hook.js

image.png (294.51 KB, 下载次数: 3)
下载附件
java层入参
2025-9-30 17:32 上传
从整体来看,第一个treemap是前面存入的一些请求头校验信息,同时也包含了token参数,返回值是一个32位的参数,猜测是md5,可以将参数丢进标准算法中和返回值对比

image.png (89.04 KB, 下载次数: 3)
下载附件
标准算法比较
2025-9-30 17:32 上传
应该是在so层对入参进行了一些处理,我们丢进ida进行so层的逻辑处理
2、so层分析

image.png (30.7 KB, 下载次数: 3)
下载附件
so文件
2025-9-30 17:33 上传
拖入ida进行分析,先在导出函数表确定是动态注册函数还是静态注册函数,搜索java,可以发现是一个静态注册函数

image.png (105.02 KB, 下载次数: 3)
下载附件
静态函数
2025-9-30 17:34 上传
点击跳转到对应的地址

image.png (502.97 KB, 下载次数: 3)
下载附件
汇编界面
2025-9-30 17:34 上传
通过快捷键tab或者f5进入到伪c界面

image.png (305.55 KB, 下载次数: 3)
下载附件
伪c
2025-9-30 17:35 上传
、
修改jni函数入参方便分析,修改后通过f5刷新伪c代码,这样就可以清晰看到jni函数的调用

image.png (311.06 KB, 下载次数: 3)
下载附件
jni函数
2025-9-30 17:36 上传
已经写了一部分的注释,可以参考

image.png (452.19 KB, 下载次数: 3)
下载附件
代码执行逻辑
2025-9-30 17:36 上传
通过代码分析,可以看到这段伪c代码不断对treemap入参进行处理,包括追加,同时判断了一个data参数是否为空,在java层我们可以知道,这里的data很明确是空值,我们就可以确定这个判断的走向

image.png (492.32 KB, 下载次数: 2)
下载附件
代码分析
2025-9-30 17:37 上传
之后持续对reale_str进行追加,同时只有一个地方调用了这个参数入参追加结果,可以怀疑这是一个加密入口,将他改名留一个记录,进入函数查看分析

image.png (420.05 KB, 下载次数: 3)
下载附件
函数入口
2025-9-30 17:38 上传
这里的话可以看到返回值是a1,从a1往上推导,在备注rucan这个函数有唯一的调用,同时也是唯一的函数,进入其中继续分析

image.png (320.03 KB, 下载次数: 2)
下载附件
加密函数
2025-9-30 17:39 上传
这里的话也只有一个函数调用,已经被我改名了,是通过ai分析得到是一个标准的md5算法

image.png (602.98 KB, 下载次数: 3)
下载附件
函数偏移
2025-9-30 17:39 上传
既然这里可能是加密的核心,我们来做一个参数的hook分析,看看情况。找到函数的偏移,6A8CC
[JavaScript] 纯文本查看 复制代码function print_arg(addr){
var module = Process.findRangeByAddress(addr);
if(module != null) return hexdump(addr) + "\n";
return ptr(addr) + "\n";
}
function hook_native_addr(funcPtr, paramsNum){
var module = Process.findModuleByAddress(funcPtr);
Interceptor.attach(funcPtr, {
onEnter: function(args){
this.logs = [];
this.params = [];
this.logs.push("call " + module.name + "!" + ptr(funcPtr).sub(module.base) + "\n");
for(let i = 0; i
我们打印出日志信息

image.png (269.2 KB, 下载次数: 2)
下载附件
日志
2025-9-30 17:42 上传
这里我们发现dump出非常可疑的数据,和我们的入参非常相似,我们修改一下代码,直接打印成字符串形式 [JavaScript] 纯文本查看 复制代码function hook_native_addr(funcPtr, paramsNum) { console.log("hook_native_addr")
var module = Process.findModuleByAddress(funcPtr);
Interceptor.attach(funcPtr, {
onEnter: function (args) {
console.log('so层函数调用====>')
console.log(args[1].readCString())
}, onLeave: function (retval) {
}
});
}
so层函数调用====>
S-CID=011332370515867896192S-PID=932773080366004480S-PPID=1556925024278454272@sohu.comapp_key_vs=6.12.1appid=330000circle_id=799434391037358592count=10exposed_circle_pos_feed_id=exposed_hot_feed_ids=extras=1flyer=1759066923374list_type=2log_user_id=932773080366004480score=-1.759066143423E12stpl=1,2,3,4,7,9,11,12tpl=1,3,24,26,27,29withTop=163a000NqP3011J32
这样我们就得到md5实现的一个加密,同时在java层和so层hook,对比参数
a.a is called: treeMap={S-CID=011332370515867896192, S-PID=932773080366004480, [email protected], app_key_vs=6.12.1, appid=330000, circle_id=799434391037358592, count=10, exposed_circle_pos_feed_id=, exposed_hot_feed_ids=, extras=1, flyer=1759067087855, list_type=2, log_user_id=932773080366004480, score=-1.759063282077E12, stpl=1,2,3,4,7,9,11,12, tpl=1,3,24,26,27,29, withTop=1}
so层函数调用====>
S-CID=011332370515867896192S-PID=932773080366004480S-PPID=1556925024278454272@sohu.comapp_key_vs=6.12.1appid=330000circle_id=799434391037358592count=10exposed_circle_pos_feed_id=exposed_hot_feed_ids=extras=1flyer=1759067087855list_type=2log_user_id=932773080366004480score=-1.759063282077E12stpl=1,2,3,4,7,9,11,12tpl=1,3,24,26,27,29withTop=163a000NqP3011J32
a.a result=e33814fd5ef620fa619b8ea466a6cd0c

image.png (107.46 KB, 下载次数: 2)
下载附件
最后结果
2025-9-30 17:44 上传
这样发现找到了,入参在so层进行了重新处理,愉快的结束了这个简单so层样本的分析
三、总结
一个简单的小案例,没啥总结的。预祝大佬们国庆节快乐{:1_932:}