29-項(xiàng)目實(shí)戰(zhàn)(1)

前言

本篇文章將接著之前的21-自動(dòng)搶紅包UI這個(gè)項(xiàng)目,繼續(xù)實(shí)現(xiàn)自動(dòng)搶紅包的功能。根據(jù)以往所掌握的逆向知識(shí),要在WeChat中實(shí)現(xiàn)自定義的功能,有2種方式:

  1. 越獄機(jī) ???? 創(chuàng)建tweak插件,插入代碼。
  2. 非越獄機(jī) ???? 先重簽名,再代碼注入。

其實(shí)以上2種方式,都可以通過MonkeyDev插件實(shí)現(xiàn),我們可以使用logos語法,實(shí)現(xiàn)Hook紅包功能相關(guān)的一系列方法,那么越獄非越獄這2個(gè)環(huán)境就可以自由切換,從而達(dá)到自動(dòng)搶紅包的目的。

一、編寫Tweak插件

接下來,我們就以越獄機(jī)的方式,編寫Tweak插件來實(shí)現(xiàn)自動(dòng)搶紅包的功能。

  1. 首先創(chuàng)建Tweak插件工程XFWeChatDemo????

如何獲取WeChat的BundleID呢?直接使用OpenSSL端口鏈接(可參考22-越獄 & OpenSSH)????

然后使用cy腳本,打印APPID(可參考19-Cycript)????

有個(gè)很實(shí)用的cy腳本 ???? mjcript

  1. 添加自定義的代碼(包括搶紅包的2個(gè)自定義的cell)
  1. 修改Monkey的配置????
  1. 編譯
  1. 越獄機(jī)運(yùn)行查看

如果碰到上述問題 ???? 說明你mac的RSA密鑰對(duì)不存在,需要重新生成。解決方案????

// 1. 生成公鑰 (直接回車回車回車生成)
ssh-keygen

// 2. copy到你的越獄手機(jī)中
ssh-copy-id -i $HOME/.ssh/id_rsa.pub root@你的手機(jī)ip地址

?? 確保你的手機(jī)已經(jīng)越獄,并且和mac是在同一個(gè)wifi下!

重新生成新的密鑰對(duì)后,再次運(yùn)行,手機(jī)會(huì)自動(dòng)重啟,打開微信設(shè)置頁面????

上圖可見,2個(gè)cell已經(jīng)展示出來了!????????????

圖片的處理

之前21-自動(dòng)搶紅包UI時(shí),是將圖片復(fù)制到app包里面,再重簽名安裝即可。那么現(xiàn)在越獄狀態(tài)下怎么將圖片copy過去呢?不難????

  1. OpenSSH連接手機(jī)設(shè)備????
  1. 搜索出WeChat的包路徑(需先啟動(dòng)WeChat)????
ps -A | grep WeChat

地址 ???? /var/containers/Bundle/Application/27D7F5E7-E36C-435F-B1B8-8267FECF58E6/WeChat.app/,只需要到.app這個(gè)路徑即可。

  1. 逐個(gè)將圖片copy到手機(jī)的WeChat的包路徑之中(先去到圖片的文件夾之中)????
scp -p 12345 ./xxx.png root@localhost:/var/containers/Bundle/Application/27D7F5E7-E36C-435F-B1B8-8267FECF58E6/WeChat.app/
  1. 再次運(yùn)行就有圖片了????

至此,UI方面就基本完成了。

二、定位聊天界面消息接收

接下來就是實(shí)現(xiàn)搶紅包功能了,在搶紅包之前,我們得先理清WeChat接收消息的流程。最直觀的當(dāng)然是 ???? 在聊天界面定位消息的接收,觸發(fā)了哪些方法的調(diào)用?

準(zhǔn)備工作

在定位之前,我們還要做些準(zhǔn)備工作????

  1. 對(duì)WeChat包進(jìn)行砸殼class-dump ???? 可參考23-應(yīng)用砸殼
  2. info.plist中刪除UIDevice的配置,否則無法重簽名????
  1. 定位聊天界面的VC 看UI層級(jí) ???? 找到聊天信息的VC
    有2種方式定位VC????
  • attach to process,然后查看UI層級(jí)????
  • cycript命令查看 ????

