文章旨在学习和记录,若有侵权,请联系删除
本期主要是结合前面所讲的平头哥和sekiro,进行一个实例演示
通过重打包APP的方式注入sekiroRPC框架,分析推荐接口
若不太了解平头哥和sekiro,可移步往期博文介绍
平头哥:https://blog.csdn.net/m0_51159233/article/details/126694304
sekiro:https://blog.csdn.net/m0_51159233/article/details/126770751
使用的app版本是6.87
用jadx打开app,全局搜索链接路径 api/sns/v6/homefeed
,搜索结果如图
从上图框住的部分来看,根据特征可以看出这是 RxJava+Retrofit+okhttp3的网络请求框架
意味着只要找到queryHomeFeed接口的用例,然后进行Hook以及RPC的注入,就能够通过本地rpc来调用这个接口了
右键queryHomeFeed,点击查找用例,只有一个方法调用了,跟进来
可以发现,函数return的这一行就是发起推荐页请求的代码
return ((ExploreService) b.f55128c.a(ExploreService.class)).queryHomeFeed(str10, str11, str12, b, i2, ordinal, format, str13, str14, a, str15, str16, str17, str18, i3);
接下来我们在平头哥框架中实现下这一行代码
先新建一个平头哥项目
指定入口类XhsEntry,然后建立sekiro连接
新建XhsHandler类,接着对上文提到的app发请求的这行代码进行实现
return ((ExploreService) b.f55128c.a(ExploreService.class)).queryHomeFeed(str10, str11, str12, b, i2, ordinal, format, str13, str14, a, str15, str16, str17, str18, i3);
我们来分解一下这行代码
1 ((ExploreService) b
2 .c
3 .a(ExploreService.class))
4 .queryHomeFeed(str, str2, str3, b, i2, ordinal, format, str4, str5, a, str6, str7, str8, str9, i3);
1 实现类 – b
Class<?> retrofitClass = RposedHelpers.findClass("n.d0.m0.b.b", RatelToolKit.hostClassLoader);
2 获取对象 – c
Object retrofitApiManager = RposedHelpers.getStaticObjectField(retrofitClass, "c");
3.1 构造参数 – ExploreService.class
Class<?> exploreServiceClass = RposedHelpers.findClass("com.xingin.matrix.explorefeed.model.ExploreService", RatelToolKit.hostClassLoader);
3.2 调用 – b.c.a(ExploreService.class)
Object exploreService = RposedHelpers.callMethod(retrofitApiManager, "a", exploreServiceClass);
4.1 构造请求参数
接口用到的参数变量大部分都能与所在方法n.d0.j0.l.g.d.a
传进来的参数一致,不过需要处理下对应关系
用平头哥Hook n.d0.j0.l.g.d.a
方法,将参数常量直接拿来使用
需要注意的是,第4和第8这两个参数要进行构造
// arg4 -- String b = h.b();
Class<?> hClass = RposedHelpers.findClass("n.d0.j0.l.j.h", RatelToolKit.hostClassLoader);
String traceId = (String) RposedHelpers.callStaticMethod(hClass, "b");
// arg8 -- int a = e.b().a("config_personalization", 1)
Class<?> eClass = RposedHelpers.findClass("n.d0.y1.y0.e", RatelToolKit.hostClassLoader);
Object e = RposedHelpers.callStaticMethod(eClass, "b");
Integer personalization = (int) RposedHelpers.callMethod(e, "a", "config_personalization", 1);
4.2 调用/发出retrofit请求
Object rxJavaObsevable = RposedHelpers.callMethod(exploreService, "queryHomeFeed",
str, str2, str3, traceId , i2, ordinal, format, str4, str5, personalization, str6, str7, str8, str9, i3
);
注意替换上n.d0.j0.l.g.d.a
方法Hook出的对应参数,以及构造出来的traceId
和 personalization
寻找 RxJava+Retrofit+okhttp3框架的回调方法:
1. 在回调接口处跟进返回的Observable类中
2. 搜索 “abstract” 找到 subscribe 方法
3. 跟进 参数类(具有onNext、onError等方法的类)
上图中的x进去
4. 对类s.a.x
进行动态代理
并且在onNext方法中注入sekiro
// 动态代理 --
Class<?> ObserverClass = RposedHelpers.findClass("s.a.x", RatelToolKit.hostClassLoader);
Object observer = Proxy.newProxyInstance(ObserverClass.getClassLoader(), new Class[]{ObserverClass}, new InvocationHandler() {
private String TAG = "xhsHook";
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getDeclaringClass() != ObserverClass) {
//Object hashcode,toString
return method.invoke(this, args);
}
if (method.getName().equals("onNext")){
// onNext 参数就是返回的响应
sekiroResponse.success(args[0]);
return null;
}
if (method.getName().equals("onError")){
Throwable throwable = (Throwable) args[0];
Log.i(TAG, "error: ", throwable);
sekiroResponse.failed(-1, throwable);
return null;
}
return null;
}
});
5. 调用第2步的 b 方法订阅
RposedHelpers.callMethod(rxJavaObsevable, "b", observer);
回调响应构造完成
./sekiro.bat
至此,数据获取成功。
本文主要分析了平头哥和sekiro结合的一个实例操作
分析了如何使用平头哥和sekiro对 RxJava+Retrofit+okhttp3安卓请求框架进行RPC注入
对于xhs其他接口,如搜索接口,评论接口啥的,只要是使用RxJava+Retrofit+okhttp3请求框架的都可以尝试下这个思路
对平头哥和sekiro不太了解的可以参考下这两篇文章:
平头哥介绍与使用:https://blog.csdn.net/m0_51159233/article/details/126694304
sekiro介绍与使用:https://blog.csdn.net/m0_51159233/article/details/126770751