<dd id="yzu3f"><tr id="yzu3f"><kbd id="yzu3f"></kbd></tr></dd>

              安基網 首頁 資訊 安全報 查看內容

              微信PC端技術研究:截獲語音消息

              2019-2-25 17:28| 投稿: lofor |來自: 互聯網


              免責聲明:本站系公益性非盈利IT技術普及網,本文由投稿者轉載自互聯網的公開文章,文末均已注明出處,其內容和圖片版權歸原網站或作者所有,文中所述不代表本站觀點,若有無意侵權或轉載不當之處請從網站右下角聯系我們處理,謝謝合作!

              摘要: 最近又學習了某位大佬用CE的方法,大佬的一句話有點醍醐灌頂,然后有了新的感覺,然后開始嘗試實踐這篇文章。 自己總結一下CE用法的核心思路:通過各種技巧搜索找到內存中關鍵數據,然后結合動態調試找到操作數據 ...

              0×0. 前言

              最近又學習了某位大佬用CE的方法,大佬的一句話有點醍醐灌頂,然后有了新的感覺,然后開始嘗試實踐這篇文章。

              自己總結一下CE用法的核心思路:通過各種技巧搜索找到內存中關鍵數據,然后結合動態調試找到操作數據的函數。

              0×1. 了解CE

              官網:https://www.cheatengine.org/

              看看來自百科的介紹:

              Cheat Engine是一款內存修改編輯工具 ,它允許你修改你的游戲或軟件內存數據,以得到一些其他功能。它包括16進制編輯,反匯編程序,內存查找工具。與同類修改工具相比,它具有強大的反匯編功能,且自身附帶了外掛制作工具,可以用它直接生成外掛。

              在我看來,CE做的最好的就是各種策略的內存搜索能力:

              1.支持準確數據(整數、字符串、十六進制、浮點數、字節數組等等)搜索,針對目標數據明確效果顯著,比如金幣數;

              2.支持數據范圍的搜索,比如大于某個值,小于某個值等等。比如想找到沒有顯示數值的血量數據;

              3.支持多組數據同時搜索,針對數據結構復雜的情況;

              4.支持搜索結果的多次過濾(圖中框選的Next Scan),最終找到目標數據。比如血量未知時,通過加血、減血多次搜索最終找到血量地址。

              說到底CE內存搜索的能力就是通過各種策略幫助你找到游戲中需要修改的數據(比如血量、分數、金幣等等),然后通過內存修改能力(直接改血量)打破游戲平衡,外掛制作工具生成外掛,助你超神!

              0×2. 分析

              進入正題,本文是要拿到微信聊天的語音消息,然后dump保存下來。

              要按以前我的思路,會通過網絡通信找到接受消息的函數,然后找到語音數據,看起來很簡單,但是有點難。

              因為函數真的很多,網絡消息也會受到很多干擾。

              現在用CE了,應該怎么辦呢?

              找到關鍵數據

              關鍵數據肯定是語音消息了,但是怎么搜索呢,肯定搜語音內容不現實,所以轉了彎,先看看文字消息,找到接受文字消息處理函數之后,猜測語音處理函數會相同或者在不同分支。

              接著,如何搜索文字消息呢?已經收到的顯示在聊天窗口的內容當然可以通過CE找到,但是沒用啊,它和接受文字消息處理函數已經沒關系了,流程已經處理完成了。

              那么在測試中肯定知道發送的消息內容,通過CE來搜索可以嗎?

              額,我覺得不行,還沒收到消息呢,內存中也沒有這個文字消息,搜索不到(如果可以,請大佬指點一下)。

              能想到的是,在接受到消息某一點通過調試器斷下來,然后CE搜索,這樣可以,但是這個斷點找不到阿,放棄。

              那怎么辦呢?

              看到左側聊天列表中顯示的最新一條消息,有了新的思路。

              每次收到新消息后,都會在列表中顯示最新消息內容(圖中綠框指示位置、注意是unicode字符)。

              那么,先用CE(First Scan)搜索當前搜到的消息內容,找到可能的內存地址。多次接受不同消息后,Next Scan按鈕搜索每次新的消息內容,最終確定聊天列表中顯示的最新消息內容的內存地址。

              多次刷選之后,留下兩個地址,通過CE修改內容,在界面中查看是否改變,最終確認第二個地址就是我們的目標,暫把該地址記錄為MsgAddr。

              分析消息接收函數

              關鍵數據地址已經找到,下面的工作復雜也不復雜,就看微信是如何實現的了。

              猜測微信實現消息顯示的流程是這樣的:

              1.recv收到消息,組裝完整包后,分發給消息處理函數;

              2.根據wxid找到要顯示消息的列表項,如果不在已聊天消息列表,就新建一個項;

              3.在列表中顯示消息,如果是表情顯示[文字],語音顯示為[語音],消息插入wxid對應消息隊列,或者存入數據庫。

              步驟3中肯定要寫前面找到的MsgAddr內存,把最新消息顯示到界面中,這個流程肯定在消息處理函數內部。

              So,通過OD對MsgAddr下內存寫入斷點,回溯堆棧就可以找到消息處理函數。

              具體操作如下:

              OD掛載Wechat.exe進程后,在左下角內存窗口處Ctrl+G,輸入找到的MsgAddr(11A11F34)回車,定位到該數據,然后再HEX數據處,右鍵彈出菜單,選擇斷點->內存寫入。

              斷點設置完成后,測試發送文字消息,OD斷住,代碼窗口顯示的就是修改MsgAddr的代碼位置,如上圖10CE412C處。

              Alt+K查看當前堆棧:

              調用堆棧
              地址       堆棧       函數過程 / 參數                       調用來自                      結構
              0012E068   106BD6F3   WeChatWi.10CE4110                     WeChatWi.106BD6EE             0012E064 //wcsncpy
              0012E088   106BD769   WeChatWi.106BD67E                     WeChatWi.106BD764             0012E084
              0012E09C   1011DD8B   WeChatWi.106BD753                     WeChatWi.1011DD86             0012E098
              0012E0EC   10206C67   包含WeChatWi.1011DD8B                   WeChatWi.10206C64             0012E0E8
              0012E600   1020E8F1   ? WeChatWi.10206460                   WeChatWi.1020E8EC             0012E5FC //界面操作

              看到這個調用棧是不是感覺好少,分析起來肯定簡單。但,其實是OD顯示的并不全,此時真的很想用windbg。

              在OD的右下角堆棧窗口,可以看到當前調用棧的參數和預覽數據。F8單步(或者Alt+F8執行到返回)逐步的回溯每層堆棧。關注MsgAddr的數據是如何生成的,也就是找到數據來源,然后找到消息處理函數。

              跟蹤過程不贅述(需要熟悉匯編知識),直到看到的最頂層的WeChatWi.10206460處,發現是把收到的消息內容顯示到聊天列表處的一個界面功能函數。

              那這里不是可以拿到消息了嗎,是的,普通文字消息已經可以拿到,但是語音內容不行。

              通過觀察內存窗口的數據,整理WeChatWi.10206460處的關于消息參數的大致結構。

              //聊天列表框信息
              
              struct chat_list_msg {
              DWORD unk;//
              wstring wxid;//
              //wchar_t* wxid;//4
              //int len;//8
              //int maxlen;//c
              DWORD unk1;//10
              DWORD unk2;//14
              wstring name;
              //wchar_t* name;//18微信名
              //int len;//1c
              //int maxlen;//20
              …
              wstring msg; //
              //wchar_t* msg;//3c
              //int len;//
              //int maxlen;
              }

              wstring msg字段就是文字消息內容,而語音消息則是預覽中看到的[語音]兩字,并沒有實際能夠聽到的語音數據,所以還得繼續往前找。

              繼續往上回溯了3層左右,進入了102DDC50,找到了語音消息的新信息。

              struct msg_xx
              {
              char unk[0x40];//
              wstring wxid1;//40
              wstring wxid2;//4c
              char unk1[0x10];//58
              wstring msg;//68
              char unk2[0x10];//74
              ;//84
              }

              在wstring msg處就是普通文字消息內容,而語音消息并不是我想象的就是直接語音的數據,而是…如下:

              <msg><voicemsg endflag="1" cancelflag="0" forwardflag="0" voiceformat="4" voicelength="1176" length="1334" bufid="147445261304397871" clientmsgid="416261363964373964444633636200230013013119fdd53b1f494102" fromusername="wxid_xxxxxxxxx" /></msg>

              真是一波三折,還不是語音的數據,而是關于語音信息的xml,有語音的大小,來自誰,在語音緩沖區中的id(bufid)等等信息。

              繼續往前找唄,最后回溯到了所有消息處理的分發函數10323FF0中。這個函數處理邏輯很復雜,我并沒有很快就找到如何生成語音消息的xml,以及處理語音數據的函數。

              一度卡住,重復分析了很多次。

              后來又回神想到了逆向神器IDA,xml中數據如voicemsg肯定是模塊中會在代碼中用到,看看有沒有有用的信息。

              用IDA打開Wechatwin.dll,shift+F12分析出所有字符串,Ctrl+F找到關鍵字voicemsg,看來有戲。

              真的是柳暗花明又一村。

              點擊字符串跳到代碼窗口,按下x,跳到引用該數據的位置。

              找到了解析語音xml數據和解碼語音數據的關鍵函數。

              f_parseVoiceXmlInfo_103148E0
              text:103149DD 0E4 0F 84 74 02 00 00                             jz      loc_10314C57
              .text:103149E3 0E4 68 D0 06 F0 10                                push    offset aVoicemsg ; "voicemsg"
              .text:103149E8 0E8 8B CF                                         mov     ecx, edi
              .text:103149EA 0E8 E8 31 28 3E 00                                call    f_xml_subnode_106F7220
              .text:103149EF 0E4 85 C0                                         test    eax, eax
              .text:103149F1 0E4 0F 84 60 02 00 00                             jz      loc_10314C57
              .text:103149F7 0E4 8D 70 2C                                      lea     esi, [eax+2Ch]
              .text:103149FA 0E4 68 C4 06 F0 10                                push    offset aClientmsgid ; "clientmsgid"
              .text:103149FF 0E8 8B CE                                         mov     ecx, esi
              .text:10314A01 0E8 E8 CA 3A 3E 00                                call    f_xml_getvalue_106F84D0

              函數103148E0解析xml拿到幾個字段的內容,返回上層函數調用一個語音解碼的函數進行處理,而這個解碼函數就會直接操作語音數據。

               (*(void (__thiscall **)(int *, _DWORD, _DWORD, int *, signed int))(*v7
                                                                                           + 28))(//
                            v7,
                            *(_DWORD *)(voice_msg + 48),      // 語音內容
                            *(_DWORD *)(voice_msg + 52),      // 語音長度
                            v17,
                            v4);

              函數103148E0回溯再看看,進入了分發函數10323FF0中,在一個循環中處理了多種流程,包括顯示界面最新消息的流程和解碼語音的流程。所以前面找的方向并沒有問題,只是缺少認真分析數據和代碼的耐心。

              不過,目的都達到了,找到了數據處理函數,最后通過hook這個函數就能拿到語音數據。


              小編推薦:欲學習電腦技術、系統維護、網絡管理、編程開發和安全攻防等高端IT技術,請 點擊這里 注冊賬號,公開課頻道價值萬元IT培訓教程免費學,讓您少走彎路、事半功倍,好工作升職加薪!



              免責聲明:本站系公益性非盈利IT技術普及網,本文由投稿者轉載自互聯網的公開文章,文末均已注明出處,其內容和圖片版權歸原網站或作者所有,文中所述不代表本站觀點,若有無意侵權或轉載不當之處請從網站右下角聯系我們處理,謝謝合作!


              鮮花

              握手

              雷人

              路過

              雞蛋

              相關閱讀

              最新評論

               最新
              返回頂部
              十一选五奖金对照表