操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    對破解過程不感興趣的可以直達文末 獲取插件下載地址

    帶自定義提示的防撤回

    1.前言

    最近太忙了,一直沒有時間更新這個文章.今天做點好玩的東西

    分析下怎么實現帶自定義提示的消息防撤回,實現的效果圖就是如下所示:

    可以看到這人一直在辱罵我,哈哈哈

    PC微信核心模塊:wechatwin.dll (2.6.7.57版本)

    相關工具:

    • windbg 或者 OD,x64dbg (動態調試工具)
    • IDA (靜態分析)
    • vs2015(開發hook功能模塊)

    2.分析

    大家知道ios/android/mac中都實現了防撤回,這些平臺上的分析也是有相似之處,就是搜索"Revoke"的關鍵字進行分析,我們可以借鑒他們的思路,嘗試從關鍵字"Revoke"入手,我們先腦中想一下整個撤回邏輯的實現

    • 對方在一個終端上發起一個撤回消息,服務端收到這個通知,下發消息給我方的所有終端
    • 我方所有的終端收到了服務端發來的撤回消息通知
    • 我方所有的終端實現撤回消息邏輯

    可以看出,如果我們要實現防撤回邏輯,需要在第二步的網絡數據層或者第三步的撤回邏輯實現層做點手腳,我們先搜索下關鍵字"Revoke"吧

    可以看到Revoke相當之多了, 初步可以認為上面標注的消息中可能存在我們需要查找的邏輯,通過調試確認,能發現 On RevokeMsg svrId : %d這個就是服務端發來的撤回消息通知,看下下圖中相關的邏輯

    可以看出來服務端對于撤回消息的定義是10002,上圖中還標注了sub_10252f80這個函數,下面解釋下為什么要標注這個函數

    看看上圖中對sub_10483FE0的匯編調用

     sub esp, 14h 
     mov ecx, esp; 
     push 0
     push dword ptr [eax+4]
     call sub_10483FE0
    

    再看下sub_10483FE0函數的匯編

    push ebp
    mov ebp, esp
    sub esp, 8
    push esi
    mov esi, ecx
    mov ecx, [ebp+arg_0]
    push edi
    mov dword ptr [esi], 0
    mov dword ptr [esi+4], 0
    mov dword ptr [esi+8], 0
    mov dword ptr [esi+0Ch], 0
    mov dword ptr [esi+10h], 0
    

    綜合起來看,可以看出來

     sub esp, 14h 
     mov ecx, esp;
    mov esi, ecx
    mov ecx, [ebp+arg_0]
    push edi
    mov dword ptr [esi], 0
    mov dword ptr [esi+4], 0
    mov dword ptr [esi+8], 0
    mov dword ptr [esi+0Ch], 0
    mov dword ptr [esi+10h], 0
    

    其實就是有兩個含義

    • ecx此時是一個類的指針,這個類的內存布局大小是0x14
    • 類每個成員是4字節大小,共有5個成員

    而且從sub_10483FE0函數中可以發現這是一個MultiByteToWideChar的操作,可以推斷下這個類其實有點類似Wstring,那么對于下面的匯編函數來說,此時ecx是wstring, dword ptr [eax+4]是string(UTF-8)

     sub esp, 14h 
     mov ecx, esp; 
     push 0
     push dword ptr [eax+4]
     call sub_10483FE0
    

    那將斷點斷在在call sub_10483FE0上, 先記錄下此時的ecx的值,等執行完call sub_10483FE0,再dd剛才保存的ecx的值,下面用xxxxx打碼了一些個人信息

    0:000:x86> dd 00efcb20-14
    00efcb0c 13f0e7f0 000000d6 00000100 00000000
    00efcb1c 00000000 a6d44d71 00efee84 00efe484
    00efcb2c 00000000 00000000 00000000 00000000
    00efcb3c 00000000 00000000 00000000 00000000
    00efcb4c 00000000 00000000 00000000 00000000
    00efcb5c 00000000 00000000 00000000 00000000
    00efcb6c 00000000 00000000 00000000 00000000
    00efcb7c 00000000 00000000 00000000 00000000
    0:000:x86> du 13f0e7f0 
    13f0e7f0 "<sysmsg type="revokemsg"><revoke"
    13f0e830 "msg><session>wxid_xxxxxxxxxxxxx"
    13f0e870 "</session><msgid>1675514177</msg"
    13f0e8b0 "id><newmsgid>2468247753633590716"
    13f0e8f0 "</newmsgid><replacemsg><![CDATA["
    13f0e930 ""xxxxxxx" 撤回了一條消息]]></replacemsg"
    13f0e970 "></revokemsg></sysmsg>"
    

    可以看到拿到了服務端的消息數據,注意其中的 xxxx 撤回了一條消息 這個和微信界面顯示是一致的,那么可以知道微信其實提取了replacemsg里面的消息顯示給界面

    IDA中搜索"replacemsg"這個字符串,可以發現sub_10257570中是唯一處理replacemsg的函數,并且可以找到一條sub_10252F80 -> sub_10257570 的調用鏈條,現在可以知道,sub_10252F80這個函數其實就是第三步的撤回邏輯實現層,下圖是sub_10252F80的邏輯,一步步的跟下去,可以知道sub_10253250這個函數是邏輯實現層

    下圖是sub_10253250函數中的邏輯,經過調試后能發現,如果v69為0的時候,界面仍然會顯示出來 xxx撤回了一條消息 , 但是實際上這條消息并沒有被撤回,所以我們的思路很簡單,Patch這塊的代碼,讓它一直走else里面的邏輯即可

    3.深入挖掘

    到第二步其實已經就可以了,但是其實還是有一個問題的,你會發現,上面在阻止別人撤回的同時也阻止了自己的撤回,更糟糕的是,當自己發起撤回的時候,界面會彈出來兩次 你撤回了一條消息 ,一開始其實還好了,自己用這個插件的時候倒是能接受,后來把這個插件給好友使用后,被一直吐槽,說體驗很差,還有就是希望加上自定義的撤回提醒,吐槽的久了以后,那就進一步研究下,當自己發起撤回的時候,就不攔截這個撤回了

    注意看下sub_10253250函數中下圖的代碼段, 其中v46是個結構體,sub_1004E320初始化這個結構,sub_1025A390是對這個結構體的賦值,v50是結構體中的成員,可以看到當v50為10000的時候,sub_10253250是什么事情也不做就退出了,這個結構體值得我們的關注,它里面的成員對sub_10253250的邏輯有很大的影響,調試觀察下這個結構體的數據吧

    將斷點斷在sub_1025A390執行后,直接能打印出來此時v46中的值,然后先讓別人撤回一條消息,再自己撤回一條消息,可以看到兩次v46內容的差異性

    為啥使用這兩個數據的作為差異比較呢,當自己撤回的時候,微信還提供重新編輯的功能,但是當別人撤回的時候,微信就直接撤回了,也就是說,微信其實是保存了是自己撤回還是別人撤回這個變量作為區分的

    再看下sub_10253250函數中下圖的代碼段

    查看sub_102541D0 -> sub_102542A0 的調用,在sub_102542A0中可以看出當a1為1的時候,會提供撤回編輯的能力,這個a1是 (_DWORD )(v7 + 52) !=0 賦值的 v7就是v46,也就是上圖中的差異的位置

    至此就找到了判斷是別人撤回還是自己撤回的標志,解決了第一個問題,那下面還要解決第二個問題,那就是撤回消息的定制

    既然sub_102542A0函數中提供了撤回編輯的能力,并且可以在sub_102542A0中看到下面的函數片段

    對應的匯編操作

    .text:102544A1 85 C0 test eax, eax
    .text:102544A3 74 06 jz short loc_102544AB
    .text:102544A5 66 83 38 00 cmp word ptr [eax], 0
    .text:102544A9 75 05 jnz short loc_102544B0
    

    可以看出來這個是字符串拼接,a5就是需要被拼接的字符串.調試看下這個數據

    Breakpoint 1 hit
    WeChatWin!IMVQQEngine::`default constructor closure'+0x1a7121:
    69a844a1 85c0 test eax,eax
    0:000:x86> du eax
    0c073b08 ""xxx" 撤回了一條消息"
    

    也就是說對a5進行修改就可以了,a5是sub_102542A0的參數,那么在sub_102541D0中看下a5的賦值

    好了,只需要修改lpmem就行了.

    4.工程實現

    現在我們知道只需要hook住sub_102541D0,然后判斷下撤回的來源

    1. 如果是別人撤回的,Patch掉sub_10253250的v69的邏輯,并且修改撤回的字符串消息為我們自定義消息
    2. 如果是自己的撤回,恢復sub_10253250的v69的邏輯

    下圖中SigPatternRevoke2_6_7_40是sub_102541D0函數頭開始的特征碼

    下圖是代{過}{濾}理函數的實現,注意修飾符__declspec(naked) 就是告訴編譯器按照我們寫的匯編代碼生成代碼,不要偷偷的再加入一些多余的匯編代碼

    解釋下 上圖 中間那段匯編push寄存器的來源, 首先是Push edx, 從下圖中可以看到sub_102541D0中判斷自己還是別人撤回的標志位是[exi+52],而esi來源于edx,故代{過}{濾}理函數需要的參數是edx寄存器

    從上圖中可以看到要修改的字符串是[ebp+8]的位置,而ebp又是

    push ebp
    mov ebp, esp
    

    也就是說當斷點斷在 push ebp這個位置的時候,此時的[esp+4]就是字符串了, 而看下代碼中的代{過}{濾}理函數

    __asm
     {
     PUSHAD;
     sub esp, 20;
     }
    

    其中 pushad會使得 esp-0x20(壓了8個寄存器), 然后又 sub esp, 20(0x14), 所以代{過}{濾}理函數 esp + 0x14 + 0x20 + 4 的位置就是字符串了

    剩下的RevokeMsg2_6_7_40函數就是比較簡單了

    1. 需要注意下這個字符串使用的內存不是crt的堆,而是進程堆就可以了. 至于為啥這樣,這里就當留個作業了,提示下sub_10484190函數內有答案
    2. PatchMemoryUCHAR中修改的就是sub_10253250的v69的邏輯

    具體的工程實現就在上篇文章上增加而來

    使用說明:代碼和bin都在壓縮包內

    如果是只需要 version.dll 可以下載論壇中的附件,解壓后將 version.dll 放到微信的安裝目錄下就可以

    如果正在運行微信,要重啟微信才生效。

    支持微信版本 2.6.7.40 2.6.7.48 2.6.7.57

    頭條號后臺私信我 關鍵字 【微信防撤回】獲取插件。

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有