逆向WeChat(八)

bbqz007發表於2024-11-28

上一篇逆向WeChat(七)是逆向微信客戶端本地資料庫相關事宜。

本篇逆向微信客戶端本地日誌xlog相關的事宜。

本篇在部落格園地址https://www.cnblogs.com/bbqzsl/p/18459562

現在開始本篇。

如果問AI, "微信xlog檔案開啟方法"。(提問AI的時間在較早的時候,下面的回答不代表最新的回答。)

百度AI:

Gemini:

gpt3.5:

騰訊混元 g3.5

百度AI 跟 Gemini 出現幻覺一本正經,它們還好像停留在搜尋引擎爬網頁的階段。哦,它們本業就是搜尋引擎。它們被https://m.300.cn/itzspd/634130.html這編2021-0523的舊POST汙染了。這編POST也是一本正經說微信的xlog檔案是語音聊天記錄檔案。騰訊混元也是一本正經胡說八道,它自家的東西還不比誰都清楚,也不抖一點出來。對比後,這就側面證明了AI能有多聰明,視乎你都教了它些什麼,或者讓它學了什麼。填鴨式的井蛙式的AI會更聰明。(題外一下,gpt也有掉鏈子的時候。我在寫(五),(六)的時候,問gpt,“微信的WMPF使用chromium哪些程式碼編譯”。gpt三申五令chromium是google瀏覽器開源專案,並且強調WMPF是微信團隊獨立研發的小程式框架,不是瀏覽器,兩者獨立毫無關係,小程式框架不存在使用chromium程式碼。我然後重複4次,”微信WMPF是不是使用了chromium程式碼“之類變換問法,gpt給我相同的回答三申五令並且強調微信團隊獨立研發,最後還發起脾氣罷答。那時候openai的確公告過出現罷答的bug。我最後問”我逆向過WMPF,它的確使用了chrominum程式碼編譯“。gpt才變了回答,微信的WMPF可能使用了chrominum某些技術,縱然這樣WMPF也是微信團隊獨立研發的。我去,它是你Ex嗎?)。

百度AI更多地爬特定地區的新網頁,爬到了有人發現mars的github有一未合併的分支,有人上傳了decode_mars_nocrpyt_log_file.py等解碼程式碼這一訊息。但它並不知道xlog是加密的。Gemini爬不到這特定地區的網頁,漏過了這一訊息。只有gpt最不靠譜。

gpt還提出了兩點建議,逆向破解加密跟找明文輸出。我是一翻逆向分析驗證後,做好了演示材料,定了稿的大綱,才問AI,沒想到gpt將我做的都說了。

本篇主要內容就是逆向破解加密找明文輸出

首先來看逆向破解加密。

對於第一點,也不浪費大家時間,這是基本不可能的。xlog使用Elliptic Curve Cryptography進行加密。gen_key(srv_pub, client_priv) == gen_key(client_pub, srv_priv)。每次xlog初始化,會隨機生成client_pub跟client_priv,在gen_key(srv_pub, client_priv)產生金鑰後,丟棄client_priv。這樣每次啟動微信,日誌的金鑰都不相同。每段加密內容都會附加上client_pub,只有用srv_priv才能產生出正確的金鑰。除非你能夠將每次丟棄的client_priv跟client_pub一同儲存起來。透過加密段內容的附帶的client_pub,找回client_priv,並使用srv_pub就可以產生金鑰了。

下圖演示,使用wechatwin.dll!xlog方法uECC_make_key()生成兩組ECC金鑰對。uECC_shared_secret()分別對交換公鑰後金鑰pair,生成出相同的加密金鑰ECDH_KEY。

正因為這樣,微信開發團隊才可以無忌憚地大寫特寫日誌,簡直如同寫除錯資訊一樣,方便它們搞除錯,搞不好你的一天的日誌檔案就會有幾百個M。微信還有setDebugHost功能,還有除錯伺服器。猜想一下,伺服器需要向客戶端進行命令互動,這是十分簡單的事,比如列出日誌,上傳日誌。日誌基本上只能它們用srv_priv進行檢視。日誌裡幾乎都是流水帳的除錯資訊。不單是錯誤除錯。

