一句話歸納本文python
一步步Hook微信,實現微信消息防撤回。git
引言github
上週六下班,與往常同樣,和公司同事去吃個飯,而後打個球,在支付的時候忽然卻意外發現個人微信號 被封了,出現了一個這樣的頁面(別人的截圖,當時慌了沒截圖,只想着解封):數據庫
臥槽,想一想在深圳從不帶錢包出門的我,要是沒同事在,而我只用微信支付這個工具的話...瀏覽器
細思極恐,解封的話須要發短信,而後讓另外一個朋友幫你解封,要輸身份證,手機號,銀行卡後八位幫你解封。 有點繁瑣,我開始回想我何時使用了微信外掛,是以前hook了微信步數,幾天98800步,而後捐步,被檢測出來了? 可是改步數那個是挺久以前的事了,隔那麼久才檢測出來?次日才發現並非我一我的被封號了,在逼乎上看到這篇:bash
《如何看待微信6月15號大面積封號問題(裝xposed插件)?》服務器
逼乎上討論沒那麼激烈,可是在酷安卻炸鍋了:微信
貌似此舉的目標是打擊大部分的微商插件,可是感受誤傷不少普通用戶啊,原理貌似是檢測 是否安裝了xposed,裝了的話直接封...上節hook下廚房檢測xposed的套路,看看可否也用在 微信上,反編譯一波dex文件,而後全局搜xposed:ide
果真,判斷異常堆棧裏是否有XposedBridge,em... 後面這個 com.zte.heartyservice.SCC.FrameworkBridge 又是?百度搜了一波包名,發現是中興的手機管家工具
呃,一個管家類的APP都攔截?是無需root就能夠凍結應用的緣由? 綜上因此說只要你裝了xposed,無論你有沒有用微信相關的插件都會被封!哇,吃瓜羣衆表示很受傷...
好吧,關於封號風波的事就講到這裏,本節的話想折騰個微信消息防撤回的東東, 緣由是這樣的,某天和UI小姐姐聊天到深夜:
萬一小姐姐是向我表白,而後害羞又撤回了,我不就虧了是吧~
好吧,開個玩笑,不過能看到別人撤回的東西心裏會莫名的偷(愉)稅(悅),並且有些老司機喜歡 發車而後撤回,圖還沒加載完,就撤回了,褲子他麼都脫了你TM撤回?
因此就有了這篇文章,Hook微信實現信息防撤回!
圖1
微信消息從發送到撤回的幾步
先不具體去看源碼,若是是讓你來作這個消息撤回,流程會是怎樣? 首先,信息確定是持久化到本地的,通常會保存在數據庫裏,否則怎麼每次打開。
撤回操做 -> 根據某一個標記檢索數據庫裏的記錄 -> 刪除記錄 -> 更新頁面 -> 發送信息到服務器更新其餘用戶的撤回狀態。
Maybe是這樣,接着就開始跟代碼了,依舊是撈比的逆向套路:方法跟蹤 + 反編譯源碼 + 日誌定位。 從點下撤銷開始跟蹤,直到頁面顯示撤銷成功~,入手關鍵詞SQLite,而後依次涉及到這幾個類:
com.tencent.wcdb.database.SQLiteCursor
com.tencent.wcdb.database.SQLiteQuery
com.tencent.wcdb.database.SQLiteSession
com.tencent.wcdb.database.SQLiteConnection
com.tencent.wcdb.database.SQLiteDatabase
com.tencent.wcdb.database.SQLiteProgram
com.tencent.wcdb.database.SQLiteStatement
com.tencent.wcdb.database.SQLiteQueryBuilder
複製代碼
接下來就要一個個看這個類大概是幹嗎的了,用AS打開反編譯的項目,而後打開這些類,左側選擇
一個個結構看,限於篇幅這裏就不一一列舉了,最終定位類應該是SQLiteDatabase,它的結構裏看到了這些方法:
接着就細化關鍵詞再搜索,進行方法跟蹤。
進去代碼看下這個update方法~
好吧,update調用的是**updateWithOnConflict()**方法,把參數打印出來看看?
運行結果發現每接受到一條信息都會觸發這個方法,連公衆號信息也會調用。 (PS:Hook的時候參數的個數和順序要對應,我一開始漏了一個string,log一直沒打印,還覺得 垃圾魅族的問題,沒把我噁心死)
能夠,那麼分別來看看本身發信息撤回和別人發信息撤回 的兩種狀況:
不難發現,第一個參數應該是一個表明信息類型的東西,普通訊息是rconversation,而撤回信息類型是message,而後是第二個參數,類型是ContentValue,這個類用於存取鍵值對的數據,每一個鍵值對錶示一列的列名和該列的數據,撤回類型的信息除了上面的content外還有後面一塊:
咱們先要明確防止撤回的是別人發的信息而不是本身的,因此先要過濾掉本身的,對比兩種狀況得出這樣的結論:
-> 判斷第一個參數是否爲message -> 獲取第二個參數中的type判斷是否等於10000(本身撤回是10002)
修改下程序,只處理別人發的信息的狀況,打Log驗證下,
看Log卻意外發現了一個問題:
是的,多了個你撤回了一條信息,出現這條信息的緣由是微信整了個比較貼心的功能:
用戶撤回信息的緣由多是編輯內容錯誤,在五分鐘之內,用戶點擊能夠經過點擊從新編輯, 得到撤回的文本信息,而後進行從新編輯,五分鐘事後就會變成你撤回了一條消息。
因此判斷條件還要加上這個過濾條件,因此代碼就變成:
繼續看Log:
行吧,是個聰明人都知道msgId這個字段裏面有東西。
圖2
圖3
先從第一波跳出來,想一想怎麼咱們到底要幹嗎?信息處理簡單流程是這樣的:
收到信息會插入到數據庫裏,而後撤回就是移除數據庫裏對應的這條信息!
那麼咱們能夠:
強調一點,搬運,一開始我還想着去處理找個信息,而後拿點什麼,加點什麼。 後面發現改動的成本很是大,並且不知道會引起什麼樣的問題,因此拿到信息直接 傳就好,不要加特技進去!
而後是找個標識,猜想是第一波分析出來的msgId,等等還須要咱們驗證下! 繼續跟方法,另外一個帳號發送一條信息,而後全局搜insert,定位到了一個數據庫插入的方法!
不會直接跟這個bt.f類,由於參數同樣,並且執行插入操做確定是不止調用一個方法的,跟下該方法的父方法,
繼續跟
能夠,參數不同,說明信息是從這裏構造的,而後也調用了好幾個方法,打開源碼查看這個類: com.tencent.mm.storage.be 還有這個b方法,從左側的類結構能夠看到,b方法有好幾個,可是第一個參數都是同樣的(bd bdVa) 進去這個bd類看看 com.tencent.mm.storage.bd
好複雜的類,加上混淆,看死我的,上面講了,搬運,而不是對信息作處理,咱們要作的只是找到這個信息裏和msgId同樣的標記而已。全局搜msgId:
恩,就是這個field_msgId了,咱們經過Xposed拿到這個變量的值,而後作下對比,驗證下咱們的猜測! 而後寫出這樣的程序:
懷着忐忑的心情重啓手機,發信息,撤回信息,看下日誌
臥槽,屌,猜對了,接下來咱們整個Map來存鍵值對,而後試試在觸發撤回操做的時候,根據msgId取出 對應的信息而後調用插入數據的方法,因此上面的代碼改一下,咱們要拿到調用b方法的那個對象。 而後就有了這樣的代碼:
運行下看看效果~
正常的微信裏撤回:
Hook了的微信:
能夠,儘管提示XX撤回了一條消息,可是信息並無真的被撤回,因此說Hook成功了~ 接着咱們進行一些細節的優化,還有改下撤回的信息。把能打印的都打印出來吧,把Content內容修改下:
打印下:
呃,個人微信好像有點不對勁,臥槽,變成頭像發信息了?:
感受是type類型的問題,改改,改爲撤回信息那個type?
嗯,信息是看到了,可是不該該是這樣的啊,後面排查了一下是updateWithOnConflict方法返回值是0, 才這樣,把返回值設置爲1,就能夠了(param.result = 1)
嗯,正常是正常了,不過這順序有點不對勁啊,撤回的提示信息比咱們插入的信息快了一些,那就加點吧。
運行看看:
想着大概差很少的時候,今早老同窗發的一個連接,而後撤回,撤回信息提示變成這樣了:
後來想一想仍是拼接成這樣的提示信息就算了,不要再在提示信息裏顯示具體內容:
小豬攔截到 XXX 撤回的信息
最終效果以下,能夠,很贊:
圖4
在我覺得一切大功告成,膨脹得沾沾自喜的時候,測試小哥發現了意外的發現了一個Bug, 發語音,圖片,視頻,雖然沒撤回,可是打開失敗,估計就是文件被刪除了。
而Android裏刪除文件調用的是File類的delete方法,跟一波方法,直接搜File.delete看下是否真的有調用:
好吧,直接Hook掉File類的delete方法,看看微信刪除對應類型文件的路徑,觀察一波這些路徑的規律,而後若是delete方法被調用了,過濾一波,不刪除文件,直接返回結果true,欺騙微信文件刪除成功,以此瞞天過海~ 代碼以下:
依次發送語音,圖片,視頻,而後撤回,對應的刪除記錄:
觀察下路徑規則,不難發現對應的文件夾是 voice2,image2,video,so過濾一波路徑,若是路徑包含這三個 直接過濾設置返回值爲True,另外公衆號,外鏈,都是屬於文本信息,只是微信作了特別的解析,好比上面那個 百度貼吧的,因此和普通訊息同樣處理就好。
而後發現只有語音可以正常打開,圖片和視頻都沒法正常打開,跟了下路徑,
用ES瀏覽器來到這個路徑下:
這就很奇怪了,明明圖片存在,可是就是不能正確加載,並且每次點開都會執行一次刪除的操做, 就是說數據庫裏還保存着這個記錄,撤銷信息無非 刪數據庫記錄+刪文件,刪文件確定是沒問題的, 那麼問題確定就出在刪數據庫記錄那裏了。跟蹤一下SQLiteDatabase裏的delete()方法,把參數和返回值打印下:
依次作:發送語音,發送圖片,發送視頻而後撤回的日誌跟蹤。
結合delete方法一塊兒看:
結合上面的日誌和delete方法的代碼,能夠得這樣的結論:
跟下返回值的代碼:executeUpdateDelete()方法,在SQLiteStatement類中
改變的行的數目?通常來講刪除一條數據,正確執行完,受影響的行數會是1。 而只有語音能正常播放,難道是這個緣由?hook下這個方法,若是第一個參數是這四個表, 直接把返回值設置成1試試~
發下信息而後撤回下試試~
行吧,視頻和圖片都能打開了,到此總算完美解決的,真的是一波三折。 接着改下UI頁面,補上上次下廚房Hook Xposed檢測的開光和防撤回開關。 最後的界面以下:
這就是我不喜歡折騰Xposed的緣由,太多未知,總要去猜想,去驗證本身的猜想,不斷安裝重啓, 當你覺得能夠了,而後又出新的問題,若是不是 設計小姐姐的緣由,真不想去碰這個東西。
附:由於代碼比較長,並且改動了下廚房,還有王者榮耀相關的代碼,因此就不貼代碼了,
直接給出倉庫連接自取 github.com/coder-pig/C…
來啊,Py交易啊
想加羣一塊兒學習Py的能夠加下,智障機器人小Pig,驗證信息裏包含: Python,python,py,Py,加羣,交易,屁眼 中的一個關鍵詞便可經過;
驗證經過後回覆 加羣 便可得到加羣連接(不要把機器人玩壞了!!!)~~~ 歡迎各類像我同樣的Py初學者,Py大神加入,一塊兒愉快地交流學♂習,van♂轉py。