一羊赵、前言
前一篇文章已經(jīng)詳細介紹了如何使用Xposed框架編寫第一個微信插件:搖骰子和猜拳作弊器 本文繼續(xù)來介紹如何使用Xposed框架編寫第二個微信插件售淡,可以將本地小視頻發(fā)布到朋友圈的功能。在這之前我們還是要有老套路慷垮,準備工作要做好揖闸,這里還是使用微信6.3.9版本進行操作,準備工作:
1料身、使用apktool工具進行反編譯汤纸,微信沒有做加固防護,所以這個版本的微信包反編譯是沒有任何問題的芹血。
2贮泞、借助于可視化反編譯工具Jadx打開微信包,后續(xù)幾乎重要分析都是借助這個工具來操作的。
二、猜想與假設(shè)
做好上面這兩步之后准脂,加上我們在之前的那個編寫插件的基礎(chǔ)之上,我們本次操作就應(yīng)該非常簡單了令蛉,還記得之前的插件的突破口是啥嗎?看過文章的同學應(yīng)該了解通過分析界面的控件來獲取到id值狡恬,然后全局搜索得到的突破口珠叔,那么本文其實可能不需要這個方式了,而是另外一種方式弟劲,下面來詳細介紹一下祷安。在這之前我們先來看看微信正常的發(fā)布小視頻到朋友圈的方式,會跳轉(zhuǎn)到這個發(fā)布頁面:
那么我們又要開始大膽的猜想了:
首先這個頁面有的元素:標題兔乞,小視頻汇鞭,地理位置等信息,而這些信息應(yīng)該會在請求發(fā)布的時候攜帶到服務(wù)器上庸追。這個有點類似于小文件的上傳功能霍骄。所以這個視頻的文件是如何得到的。那么可以得到的假設(shè):這個頁面是一個Activity頁面锚国,可能從其他頁面跳轉(zhuǎn)過來的腕巡,同時會把這些元素信息通過intent攜帶過來玄坦,而小視頻是個文件血筑,所以應(yīng)該會攜帶文件的名稱绘沉。
三、逆向分析
有了這猜想之后豺总,咋們就可以開始操作了车伞,首先得到這個頁面的activity名稱,這個比較簡單了喻喳,直接使用一個命令即可:adb shell dumpsys activity top
看到這個頁面的名稱是SightUploadUI另玖,我們借助Jadx反編譯微信之后,找到這個類:
我們直接看onCreate方法中有沒有對intent參數(shù)解析操作表伦,或者我們可以在這個類中全局搜一下getIntent字段谦去,也可以快速得到解析的地方:
看到第一個字段Kdescription,從字段的名稱來看應(yīng)該是描述信息蹦哼,而從下面的代碼setText調(diào)用更可以確認了這個就是標題信息鳄哭。我們繼續(xù)查找:
又發(fā)現(xiàn)了一個字段KSightDraftEntrance,這塊代碼就有點多了纲熏,他是一個boolean類型妆丘,所以先不管了,因為后面即使是嘗試的話也就兩次操作局劲,一次false一次true勺拣。不礙事的!可是到這里我們在也搜不到其他字段了鱼填,但是這個就和我們的預期不一樣了药有,還差幾個元素信息呢?最重要的視頻文件路徑?jīng)]有苹丸,所以這個就要想起在onCreate方法中有一個ae類初始化的時候把當前activity傳遞進去了塑猖,那么可能他內(nèi)部繼續(xù)進行了參數(shù)解析,我們可以進去查看一下:
果然在他內(nèi)部還有三個字段解析谈跛,分別是:KSightThumbPath羊苟,KSightPath,sight_md5感憾;而從字段命名上來看猜想這個應(yīng)該就是和視頻信息相關(guān)的字段了蜡励。這里只要有Android開發(fā)經(jīng)驗的同學應(yīng)該可以猜想:KSightPath字段是短視頻路徑,KSightThumbPath是短視頻的默認封面圖阻桅,sight_md5是短視頻的校驗值凉倚。到這里其實我們已經(jīng)感覺快成功了,得到了這五個參數(shù)嫂沉,那么我們可以直接嘗試了操作了:
在本地存放一個短視頻稽寒,封面圖片,然后計算短視頻的md5碼趟章,最后通過intent來啟動這個頁面即可杏糙。先不管后面的上傳過程了慎王,咋們可以先試驗能成功跳轉(zhuǎn)到這個頁面展示本地小視頻功能。
可惜到這里我們有一個問題宏侍,就是怎么獲取這個啟動頁面的activity呢赖淤?也就是用哪個activity來啟動他呢?有的同學可能這么干谅河?直接簡單明了的編寫一個小程序咱旱,然后用小程序的activity啟動這個頁面。這個猜想是可以的绷耍,不過我沒嘗試吐限,因為我想微信做了activity啟動安全防護的,不可能在其他應(yīng)用中可以啟動微信中的任意一個頁面褂始。所以這里我就沒費那勁了毯盈。而是想到用微信自己的頁面來啟動他,那么如何獲取到微信的一個其他頁面呢病袄?這個也簡單搂赋。咋們可以打開一個聊天頁面,繼續(xù)使用adb shell dumpsys activity top 命令查看頁面:
好了益缠,就是這個LauncherUI頁面了脑奠,那么知道這個頁面下面怎么獲取這個對象呢?這時候就需要借助Xposed框架進行Hook了幅慌,代碼如下:
看到了吧宋欺,代碼很簡單的,我們hook頁面的onResume方法胰伍,因為這時候頁面已經(jīng)初始化完成了是整個Activity生命周期中的比較晚的一個方法了齿诞,所以攔截他就可以了。然后在攔截回調(diào)用使用MethodHookParam的thisObject屬性就可以得到這個方法所屬的對象了骂租,也就是LauncherUI類型了祷杈。
好了既然現(xiàn)在微信啟動頁面也有了,下面就簡單了渗饮,直接構(gòu)造上面的五個參數(shù)得到intent直接啟動:
代碼很簡單但汞,咋們直接運行模塊,然后重啟設(shè)備生效互站,然后打開微信界面瞬間看到效果了:
果然跳轉(zhuǎn)到這個頁面了私蕾,也就是說我們的猜想對了,下面我們點擊發(fā)送胡桃,會發(fā)現(xiàn)發(fā)送失敗了:
原因可能有兩個:
1踩叭、沒有弄對視頻文件的MD5碼
2、視頻格式不符合服務(wù)器接受的要求:視頻的長度和視頻的大小
關(guān)于第二個原因,其實網(wǎng)上有答案容贝,就是微信這個發(fā)布的小視頻長度不能超過15s自脯,大小不能超過1M。所以這里我就把本地視頻做成了符合這兩個標準的嗤疯,再次操作依然是這樣的失敗效果。那么就有可能猜想是視頻的MD5碼校驗出問題了闺兢,上面看到代碼中我傳入的MD5碼是aaa茂缚,我是為了方便沒去弄。但是這里就必須寫了屋谭。獲取文件的MD5碼這里就不多解釋了脚囊,不過可惜的是,MD5弄成文件的還是失敗桐磁。那么這時候就猜想他或許不是真正意義上的MD5值了悔耘,可能加上了他自己的一個算法了。所以又來了一個問題我擂,如何得到這個算法呢衬以?
這時候就需要跟蹤代碼看看其他頁面跳轉(zhuǎn)到這個頁面攜帶過來的MD5碼是什么呢?我們可以這么干就是全局搜索那五個字段中的任意一個即可校摩,這里在Jadx中全局搜索:sight_md5
我們點擊進入查看方法:
繼續(xù)查找這個方法在哪被調(diào)用了:
咋們繼續(xù)點擊進入查看:
這里看到了倒數(shù)第二個參數(shù)就是那個MD5碼值看峻,我們在全局搜一下這個變量在哪里被使用到了:
看到這里有賦值的地方,點擊進入查看:
然后查看這個kbVar變量衙吩,在上面的代碼中:
這里我們可以先看看這個kb類的定義:
這里的aFL就是那個MD5碼值了互妓,我們繼續(xù)上面的那個a方法查看哪些地方調(diào)用了,不過查找是沒有效果的坤塞,因為這個方法可能是抽象的冯勉,所以咋們得找到他抽象定義的地方,在上面就是一個抽象類c:
然后進入c類查看抽象方法a:
然后查找a方法調(diào)用的地方:
繼續(xù)查看這個方法的調(diào)用地方:
這時候我們多看一下摹芙,這個方法所屬的類是個單例:
那么繼續(xù)查看這個g方法被調(diào)用的地方灼狰,或者全局搜一下jJA這個變量的使用也可以的:
又回到了剛剛的那個MainSightContainerView類了,這里看到了賦值的地方了浮禾,而且是給aFL字段賦值的伏嗜,這個就是上面看到kb類中的字段值,這里依然調(diào)用了一個方法計算MD5碼值伐厌,而且傳入的參數(shù)是視頻路徑:
這里首先判斷當前視頻文件是否存在承绸,然后在進行文件操作:
真正加密算法是在a方法中,這里也可以看到因為計算文件的MD5碼是耗時的挣轨,所以這里做了一個優(yōu)化军熏,只會計算文件的前100KB數(shù)據(jù):
哎,到這里終于真相大白了卷扮,看到他的確是用了MD5算法均践,只是在后面自己又高了一個簡單的算法彤委。所以這里我們?yōu)榱撕唵位蚝猓梢灾苯影堰@三個方法拷貝到我們的Xposed模塊代碼中:
然后在把之前的intent中的sight_md5字段值替換一下:
這時候咋們在之前的攔截的onResume方法中再次調(diào)用焦影,然后重啟設(shè)備生效,點擊發(fā)送:
哈哈封断,到這里可以看到斯辰,發(fā)送成功啦啦,好興奮呀坡疼。終于實現(xiàn)了這個功能彬呻。以后可以盡情的裝逼了。
注意:在上面我們定位一個方法在哪些地方被調(diào)用柄瑰,有時候可能找不到闸氮,但是不代表這個方法真的沒有被調(diào)用,而是因為這個方法是抽象的教沾,直接跟蹤可能沒有效果湖苞,這時候就需要去抽象方法的定義地方去全局搜索就可以了。
四详囤、添加發(fā)布事件
但是到這里我們是否就結(jié)束了本次操作了财骨,其實并沒有,因為有的同學在上面的實踐中會發(fā)現(xiàn)藏姐,有時候微信會打不開隆箩,一打開就閃退,其實這個原因是我們雖然攔截了LauncherUI頁面的onResume方法羔杨,但是這個頁面比較獨特的是微信中的首頁也是他捌臊,所以這就有可能出現(xiàn)你剛剛要打開微信頁面,有些初始化操作沒做完兜材,而這時候你就立馬跳轉(zhuǎn)到SightUploadUI頁面去發(fā)布視頻會出現(xiàn)問題理澎。所以這里就存在一個發(fā)布視頻的觸發(fā)時機曙寡,為了更好的體驗效果举庶,我們決定做到更人性化镀琉,就是添加一個菜單可以點擊的時候再去觸發(fā)發(fā)布視頻邏輯烁设。那么又來了一個問題就是如何在微信中添加一個我們自己想要的菜單装黑?這個我覺得比上面那個還簡單點曹体,我們準備在聊天界面中選中一條消息之后彈出的菜單中加一項子菜單:
就是在這里铜幽,我們加一項除抛,有的同學覺得這個可能會比較麻煩橄教,其實很簡單护蝶,我們只要找到這個菜單定義的地方即可。直接看看步驟:想得到這個菜單定義地方很簡單负饲,咋們先去反編譯之后的values/strings.xml文件中找到這個字符串的定義:
得到他的id值是ne返十,然后在Jadx中全局搜索:R.string.ne
注意:這里可能有的同學會好奇涛漂,在之前一篇文章中不是得去public.xml中找到ne對應(yīng)的id整型值瓢剿,然后全局搜索嗎?這里可能和微信做了資源混淆工作有關(guān)鉴象,開始的時候通過整型值死活沒找到纺弊,最后無意間用了這種方式找到了淆游。所以以后我們可以先用標準方案去public.xml中找到id對應(yīng)的整型值,如果沒找到腊脱,在使用這種方式進行查找即可陕凹。
上面找到這個字符串定義的地方杜耙,直接點擊進入即可:
這里可以看到了,使用了系統(tǒng)提供的ContextMenu類進行菜單定義的珊豹,這里就需要你對這個類了解了。后面添加菜單就必須用add方法來進行添加了劫恒,不過這個方法還是比較簡單的,參數(shù)都比較好理解主要是菜單組的id值族壳,菜單自身的id值,菜單名稱拢操,然后在設(shè)置點擊事件即可令境。下面我們繼續(xù)看這個方法在哪里被調(diào)用了:
不過這個方法跟蹤沒有結(jié)果,猜想他可能是一個抽象方法栖茉,所以就去他定義的地方進行查看y類:
果然是一個抽象方法,這里在跟蹤就可以了:
點擊查找結(jié)果:
繼續(xù)看這段代碼之前的方法和類定義:
這里有一個變量fHr,也就是菜單創(chuàng)建的回調(diào)接口犬钢,在往上面查看:
到這里就看明白了,在ChattingUI有一個內(nèi)部靜態(tài)類a歹颓,在這個類內(nèi)部開始創(chuàng)建菜單巍扛,然后定義一個fHr變量代表菜單創(chuàng)建的回調(diào)接口類型撤奸,然后在onCreateContextMenu回調(diào)方法中進行子菜單添加工作矢棚。
好了上面就分析了菜單的創(chuàng)建代碼幻妓,下面咋們就開始操練了肉津,還是得借助Xposed進行攔截了,這次攔截哪個呢距糖?咋們可以攔截ChattingUI這個類的靜態(tài)內(nèi)部類a悍引,然后我們自己在定義一個創(chuàng)建菜單的接口趣斤,去替換fHr變量的值浓领,最后我們只要在我們的回調(diào)接口中操作即可:
這里攔截代碼也是比較簡單的,主要是定義我們自己的回調(diào)接口泪幌,然后在替換fHr值即可祸泪,再來看看接口定義:
這里才是最關(guān)鍵的代碼了浴滴,在onCreateContextMenu回調(diào)方法中創(chuàng)建一個菜單升略,但是這里有一個問題就是怎么獲取到菜單組的id值炕倘,這個我們還得回到開始的那個添加菜單代碼:
看到罩旋,這里他是先通過view的tag得到dd對象涨醋,然后在調(diào)用position屬性即可,那么我們操作也就簡單了宪潮,繼續(xù)使用反射機制就可以得到這個值了梯轻。代碼如上喳挑。
代碼編寫完之后再次運行之后蟀悦,重啟設(shè)備生效,打開一個聊天室然后選中一條消息:
哈哈看到這個菜單選項了孙乖,咋們點擊之后就可以跳轉(zhuǎn)到發(fā)布頁面了:
五、知識概要與技巧總結(jié)
好了到這里我們就完成了本文提到的如何將本地小視頻發(fā)布到朋友圈功能實現(xiàn)恋拷,下面來總結(jié)一下本文的實現(xiàn)步驟以及能夠?qū)W習到的逆向技巧:
1蔬顾、首先猜想微信發(fā)布視頻的頁面中的幾個重要元素信息:標題诀豁,視頻信息烹骨,地理位置等穆趴,然后這些信息可能在其他頁面通過intent傳遞過來的遇汞,那么應(yīng)該不可能傳遞整個視頻數(shù)據(jù)络它,而是視頻路徑化戳。
2点楼、帶著猜想就去實踐掠廓,使用命令找到發(fā)布視頻的頁面activity名稱,然后去jadx中找到這個類分析intent中的字段悦污,果然能夠得到五個重要的參數(shù)信息:Kdescription,KSightDraftEntrance,KSightThumbPath切端,KSightPath小压,sight_md5怠益。
3、然后有了這五個字段再次猜想每個字段的含義抢呆,然后就直接做了一個簡單的實驗抱虐,在本地存放視頻和封面圖恳邀,然后在代碼中構(gòu)造一個intent,啟動即可乳附。
4赋除、但是在啟動頁面的時候發(fā)現(xiàn)有一個問題就是微信應(yīng)該做了頁面啟動的安全檢查,有些頁面只能在應(yīng)用中其他頁面啟動清焕,所以這里還需要得到微信中的一個頁面。這里就用了聊天界面沃粗,依然使用adb命令獲取聊天頁面類名稱突雪,然后借助Xposed進行這個頁面的onResume方法攔截惹想,然后在攔截之后啟動發(fā)布視頻頁面嘀粱。
5、實驗之后發(fā)現(xiàn)既然可以直接調(diào)用起來娃磺,說明上面的第一步猜想對了,那幾個字段我們也猜對了叫倍,但是這時候發(fā)現(xiàn)點擊發(fā)送的時候出現(xiàn)了失敗現(xiàn)象偷卧。然后分析失敗的原因有兩個:一個是微信服務(wù)器對發(fā)布的視頻做了時長和大小限制,還有一個原因是視頻的MD5碼計算錯了吆倦。我們通過修改本地視頻的大小和時長之后再次實驗發(fā)現(xiàn)還是失敗涯冠,所以可以猜想應(yīng)該是視頻的MD5碼計算錯誤了,微信自己有一個算法逼庞,所以得找到這個算法邏輯蛇更。
6派任、下面就是常規(guī)路線借助Jadx的查找方法調(diào)用功能進行跟蹤,在這個過程中學到一個技巧就是如果發(fā)現(xiàn)一個方法沒有被調(diào)用有可能是因為這個方法是抽象的,具體得去抽象類中定義的地方繼續(xù)跟蹤才有結(jié)果。
7、最終跟蹤到了MD5碼的算法,我們?yōu)榱撕唵魏偌埽苯影涯菐讉€方法拷貝出來改一下直接使用唱较,計算視頻的MD5碼汉形,再次實驗之后發(fā)現(xiàn)發(fā)送成功了概耻。
8春锋、在最后發(fā)現(xiàn)一個問題呐萌,就是微信的很多頁面都叫做LauncherUI,所以如果攔截這個方法的onResume方法然后就發(fā)送視頻的話會出現(xiàn)問題,導致微信啟動失敗莽囤。所以這里就想弄一個事件來控制發(fā)送操作北秽。
9悄泥、在聊天頁面中選中一條消息之后可以彈出一個菜單選項庶骄,決定在這里添加一項來觸發(fā)發(fā)送操作,這里定位到菜單的創(chuàng)建過程中疟暖,用到了前一篇文章中提到的查找資源id方法,但是這里需要注意的是可能微信自己做了資源混淆策略導致這個方法查找id值是失敗的,最后直接使用R.string.xxx這種方式找到了糊饱。
學習到的技巧:
1浑厚、新的逆向突破口,快速定位頁面悴势,使用adb shell dumpsys activity top命令即可。
2扇雕、使用Jadx進行方法跟蹤時候如果發(fā)現(xiàn)沒有結(jié)果亿蒸,可能這個方法是抽象的摩梧,需要找到這個抽象方法最原始的定義的地方繼續(xù)跟蹤即可阿宅。
3蔓腐、微信可能做了資源混淆(或者以后遇到做了資源混淆的apk)的時候窑邦,如果發(fā)現(xiàn)通過public.xml中的id值查找不到結(jié)果瞧筛,可以直接使用R.xxx.xxx進行查找id值。
六、說明
1、其實本文還可以做一個效果倦炒,就是上面在看到聊天界面選中一個消息的時候彈出一個我們自己定義的菜單伍茄,可以獲取到這個消息的類型(視頻,文字片挂,圖片幻林,表情等),以及具體信息音念,直接發(fā)送分享沪饺。而這個就需要解析選中之后的消息內(nèi)容了,當然這個是在本文的項目代碼中已經(jīng)做了闷愤。這里我就不做分析了整葡。
2、因為本文使用了微信6.3.9版本讥脐,所以這里進行攔截的方法有:
com.tencent.mm.ui.LauncherUI的onResume方法遭居。
com.tencent.mm.ui.chatting.ChattingUI.a的構(gòu)造方法啼器,替換fHr變量值。
對于每一個版本混淆之后的類名會發(fā)生變化俱萍,所以不要一味的用本文提到的代碼去實踐端壳,要先看懂所有的逆向流程,具體版本具體分析才是王道枪蘑。
嚴重聲明
本文的目的只有一個损谦,分享更多逆向知識以及逆向技巧,沒有任何商業(yè)目的操作岳颇,如果有人利用本文知識實現(xiàn)任何商業(yè)目的帶來的一切法律責任將由操作者本身負責照捡。與本文和作者沒有任何關(guān)系。也由衷的希望每位讀者能夠秉著技術(shù)學習的態(tài)度閱讀话侧。
七栗精、總結(jié)
本文就詳細介紹完了利用Xposed框架實現(xiàn)微信發(fā)送本地小視頻的功能,對于這個功能個人認為還是有用的瞻鹏,但是對于有些人可能并沒有那么用悲立,因為現(xiàn)在在朋友圈中發(fā)布視頻的人會很少,因為即使發(fā)布了由于流量的限制不會有什么效果的乙漓。然后就是其實微信對于小視頻做了還是有很多限制的级历,而這些限制都是在服務(wù)端進行的,比如視頻的校驗叭披,時長,大小等玩讳。這也就粉碎了小編想發(fā)布一個幾G的電影到朋友圈的夢想涩蜘。最后當然還是希望每位讀者能夠從本文學習到更多的逆向技巧,小編沒寫這樣逆向文章就會很累熏纯,感覺自己被掏空了一樣同诫,所以大家看完一定要記得多多點贊啦,如果有打賞就更好了樟澜!
更多內(nèi)容:點擊這里
關(guān)注微信公眾號误窖,最新技術(shù)干貨實時推送
[圖片上傳中。秩贰。霹俺。(48)]