(再題外一下,微信在後臺耗資源。主程式是可以透過主介面設定停止更新,但是其它子服務就不適用這個設定。WMPF是作為子服務的,我們無法阻止它在後臺下載更新。現在的WMPF有500MB,而且更新得賊頻繁。並且下載後,它會使得主程式突然耗盡你所有的CPU,強迫你重新啟動微信讓它可以順利載入最新的WMPF。如果不想重開,刪除它最新下載解壓後的WMPF,主程式會停止耗CPU。但是它依然會鍥而不捨在後臺偷偷下載。 我原本借用手機電話卡的流量,查一查網頁,掛一下微信。沒想到一個下午跟夜晚,手機突然欠費停機。後來一查,我的套餐流量被全部耗盡還刷套餐外流量刷了三十塊。套餐外流量1MB-0.3元。我才想起,我刪了幾次它反覆下載的WMPF,流量被它狂耗。要不是我的話費不多,還要冤。可能這三十塊,對於大廠里人均幾十k(加上年終各種福利隨便就double,triple)的大卡大佬大神仙人們來說,連一個工作午餐的最低餐費標準都算不上,可能還不及下班後打個車的車費,或者是買個Figure漂洋過海的運費的零頭都不夠。又怎麼會顧及我們這些塵世間的小蝦蟹囊中羞澀戳襟見肘的艱辛。你們不為使用者考慮節省流量就算了,還陰陰溼溼在後臺開水喉一樣耗流量,pukgaai。)

回到正題,正因為它們可以無後顧之憂地寫日誌,我們逆向時才能夠獲得這麼多參考資訊,雖然有點矛盾,但還是要多謝這些海量日誌資訊。

即使mars的github倉庫有分支提供瞭解碼工具的程式碼,但是沒有微信在服務端的私有金鑰,你能夠將其它人的日誌解碼出來嗎?我水平有限常識淺疏,認為基本是不可能,不排除有泰斗可以做到。對於自己用的話,那是辦法不只一個。除了我在上面說的,將客戶端的隨機私鑰統統儲存這個方法外,還可以偽造公鑰patch掉微信程式裡的公鑰,這樣就可用自己的偽造私鑰來解碼日誌了。

patch方式有兩種,一種只要用hex編輯器即可以,將wechatwin.dll的'1dac3876bd566b60c7dcbffd219ca6af2d2c07f045711bf2a6d111a2b1fc27c4d'開頭的64位元組替換成你偽造的ECC公開金鑰。另一種就是在執行時,修改對應的動態記憶體,因為公開金鑰已經載入到xlog物件的成員了。對於動態改記憶體,方法很多,最簡單就是用windbg了。s-a命令搜尋,ea命令修改。

換句話說,只要包含有這個公開金鑰的模組都會有自己的一個xlogger。這些模組分別有wechatwin.dll,wmpf_host_export.dll,AppEx。它們對應的日誌檔名分別以下列字首開後,MM_, host_, main_。日誌檔案全部都在AppData/Roaming/Tencent/WeChat/log目錄。

然後來看找明文輸出

我們的切入點是appender,有一個關鍵的函式指標__xlogger_Write_impl。簡介如下,詳細去github看程式碼。

xlog的介面XLog設計在mars/comm/xlogger。它的實現XLoggerAppender在mars/xlog。

XLog設計跟Chrome::base::LogMessage相似,是對logging行為的封裝。初始化,設定本條日誌的說明資訊,包括原始碼檔名,行號,日誌物件。流串輸入運算子<<新增日誌內容。解構函式結束本條日誌,並且提交到XLoggerAppender。

XLoggerAppender相當於日誌裝置的實現,負責將XLog提交的日誌寫到儲存裝置上,過程包含加密。

所有WeChat模組都使用mars::xlog作為日誌系統,但每個EXE都將它自身的appender設定給所有模組的mars::xlog。這樣每個模組都統一使用EXE的appender作為日誌系統。具體方式就是將其它模組的appender的__xlogger_Write_impl指向同一個appender的__xlogger_Write_impl。沒錯,這個函式就是我們可以要找的樞紐點,所有明文日誌的入口點。要注意的是,wechatwin.dll生成的日誌以MMPC_開頭,它們是以utf8作為編碼的。而其它的卻是用gbk進行編碼的。

小程式平臺WeChatAppEx同時使用xlog進行日誌處理,它是將mars/xlog封裝成一個服務xlogger.mojom.XLogger,並且將chrome的日誌系統指向這個日誌服務。

由於日誌會洩漏個資,所以只能給一些無關重要的日誌作為演示。

本篇到這裡,下一篇再見。

逆向WeChat(八,日誌XLog)

逆向WeChat(七,查詢sqlcipher的DBKey,檢視protobuf檔案)

逆向WeChat(六,透過嗅探mojo抓包小程式https,開啟小程式devtool)

逆向WeChat(五,mmmojo, wmpfmojo)

逆向通達信 x 逆向微信 x 逆向Qt (趣味逆向,你未曾見過的signal-slot用法)

逆向WeChat(四,mars, 網路模組)

逆向WeChat(三, EventCenter, 所有功能模組的事件中心)

逆向WeChat (二, WeUIEngine, UI引擎)

逆向wechat(一, 計劃熱身)

相關文章