微信PC端技術研究-消息防撤銷

微信PC端技術研究-消息防撤銷
by anhkgg
2018年11月30日

0x1. 寫在前面

不知道大家有沒有遇到過這種情況,微信收到消息,但是沒有及時查看,然後閒暇時去看的時候,消息被撤銷了,撤銷了!

那時肯定是無比無語,撓心撓肺,究竟發了什麼?

有沒有一種神器可以防消息撤銷呢,有的!其實移動端和mac上已經有人做了相關的插件,但是PC端貌似沒人來啃這塊骨頭。

當然也可能是我沒找到,不過不管怎樣,對我來說就是沒有。

既然如此,小生來!

0x2. 技術分析

先理一下思路:

1.對方發送消息之後,我收到消息並在消息窗口顯示

2.然後對方點擊菜單選擇撤銷

3.我會收到發來的撤銷通知,然後刪除消息窗口顯示的消息

所以分析方向就基本定爲兩個方向了:

1.一個是通過分析網絡消息找到撤銷消息,然後攔截該消息阻止消息被撤銷

2.另一個是找到撤銷消息的界面操作,patch掉這個撤銷消息的操作即可

開始之前,先了解一下微信主要模塊都實現什麼功能。

模塊 功能
WeChat.exe 主程序,初始化操作,加載WeChatWin.dll
WeChatWin.dll 主要功能模塊,包括界面、網絡、功能
wechatresource.dll 保存資源的模塊,包括界面資源

主要分析目標就是WeChatWin.dll,其實很早之前就想分析這個東西了,但是那時候的老版本vmp殼加的更嚴重(映像中是,無法考證),所以擱置很久。

當前我分析的版本應該是最新的2.6.5.38,目前來看加殼程度還行,基本都是比較好分析的代碼,沒有經過加殼處理,不過聽說核心代碼還是處理過的。

1. 界面入手

首先試試從界面入手,都知道微信界面使用duilib實現的,所以可以從它的某些特徵入手分析,比如字符串click等,可以快速找到功能函數。

想的是通過click找到整個窗口響應函數,然後再分析找到撤銷操作的代碼位置。

確實很快就看到了窗口響應函數,不過大概有119個相關函數,所以無奈放棄。

換一個方向,通過菜單入手,搜索menu找到menuCmdDeletemenuCmdRevoke等字符串,menuCmdRevoke就是撤銷菜單對應的名字。有29個相關函數,還行。結合調試,嘗試了幾個函數,果然找到了刪除、撤銷對應的響應函數。然後想通過刪除菜單來找到刪除界面消息的代碼,而被撤銷消息其實也是刪除界面消息,不過折騰了一圈未果。

2. 網絡入手

通過recv回溯到接收網絡消息的函數中,40個,有點多。找了個tcp抓包工具,想抓到撤銷消息的調用堆棧,結果一直被其他消息干擾,無果。

3. 取巧

函數太多,分析很費實踐,想看看有沒有其他路可以走。在字符串中搜索revoke發現很多看起來有用的調試信息,不過也有79條之多。然後通過篩選和調試確認,找到了On RevokeMsg svrId : %d,然後回溯到撤銷消息處理的函數中。

if ( sub_10247BF0((wchar_t *)v258, (int)v259, (int)v260, v261) )
{                             // 撤銷消息
*(_OWORD *)&v259 = xmmword_10E6A278;
v257 = xmmword_10E6A278;
v256 = xmmword_10E6A278;
v255 = xmmword_10E6A278;
*(_OWORD *)&v251 = xmmword_10E6A278;
sub_1007E090(&v247, v353, SHIDWORD(v353));
f_log_10471580(
  (int)"02_manager\\SyncMgr.cpp",
  2,
  1357,
  (int)"SyncMgr::doAddMsg",
  (int)"SyncMgr",
  "On RevokeMsg svrId : %d",

經過調試發現sub_10247BF0返回1則進入撤銷消息處理中,消息被撤銷,跳過此段代碼,消息不會被撤銷,所以patch掉sub_10247BF0這個函數的返回值使其一直爲0即可完成防撤銷的功能。

當然也不能太隨意了,還是看看這個函數大概做了些什麼處理吧。關鍵參數第一個,調試中發現值如下:

<sysmsg type="revokemsg">
    <revokemsg>
        <session>wxid_0811111140112</session>
        <msgid>1111000048</msgid>
        <newmsgid>11411701182813217</newmsgid>
        <replacemsg><![CDATA["xxx" 撤回了一條消息]]></replacemsg>
    </revokemsg>
</sysmsg>

sub_10247BF0解析發現type="revokemsg"即判斷爲撤銷消息操作,返回1,很明瞭。

小結:此次分析運氣較好,通過revoke找到關鍵代碼,少花了很多時間,其實通過網絡方向堆棧篩選確認應該也是可以找到這段代碼的,但是通過結果去看,發現有近10層調用棧,肯定會花成倍的時間才能找到關鍵代碼。

0x3. 實現

分析是爲了最後能夠用起來,所以用上一篇文章《一種通用Dll劫持技術》寫了一個簡單的包含patch代碼(沒有用hook)的dll模塊,劫持微信的WeChatResource.dll來完成加載。

關鍵代碼如下所示,patch了sub_10247BF0返回值所在代碼,讓其eax永遠爲0。

bool FakeRevokeMsg()
{
	if (!IsSupportedWxVersion()) {
		return false;
	}

	//33 C0                xor eax,eax 
	BYTE code[] = { 0x33, 0xc0, 0x90 };
	HMODULE hMod = GetModuleHandle(WECHATWINDLL);
	DWORD offset = 0x247EF1;//返回值處
	if (!hMod) {
		return false;
	}

	PVOID addr = (BYTE*)hMod + offset;
	Patch(addr, 3, code);

	return true;
}

最後慣例,放上github地址:https://github.com/anhkgg/multi_wechat_pc

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章