騰訊hotfix分析
在逆向騰訊某產品時,發現很多方法的前面都有這麼一段程式碼:
if(NotDoVerifyClasses.DO_VERIFY_CLASSES) {
System.out.print(AntiLazyLoad.class);
}
NotDoVerifyClasses和AntiLazyLoad在dex中居然找不到,這勾起我的興趣。先來debug看看,到底是從哪裡載入的這兩個類:
ok,發現是從files下的verify.jar載入的,找到這個jar發編譯一下:
package com.tencent;
public class AntiLazyLoad {
public AntiLazyLoad() {
super();
}
}
package com.tencent;
public class NotDoVerifyClasses {
public static boolean DO_VERIFY_CLASSES;
static {
NotDoVerifyClasses.DO_VERIFY_CLASSES = false;
}
public NotDoVerifyClasses() {
super();
}
}
程式碼很簡單,感覺像是個樁,但這個有什麼用?
從檔案路徑我們知道有hotfix,應該和熱修復有關,深入研究一下。
我們先來看看另外一個問題:在前面的截圖中,我們看到classloader是PathClassLoader,其pathList中居然被增加一個files目錄下的jar,這個是怎麼做到的?一般來說動態載入應該是DexClassLoader才對。
通過搜尋verify.jar,發現了關鍵程式碼:
public static boolean inject(Context ctx, String dexPath, String arg5, String odexPath, String clazzName, boolean arg8) {
boolean v0 = false;
if(dexPath != null && (new File(dexPath).exists())) {
if(DexUtil.isAliyunOs()) {
try {
DexUtil.injectInAliyunOs(ctx, dexPath, arg5, odexPath, clazzName, arg8);
v0 = true;
}
catch(Throwable v0_1) {
PatchLog.e("SystemClassLoaderInjector", "fail to inject", v0_1);
throw v0_1;
}
}
else if(!DexUtil.hasBaseDexClassLoader()) {
try {
DexUtil.injectBelowApiLevel14(ctx, dexPath, arg5, odexPath, clazzName, arg8);
v0 = true;
}
catch(Throwable v0_1) {
PatchLog.e("SystemClassLoaderInjector", "fail to inject", v0_1);
throw v0_1;
}
}
else {
try {
DexUtil.injectAboveEqualApiLevel14(ctx, dexPath, arg5, odexPath, clazzName, arg8);
v0 = true;
}
catch(Throwable v0_1) {
PatchLog.e("SystemClassLoaderInjector", "fail to inject", v0_1);
throw v0_1;
}
}
}
return v0;
}
不同版本做了不同的Classloader注入方案,我是4.4的手機,對應看看injectAboveEqualApiLevel14
:
private static void injectAboveEqualApiLevel14(Context ctx, String dexPath, String libPath, String odexPath, String arg9, boolean arg10) {
ClassLoader oldClassloader = ctx.getClassLoader();
DexClassLoader dexClassLoader = new DexClassLoader(dexPath, odexPath, libPath, ctx.getClassLoader());
Object v2 = DexUtil.combineArray(DexUtil.getDexElements(DexUtil.getPathList(oldClassloader)),
DexUtil.getDexElements(DexUtil.getPathList(dexClassLoader)), arg10);
Object v0_1 = DexUtil.getPathList(oldClassloader);
DexUtil.setField(v0_1, v0_1.getClass(), "dexElements", v2);
if(!TextUtils.isEmpty(((CharSequence)arg9))) {
dexClassLoader.loadClass(arg9);
PatchLog.e("DexUtil", "load clas " + arg9 + " success ");
}
}
原理弄明白了:先通過DexClassLoader載入files下的jar,然後反射獲取其dexElements,然後合併到PathClassLoader的dexElements中,很巧妙的做法,其他注入方案不再詳述。
上述這個過程在Application的attachBaseContext中就完成,即app一執行就會載入。也就是說,加入某個時候更新了files下的verify.jar,在下次啟動app時,修改後的verify.jar程式碼就會被載入。 前面最開始看到有很多方法執行前就呼叫的樁,如果精心去設計NotDoVerifyClasses和AntiLazyLoad的程式碼,在方法體執行前就能被執行,確實可以做到熱修復。
然而,其hotfix目錄下不僅僅是上面的程式碼,上面也沒有講述其是如何從伺服器端拉取熱修復的程式碼的, hotfix下程式碼如下:
程式碼有點多,我耐著性子看完了,截圖中的這一坨程式碼是為了做補丁管理的,其中就包括從服務端去拉取補丁,然後儲存到files下的hotfix目錄。假如服務端返回的補丁名字叫做verify,那麼就會覆蓋verify.jar,我想騰訊他們在推送熱修復補丁時,肯定是推送這樣一個補丁。
我記得阿里之前開源了一個修改自xposed的熱修復框架:dexposed,其利用xposed的hook原理,可以做到hook任何一個java方法,效果也是不錯的,但xposed因為很多適配問題,所以要產品化效果不太好。
騰訊的這種熱修復方案是通過硬編碼方式植入樁,假如植入方式能夠工具化,也是一個不錯的選擇,至少沒有適配問題。
關於上面的熱修復原理,騰訊有官方介紹,發現自己之前有一些理解不到位的地方,原理參考:
https://mp.weixin.qq.com/s?__biz=MzI1MTA1MzM2Nw==&mid=400118620&idx=1&sn=b4fdd5055731290eef12ad0d17f39d4a&scene=1&srcid=1106Imu9ZgwybID13e7y2nEi#wechat_redirect
搜尋了一下熱修復,原來是2015年很火的一個技術(孤陋寡聞了),現在已經有很多成熟的方案,上述的hotfix只是其中之一,想了解更多可以自行去搜尋。
相關文章
- 探究如何給Python程式做hotfixPython
- 手把手教你寫熱修復(HOTFIX)
- 熱更新應用--熱補丁Hotfix學習筆記筆記
- Android Hotfix 新方案——Amigo 原始碼解讀AndroidGo原始碼
- 騰訊電腦管家TAV引擎逆向分析
- Flutter 1.12 最新 hotfix 與 2020 路線計劃Flutter
- [外掛擴充套件]騰訊分析外掛套件
- 熱乎的騰訊資料分析實習生面經
- 微軟稱win10系統將不再支援Hotfix補丁修復程式微軟Win10
- 服務質量分析:騰訊會議&騰訊雲Elasticsearch玩出了怎樣的新操作?Elasticsearch
- Flutter 混合開發實戰問題記錄(五)1.9.1-hotfix 打包aar差異Flutter
- 騰訊雲EMR大資料實時OLAP分析案例解析大資料
- Spitfire騰訊2021sigmod論文分析
- [面試]騰訊資料分析秋招四面經歷面試
- 記一次 騰訊會議 的意外崩潰分析
- 楊列昂:騰訊移動分析與服務架構架構
- 騰訊 IVWEB 團隊:前端識別驗證碼思路分析Web前端
- 騰訊財報:2013年騰訊財報分析師會議全紀錄及要點提煉
- Git開發、釋出、缺陷分離模型概述(支援master/develop/feature/release/hotfix型別分支)Git模型ASTdev型別
- struts2 CVE-2012-0838 S2-007 Remote Code Execution && HotfixREM
- 騰訊效能監控框架Matrix原始碼分析之第一篇框架原始碼
- 騰訊雲 BI 資料分析與視覺化的快速入門指南視覺化
- 【騰訊地圖】騰訊地圖定位解析地圖
- 騰訊2021LIGHT公益創新挑戰賽賽題分析
- 騰訊AI Lab釋出「智慧顯微鏡」,搶先佈局病理分析領域AI
- 騰訊AI Lab研發「智慧顯微鏡」 搶先佈局病理分析領域AI
- 騰訊課堂:2014年K12教育市場分析報告
- 騰訊會議
- 騰訊主機安全(雲鏡)兵器庫:威脅分析的福爾摩斯-Cyber Holmes引擎
- 百度騰訊阿里,看看他們的大資料優劣勢與策略分析阿里大資料
- 騰訊移動分析 MTA 首推視覺化埋點!動態運營是關鍵!視覺化
- 騰訊雲使用筆記一: 騰訊雲重灌記錄筆記
- 騰訊T3團隊整理,騰訊Java校招面試Java面試
- 騰訊重回遊戲時代遊戲
- 騰訊電話面試面試
- 騰訊前端初試前端
- 騰訊UnLua開源
- 騰訊9.6筆試筆試