我們定位到聊天的界面VC ???? BaseMsgContentViewController

  1. hook VC中所有的方法 ???? 鎖定【接收紅包信息】的方法
    • logos hook所有方法 pl腳本(在theos的目錄下面) 輸出xm文件????
      pl腳本位置????

來到dump的文件夾,執(zhí)行腳本輸出????

logify.pl BaseMsgContentViewController.h > ../logMethod.xm

  • logMethod.xm直接拖到工程去使用????

上圖可見,就是通過%log查看調(diào)用方,參數(shù)等信息,再%orig回到原有流程。

查看源碼????

編譯前改下配置項(xiàng)????

編譯生成.mm????

logMethod.mm拖進(jìn)工程????

然后再次編譯,會(huì)報(bào)錯(cuò)????

.mm文件過大,查看時(shí)會(huì)很卡,我們直接看.xm文件。

報(bào)錯(cuò)的方法我們就注釋掉,直至編譯成功????

??注意:此時(shí)是沒有安裝的,在安裝之前,先殺掉當(dāng)前的微信進(jìn)程!

修改配置 ???? 編譯即安裝????

  • 控制臺(tái)中查看信息

很明顯,這里打印的信息,就是我們之前通過logify腳本添加的代碼所輸出的。

  1. 定位 ???? 收到消息所觸發(fā)的方法
  • 首先接收一個(gè)消息,看看控制臺(tái)的輸出????

我們只看前面觸發(fā)的幾個(gè)方法,有onNewSyncStart --> findNodeDataByLocalId -->addMessageNode,其中onNewSyncStartfindNodeDataByLocalId 的參數(shù)沒有什么實(shí)質(zhì)性內(nèi)容,我們來到addMessageNode????

上圖可見,addMessageNode方法中的入?yún)?,就有我們想要的,例如?br> m_nsFromUsr發(fā)消息的用戶Id,m_nsToUsr接收消息的用戶Id,type可能是消息類型等。

此時(shí),我們定位到方法addMessageNode,但是,你仔細(xì)想想,如果我們定位的是聊天頁面的addMessageNode,再hook它搶紅包,這時(shí)的時(shí)機(jī)是不是太晚了?

  • 接著,我們退出聊天頁面,切換到【發(fā)現(xiàn)】tab,再接收消息,看看控制臺(tái)輸出 ????

就2個(gè)方法onNewSyncStartonNewSyncfinish。當(dāng)然我們只看onNewSyncStart,明顯它時(shí)機(jī)更早,繼續(xù),看看誰調(diào)用它?

  • onNewSyncStart斷點(diǎn),看函數(shù)調(diào)用棧等信息
    ? 首先attach process附加進(jìn)程WeChat,斷住, lldb中methods指令查看方法地址????

??注意:如果沒有methods指令,可參考18-lldb(下)chisel & 插件中LLDB指令集插件的安裝。

我們搜索出onNewSyncStartaddMessageNode的地址????

- (void) onNewSyncStart; (0x117f32394)

- (void) addMessageNode:(id)arg1 layout:(BOOL)arg2 addMoreMsg:(BOOL)arg3; (0x117f3b850)

? b指令下斷點(diǎn)

斷住后,c指令continue繼續(xù)執(zhí)行。接收一條消息,驗(yàn)證是否成功????

? 接著,sbt指令查看調(diào)用棧信息????

frame#1frame#2這兩項(xiàng)沒有恢復(fù),我們繼續(xù)執(zhí)行一次看看????

frame#1 ???? 0x10e7f4418 WeChat-[MMExtensionCenter callExtension:selector:block:]`

frame#2還是沒獲取到,我們可以記錄一下地址

frame #2 : 0x10e773584 WeChat`___lldb_unnamed_symbol958446$$WeChat ... unresolved womp womp + 56

然后image list查看首地址,計(jì)算偏移地址????

那么0x10e773584 - 0x0000000104f78000 = 0x97FB584,該地址應(yīng)該在Text常量區(qū),然后我們用Hopper打開Mach-O文件,查看該地址是????

