【Android视频号信息获取①】

*在2019年深圳上班的时候 那时候还是个Java 码农 接触了一下 Xposed.时隔多年 忘记差不多了 用frida先来练练手 新公司又让我研究微信视频号获取个人的视频主页标题列表 *

确定微信版本

  • 不同版本微信hook点不一样。

预想实现方式

  • 用Xposed去请求注册一个中转服务 然后脚本请求中转服务
    • 实现:可以所有号都去处理业务 也可以用一部分号去做查询请求
    • 难点:Xp会污染手机环境 微信检测点太多
  • 用单独服务器hook微信去搭建一个中转 然后脚本请求
    • 实现:利用微信其他端(pc) 协议或者hook 专门分部分号去做服务
    • 难点:pc协议是否稳定 pchook 逆向

服务设计思路

服务应该满足 组 端 点 可以用sekiro治理

    组:不同业务 方便拓展 例如以后需要视频号 或者其他等业务 防止污染
    端:不同的客户端处理在某一个组下只处理同一种业务 方便查询管理
    点:针对于端去调用某个函数 例如 以后同一个业务下 不同的函数查询

难点

  • 多进程共享数据 当前解决方案:利用系统广播来传递数据
  • 微信hook位置 整个项目 最最最麻烦的东西 需要不断调试 分析

预想期望

搜索获取用户信息
入参 账号名
返回 类json 或者 protobuf (会有唯一账号id)

获取用户主页视频
入参 账号id
返回 类json 或者 protobuf 主页视频信息 标题 视频id 等等

实战分析

打开视频号主 主页 查询 activity :adb shell dumpsys activity top
com.tencent.mm/.plugin.finder.feed.ui.FinderProfileUI
【Android视频号信息获取①】_第1张图片
但是我并没有找到数据请求的地方 这个应该是有个中转的activity 上面这个 应该就是个显示页
搜索一番发现了Monitor这个工具 可以跟踪执行路径
【Android视频号信息获取①】_第2张图片
利用GDA或者Jadx跟踪到这个类 发现这应该就是一个数据组装的构造函数
【Android视频号信息获取①】_第3张图片
继续网下翻 可以看到 里面还有数据解析方法
【Android视频号信息获取①】_第4张图片
所以这个类 我们可以猜到应该就是数据组包和请求的一个类~ 我们写脚本验证一下

//请求的数据
let NetSceneFinderUserPage = Java.use("com.tencent.mm.plugin.finder.cgi.eg");
NetSceneFinderUserPage["$init"].overload('java.lang.String', 'long', 'com.tencent.mm.cg.b', 'int', 'com.tencent.mm.protocal.protobuf.chn', 'int', 'long', 'boolean', 'java.lang.String', 'long', 'java.lang.Integer', 'java.lang.Long', 'java.lang.String', 'boolean', 'boolean', 'java.lang.Long', 'int', 'kotlin.g.b.k').implementation = function (str, j, c14425b, i, chnVar, i2, j2, z, str2, j3, num, l, str3, z2, z3, l2, i3, c100738k) {
    console.log('$init is called' + ', ' + 'str: ' + str + ', ' + 'j: ' + j + ', ' + 'c14425b: ' + c14425b + ', ' + 'i: ' + i + ', ' + 'chnVar: ' + chnVar + ', ' + 'i2: ' + i2 + ', ' + 'j2: ' + j2 + ', ' + 'z: ' + z + ', ' + 'str2: ' + str2 + ', ' + 'j3: ' + j3 + ', ' + 'num: ' + num + ', ' + 'l: ' + l + ', ' + 'str3: ' + str3 + ', ' + 'z2: ' + z2 + ', ' + 'z3: ' + z3 + ', ' + 'l2: ' + l2 + ', ' + 'i3: ' + i3 + ', ' + 'c100738k: ' + c100738k);
    let ret = this.$new(str, j, c14425b, i, chnVar, i2, j2, z, str2, j3, num, l, str3, z2, z3, l2, i3, c100738k);
    console.log('$init ret value is ' + ret);
    return ret;
};
//响应的数据
let FinderPreloadTransform = Java.use("com.tencent.mm.plugin.finder.preload.g");
FinderPreloadTransform["a"].overload('com.tencent.mm.protocal.protobuf.cgh', 'java.util.List', 'int').implementation = function (cghVar, list, i) {
    console.log('a is called' + ', ' + 'cghVar: ' + cghVar + ', ' + 'list: ' + list + ', ' + 'i: ' + i);
    let ret = this.a(cghVar, list, i);
    console.log('a ret value is ' + ret);
    return ret;
};

【Android视频号信息获取①】_第5张图片

可以看到每次请求确实会走这里 而且第一个参数就是视频号的用户名:v2_060000231003b20faec8c5e********************@finder
解析响应的list里面也会包含标题 id等一堆信息 这样就拿到了我需要的标题 id 等信息了
接下来就去找找怎么执行这个请求

寻找构造函数的交叉引用 有很多
在这里插入图片描述
我们打印一下堆栈 看一下执行流程 (为什么是打印堆栈而不是选择交叉引用 因为这个点浪费了我很多 时间 就是它的类很多都是抽象方法 往上手动跟踪的话 会找到未实现的方法!)
【Android视频号信息获取①】_第6张图片
可以看到我们开始没有定位到的UI界面 继续跟进去
【Android视频号信息获取①】_第7张图片
在onCreate 函数中 他会获取 FinderProfileFeedLoader 对象 继承 BaseFinderFeedLoader
在这里插入图片描述在这里插入图片描述
接下来我的思路就变成了 构造 FinderProfileFeedLoader 对象 然后调用requestRefresh() 方法
【Android视频号信息获取①】_第8张图片
构造方法也很简单 第一个参数是枚举类型 第二个是用户名 第三个是chn对象 后面是boolean
hook输出一下参数打印 如下

【Android视频号信息获取①】_第9张图片

开始构造执行请求

【Android视频号信息获取①】_第10张图片

调用函数 执行刷新 完美~

【Android视频号信息获取①】_第11张图片

后面发现视频多 需要翻页这么执行就不行了 同上继续跟踪

【Android视频号信息获取①】_第12张图片

这么简单 翻页?执行一下就行了

【Android视频号信息获取①】_第13张图片

发现还是第一页 原来是它第二个构造参数变成了 获取视频 id

【Android视频号信息获取①】_第14张图片

可以填充data 或者 自己hook参数 改需要翻页的视频id就行了~ 感兴趣自己研究一下
待续…

你可能感兴趣的:(算法分析,逆向学习,android,微信视频号,Xposed,frida,视频号)