*在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

但是我并沒有找到資料請求的地方 這個應該是有個中轉的activity 上面這個 應該就是個顯示頁
搜尋一番發現了Monitor這個工具 可以跟蹤執行路徑
利用GDA或者Jadx跟蹤到這個類 發現這應該就是一個資料組裝的構造函數
繼續網下翻 可以看到 裡面還有資料解析方法
是以這個類 我們可以猜到應該就是資料組包和請求的一個類~ 我們寫腳本驗證一下
//請求的資料
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;
};
可以看到每次請求确實會走這裡 而且第一個參數就是視訊号的使用者名:
v2_060000231003b20faec8c5e********************@finder
解析響應的list裡面也會包含标題 id等一堆資訊 這樣就拿到了我需要的标題 id 等資訊了
接下來就去找找怎麼執行這個請求
尋找構造函數的交叉引用 有很多
我們列印一下堆棧 看一下執行流程 (為什麼是列印堆棧而不是選擇交叉引用 因為這個點浪費了我很多 時間 就是它的類很多都是抽象方法 往上手動跟蹤的話 會找到未實作的方法!)
可以看到我們開始沒有定位到的UI界面 繼續跟進去
在onCreate 函數中 他會擷取 FinderProfileFeedLoader 對象 繼承 BaseFinderFeedLoader
接下來我的思路就變成了 構造 FinderProfileFeedLoader 對象 然後調用requestRefresh() 方法
構造方法也很簡單 第一個參數是枚舉類型 第二個是使用者名 第三個是chn對象 後面是boolean
hook輸出一下參數列印 如下
開始構造執行請求
調用函數 執行重新整理 完美~
後面發現視訊多 需要翻頁這麼執行就不行了 同上繼續跟蹤
這麼簡單 翻頁?執行一下就行了
發現還是第一頁 原來是它第二個構造參數變成了 擷取視訊 id
可以填充data 或者 自己hook參數 改需要翻頁的視訊id就行了~ 感興趣自己研究一下
待續…