沒有什么有價(jià)值的信息。

三、定位全局消息接收

接下來定位addMesssageNode的調(diào)用棧信息,還是一樣,sbt查看????

第二次sbt恢復(fù)了調(diào)用棧的前面幾個(gè)方法的信息,得到幾個(gè)類,包括BaseMsgContentLogicController MMExtensionCenter MMContextCMessageMgr????

frame #1 : 0x10343b614 WeChat`-[BaseMsgContentLogicController DidAddMsg:] + 852
frame #2 : 0x10341ae24 WeChat`-[BaseMsgContentLogicController OnAddMsg:MsgWrap:] + 728
frame #3 : 0x109968418 WeChat`-[MMExtensionCenter callExtension:selector:block:] + 204
frame #4 : 0x1098fc244 WeChat`-[MMContext callExtension:selector:block:] + 168
frame #5 : 0x10135e4b8 WeChat`-[CMessageMgr MainThreadNotifyToExt:] + 836

接著逐個(gè)分析這些類中定位的方法, logos語法%log查看信息。

  1. 首先是BaseMsgContentLogicController
    • %log打印DidAddMsg:OnAddMsg:MsgWrap:這兩個(gè)方法????
%hook BaseMsgContentLogicController
- (void)DidAddMsg:(id)arg1 {
    %log;
    %orig;
}

- (void)OnAddMsg:(id)arg1 MsgWrap:(id)arg2 {
    %log;
    %orig;
}
%end
  1. 同理,再看MMExtensionCenterMMContext這2個(gè)類的方法,貌似和message的關(guān)系不大,所以,我們繼續(xù)hookCMessageMgr的方法????
%hook CMessageMgr
- (void)MainThreadNotifyToExt:(id)arg1{
    %log;
    %orig;
}
%end
  1. 只保留上面要hook的三個(gè)方法????

僅編譯????

編譯,生成.mm ????

  1. 退出聊天界面,回到【發(fā)現(xiàn)】tab首頁,然后接收消息,看看控制臺(tái)的輸出????

此時(shí),我們還未進(jìn)入到聊天VC,紅框處的都是CMessageMgr類的MainThreadNotifyToExt方法輸出的日志。

再一次,我們?nèi)サ搅奶霽C,看看控制臺(tái)的輸出????

此時(shí)就有了OnAddMsgDidAddMsg方法的打印。經(jīng)過分析,最終我們得到的方向就是????

MainThreadNotifyToExt方法不是我們研究搶紅包的唯一方法,類CMessageMgr才是重點(diǎn)的研究對(duì)象。

四、定位消息管理者

接下來重點(diǎn)研究CMessageMgr消息管理者類。

  1. pl腳本``hook所有方法 ????

logify.pl CMessageMgr.h > ../logMethodCMessageMgr.xm

  1. logMethodCMessageMgr.xm文件拖入Monkey注入工程中,查看源碼????

近300行。

  1. 編譯,產(chǎn)出.mm,拖入工程????

然后注釋一些編譯不過的方法????

  1. 編譯運(yùn)行,重新接收消息,打開控制臺(tái)查看????

得到GetMsg: CheckMessageStatus: AsyncOnPreAddMsg:onNewSyncAddMessage OnNewSyncAddMsgSessionArray等等很多關(guān)于消息的方法打印????

-[<CMessageMgr: 0x13fe6d300> GetMsg:Aron1101 LocalID:16 hasError:0x16f1c6d70]

-[<CMessageMgr: 0x13fe6d300> CheckMessageStatus:Aron1101 Msg:{m_uiMesLocalID=16, m_ui64MesSvrID=7818316956601146902, m_nsFromUsr=Aro*101~8, m_nsToUsr=wxi*o12~19, m_uiStatus=3, type=1, createTime=1629794366 msgSource="<msgsource><sequence_id>745337625</sequence_id></msgsource>"} ]

-[<CMessageMgr: 0x13fe6d300> onNewSyncAddMessage:{m_uiMesLocalID=16, m_ui64MesSvrID=7818316956601146902, m_nsFromUsr=Aro*101~8, m_nsToUsr=wxi*o12~19, m_uiStatus=3, type=1, createTime=1629794366 msgSource="<msgsource><sequence_id>745337625</sequence_id></msgsource>"} ]

