逆向WeChat (二)

 本篇在博客園的地址https://www.cnblogs.com/bbqzsl/p/18187099

回顧一下現時網上的資源。

原生 https://github.com/duilib,

Ultimate https://github.com/qdtroy/DuiLib_Ultimate

騰訊 https://github.com/tencentyun/TIMSDK/tree/master/cross-platform/Windows/IMApp/Basic/duilib

網易 https://github.com/netease-im/NIM_Duilib_Framework/tree/master/duilib

主體框架2019年截止。

騰訊cross-platform/Windows/IMApp/Basic/duilib止於2019年開放的5.4.666版的TIMSDK。只能通過tag切換舊舊舊版。

最後一個開放的5.6.12版在路徑Windows/Demo/Basic/duilib,時間止於2021年8月31日。

網易開源版也止於2019年。

比較了一下,網易版對原生 改動很大,去除了CDuiString,全部用std::wstring。騰訊在TIMSDK的版本是基於DuiLib_Ultimate而不是原生的duilib。根據我逆向的CControlUI結構,現在WeChat使用的duilib是基於原生版的。DuiLib_Ultimate與原生兩個版區別的最大特徵在於,CControlUI結構使用了5個EventSource還是7個EventSource。

通過WeChat的日誌跟蹤路徑,WeChat不與其它產品共享代碼,他們有一個專門子項目WeUIEngine,而非TIMSDK。架構應該可以參考網易的NIM_Duilib_Framework框架。注意是框架設計不是代碼。

WeChat版的duilib,改動CControlUI成一個大而累贅的龐物,從CContainerUI的RTTI信息可以看到,CControlUI是一個2816字節的大基類。CDuiString的確是一個累贅,尤其Unicode下,大小是132字節。而且這個基類一共使用了17個CDuiString。大廠的我不懂。後面的繼承類如CLabelUI就更加趨向於使用std::wstring。反正現在的電腦沒有16GB內存都不算電腦。

 

經過逆向後就可以對UI進行操作了。

 

 

WeChat使用了Chromium::base的MessagePumpForUI,簡單來說就相當於用win32有窗口消息實現仿如iOS的dispatcher, 如我們熟悉的這個調用dispatch_async(dispatch_get_main_queue(), ^{ // update UI })。Chromium這項目,每個版本系列的代碼都不同程序的重構,所以可以通過一些類來確認出WeChat所使用的版本是6系列的。也可以推斷出WeUIEngine開發的年份。現在這年,Chromium或cef的多線程任務框架也應該是用到爛大街的了吧。

有這個東西,就等於方便我使用,於是我就不客氣使用它向UI主線程投遞代碼執行。進行測試,運行MessageBox顯示當前線程的ID。所以我已經先逆向了需要的東西。下面演示一下。

it works。消息框在主線程376中執行了。

那麼WeChat是怎麼用它的呢,我原本以爲WeChat會用它大作爲一下,我的意思是有多一點用途,沒想到卻只是爲了完成一個單一的UI功能,動畫,或者說是動畫的計時器。

先來找出dispatch任務的地方,只要跟蹤這裏,就可是知道WeChat都向這裏Post了些什麼代碼。無它,將DebugBreak作爲任務PostTask到MessagePumpForUI。通過調用棧就可以找出來了。再通過逆向分析出綁定的執行地址。

綁定的執行地址是base::RepeatingTimer,全部都只有定時任務。下面再來逆向分析都是些什麼定時任務。我也想知道刷新掃碼,工作線程有沒有使用MessagePumpForUI將請求結果更新到UI。

定時器任務只有一個, 就是CPaintManagerUI::DelayPaint,名字是我起的,功能就是Paint,目的是動畫,還有增加或減少Paint的頻度。即使我刷新了幾次重新掃碼,也沒有收到別的任務。也就是工作線程沒有通過Chromium::base的任務框架進行dispatch_async(ui_update)。

今期先到這裏。

我還有逆向通達信系列

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章