-[<CMessageMgr: 0x13fe6d300> onNewSyncAddMsgSessionArray:{
    Aron1101 = "{m_uiMesLocalID=16, m_ui64MesSvrID=7818316956601146902, m_nsFromUsr=Aro*101~8, m_nsToUsr=wxi*o12~19, m_uiStatus=3, type=1, createTime=1629794366 msgSource=\"<msgsource><sequence_id>745337625</sequence_id></msgsource>\"} ";
} withUsers:{(
    Aron1101
)}]

這么多方法觸發(fā),關(guān)鍵我們是要對(duì)消息本身進(jìn)行研究,看看有哪些信息,才能準(zhǔn)確定位紅包消息。所以,最終我們鎖定到CheckMessageStatus它的參數(shù)才是我們想要的????

-[<CMessageMgr: 0x13fe6d300> CheckMessageStatus:Aron1101 Msg:{m_uiMesLocalID=16, m_ui64MesSvrID=7818316956601146902, m_nsFromUsr=Aro*101~8, m_nsToUsr=wxi*o12~19, m_uiStatus=3, type=1, createTime=1629794366 msgSource="<msgsource><sequence_id>745337625</sequence_id></msgsource>"} ]
  1. 接下來,我們hookCheckMessageStatus:Msg:方法????
%hook CMessageMgr
- (void)CheckMessageStatus:(id)arg1 Msg:(id)arg2 {
    %log;
    %orig;
}
%end

也可以自定義打印格式????

%hook CMessageMgr
- (void)CheckMessageStatus:(id)arg1 Msg:(id)arg2 {
    NSLog(@"arg1:%@\narg1 Class:%@\narg2:%@\narg2 Class:%@", arg1, [arg1 class], arg2, [arg2 class]);
    %orig;
}
%end
  1. 編譯安裝(記得手動(dòng)殺掉WeChat App進(jìn)程),然后接收一條消息,查看控制臺(tái)輸出????

arg1是字符串 agr2是CMessageWrap,這個(gè)就是消息model類????

arg2:
{
  m_uiMesLocalID=17, 
  m_ui64MesSvrID=6443875340523928360, 
  m_nsFromUsr=Aro*101~8, 
  m_nsToUsr=wxi*o12~19, 
  m_uiStatus=3, 
  type=1, 
  createTime=1629854565 
  msgSource="<msgsource><sequence_id>745337629</sequence_id></msgsource>"
} 

arg2 Class:CMessageWrap

可以看到,普通的文本消息type=1,消息的類class是CMessageWrap。

  1. 然后再接收個(gè)紅包消息,查看輸出????

紅包消息的type=49。那么我們接下來,就能在CheckMessageStatus:Msg方法中,做一個(gè)hook????

如果接收的消息type=49(即紅包),那么就執(zhí)行拆開紅包。

五、動(dòng)態(tài)分析拆紅包

接下來就是紅包了,還是一樣,需要定位所調(diào)用的方法。

需要使用工具IDA ???? 靜態(tài)分析搶紅包的方法。

  1. attach附加 viewDebug查看UI層級(jí)????

上圖可見,紅包的view類是WCRedEnvelopesReceiveHomeView,同時(shí)是個(gè)UIButton。

  1. 定位到按鈕的方法 ????

拆button所對(duì)應(yīng)的方法是OnOpenRedEnvelopes。接下來就是靜態(tài)分析 ???? 如何模擬觸發(fā)OnOpenRedEnvelopes方法,這個(gè)我們?cè)诤竺娴奈恼轮欣^續(xù)講解。(30-項(xiàng)目實(shí)戰(zhàn)(2)

總結(jié)

本篇文章,通過Tweak插件的方式,在越獄機(jī)中演示,如何一步步地定位 ???? 接收紅包消息所觸發(fā)的方法,hook并打印這些方法的參數(shù),找到我們想要的消息model類的具體信息,進(jìn)而為我們下一步,分析紅包做準(zhǔn)備。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容