Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android實現微信朋友圈發本地視頻功能

Android實現微信朋友圈發本地視頻功能

編輯:關於Android編程

一、前言

前一篇文章已經詳細介紹了如何使用Xposed框架編寫第一個微信插件:搖骰子和猜拳作弊器 本文繼續來介紹如何使用Xposed框架編寫第二個微信插件,可以將本地小視頻發布到朋友圈的功能。在這之前我們還是要有老套路,准備工作要做好,這裡還是使用微信6.3.9版本進行操作,准備工作:

1、使用apktool工具進行反編譯,微信沒有做加固防護,所以這個版本的微信包反編譯是沒有任何問題的。

2、借助於可視化反編譯工具Jadx打開微信包,後續幾乎重要分析都是借助這個工具來操作的。

二、猜想與假設

做好上面這兩步之後,加上我們在之前的那個編寫插件的基礎之上,我們本次操作就應該非常簡單了,還記得之前的插件的突破口是啥嗎?看過文章的同學應該了解通過分析界面的控件來獲取到id值,然後全局搜索得到的突破口,那麼本文其實可能不需要這個方式了,而是另外一種方式,下面來詳細介紹一下。在這之前我們先來看看微信正常的發布小視頻到朋友圈的方式,會跳轉到這個發布頁面:

那麼我們又要開始大膽的猜想了:

首先這個頁面有的元素:標題,小視頻,地理位置等信息,而這些信息應該會在請求發布的時候攜帶到服務器上。這個有點類似於小文件的上傳功能。所以這個視頻的文件是如何得到的。那麼可以得到的假設:這個頁面是一個Activity頁面,可能從其他頁面跳轉過來的,同時會把這些元素信息通過intent攜帶過來,而小視頻是個文件,所以應該會攜帶文件的名稱。

三、逆向分析

有了這猜想之後,咋們就可以開始操作了,首先得到這個頁面的activity名稱,這個比較簡單了,直接使用一個命令即可:adb shell dumpsys activity top

看到這個頁面的名稱是SightUploadUI,我們借助Jadx反編譯微信之後,找到這個類:

我們直接看onCreate方法中有沒有對intent參數解析操作,或者我們可以在這個類中全局搜一下getIntent字段,也可以快速得到解析的地方:

看到第一個字段Kdescription,從字段的名稱來看應該是描述信息,而從下面的代碼setText調用更可以確認了這個就是標題信息。我們繼續查找:

又發現了一個字段KSightDraftEntrance,這塊代碼就有點多了,他是一個boolean類型,所以先不管了,因為後面即使是嘗試的話也就兩次操作,一次false一次true。不礙事的!可是到這裡我們在也搜不到其他字段了,但是這個就和我們的預期不一樣了,還差幾個元素信息呢?最重要的視頻文件路徑沒有,所以這個就要想起在onCreate方法中有一個ae類初始化的時候把當前activity傳遞進去了,那麼可能他內部繼續進行了參數解析,我們可以進去查看一下:

果然在他內部還有三個字段解析,分別是:KSightThumbPath,KSightPath,sight_md5;而從字段命名上來看猜想這個應該就是和視頻信息相關的字段了。這裡只要有Android開發經驗的同學應該可以猜想:KSightPath字段是短視頻路徑,KSightThumbPath是短視頻的默認封面圖,sight_md5是短視頻的校驗值。到這裡其實我們已經感覺快成功了,得到了這五個參數,那麼我們可以直接嘗試了操作了:

在本地存放一個短視頻,封面圖片,然後計算短視頻的md5碼,最後通過intent來啟動這個頁面即可。先不管後面的上傳過程了,咋們可以先試驗能成功跳轉到這個頁面展示本地小視頻功能。

可惜到這裡我們有一個問題,就是怎麼獲取這個啟動頁面的activity呢?也就是用哪個activity來啟動他呢?有的同學可能這麼干?直接簡單明了的編寫一個小程序,然後用小程序的activity啟動這個頁面。這個猜想是可以的,不過我沒嘗試,因為我想微信做了activity啟動安全防護的,不可能在其他應用中可以啟動微信中的任意一個頁面。所以這裡我就沒費那勁了。而是想到用微信自己的頁面來啟動他,那麼如何獲取到微信的一個其他頁面呢?這個也簡單。咋們可以打開一個聊天頁面,繼續使用adb shell dumpsys activity top 命令查看頁面:

好了,就是這個LauncherUI頁面了,那麼知道這個頁面下面怎麼獲取這個對象呢?這時候就需要借助Xposed框架進行Hook了,代碼如下:

看到了吧,代碼很簡單的,我們hook頁面的onResume方法,因為這時候頁面已經初始化完成了是整個Activity生命周期中的比較晚的一個方法了,所以攔截他就可以了。然後在攔截回調用使用MethodHookParam的thisObject屬性就可以得到這個方法所屬的對象了,也就是LauncherUI類型了。

好了既然現在微信啟動頁面也有了,下面就簡單了,直接構造上面的五個參數得到intent直接啟動:

代碼很簡單,咋們直接運行模塊,然後重啟設備生效,然後打開微信界面瞬間看到效果了:

果然跳轉到這個頁面了,也就是說我們的猜想對了,下面我們點擊發送,會發現發送失敗了:

原因可能有兩個:

1、沒有弄對視頻文件的MD5碼

2、視頻格式不符合服務器接受的要求:視頻的長度和視頻的大小

關於第二個原因,其實網上有答案,就是微信這個發布的小視頻長度不能超過15s,大小不能超過1M。所以這裡我就把本地視頻做成了符合這兩個標准的,再次操作依然是這樣的失敗效果。那麼就有可能猜想是視頻的MD5碼校驗出問題了,上面看到代碼中我傳入的MD5碼是aaa,我是為了方便沒去弄。但是這裡就必須寫了。獲取文件的MD5碼這裡就不多解釋了,不過可惜的是,MD5弄成文件的還是失敗。那麼這時候就猜想他或許不是真正意義上的MD5值了,可能加上了他自己的一個算法了。所以又來了一個問題,如何得到這個算法呢?

這時候就需要跟蹤代碼看看其他頁面跳轉到這個頁面攜帶過來的MD5碼是什麼呢?我們可以這麼干就是全局搜索那五個字段中的任意一個即可,這裡在Jadx中全局搜索:sight_md5

我們點擊進入查看方法:

繼續查找這個方法在哪被調用了:

咋們繼續點擊進入查看:

這裡看到了倒數第二個參數就是那個MD5碼值,我們在全局搜一下這個變量在哪裡被使用到了:

看到這裡有賦值的地方,點擊進入查看:

然後查看這個kbVar變量,在上面的代碼中:

這裡我們可以先看看這個kb類的定義:

這裡的aFL就是那個MD5碼值了,我們繼續上面的那個a方法查看哪些地方調用了,不過查找是沒有效果的,因為這個方法可能是抽象的,所以咋們得找到他抽象定義的地方,在上面就是一個抽象類c:

然後進入c類查看抽象方法a:

然後查找a方法調用的地方:

繼續查看這個方法的調用地方:

這時候我們多看一下,這個方法所屬的類是個單例:

那麼繼續查看這個g方法被調用的地方,或者全局搜一下jJA這個變量的使用也可以的:

又回到了剛剛的那個MainSightContainerView類了,這裡看到了賦值的地方了,而且是給aFL字段賦值的,這個就是上面看到kb類中的字段值,這裡依然調用了一個方法計算MD5碼值,而且傳入的參數是視頻路徑:

這裡首先判斷當前視頻文件是否存在,然後在進行文件操作:

真正加密算法是在a方法中,這裡也可以看到因為計算文件的MD5碼是耗時的,所以這裡做了一個優化,只會計算文件的前100KB數據:

哎,到這裡終於真相大白了,看到他的確是用了MD5算法,只是在後面自己又高了一個簡單的算法。所以這裡我們為了簡單,可以直接把這三個方法拷貝到我們的Xposed模塊代碼中:

然後在把之前的intent中的sight_md5字段值替換一下:

這時候咋們在之前的攔截的onResume方法中再次調用,然後重啟設備生效,點擊發送:

哈哈,到這裡可以看到,發送成功啦啦,好興奮呀。終於實現了這個功能。以後可以盡情的裝逼了。

注意:在上面我們定位一個方法在哪些地方被調用,有時候可能找不到,但是不代表這個方法真的沒有被調用,而是因為這個方法是抽象的,直接跟蹤可能沒有效果,這時候就需要去抽象方法的定義地方去全局搜索就可以了。

四、添加發布事件

但是到這裡我們是否就結束了本次操作了,其實並沒有,因為有的同學在上面的實踐中會發現,有時候微信會打不開,一打開就閃退,其實這個原因是我們雖然攔截了LauncherUI頁面的onResume方法,但是這個頁面比較獨特的是微信中的首頁也是他,所以這就有可能出現你剛剛要打開微信頁面,有些初始化操作沒做完,而這時候你就立馬跳轉到SightUploadUI頁面去發布視頻會出現問題。所以這裡就存在一個發布視頻的觸發時機,為了更好的體驗效果,我們決定做到更人性化,就是添加一個菜單可以點擊的時候再去觸發發布視頻邏輯。那麼又來了一個問題就是如何在微信中添加一個我們自己想要的菜單?這個我覺得比上面那個還簡單點,我們准備在聊天界面中選中一條消息之後彈出的菜單中加一項子菜單:

就是在這裡,我們加一項,有的同學覺得這個可能會比較麻煩,其實很簡單,我們只要找到這個菜單定義的地方即可。直接看看步驟:想得到這個菜單定義地方很簡單,咋們先去反編譯之後的values/strings.xml文件中找到這個字符串的定義:

得到他的id值是ne,然後在Jadx中全局搜索:R.string.ne

注意:這裡可能有的同學會好奇,在之前一篇文章中不是得去public.xml中找到ne對應的id整型值,然後全局搜索嗎?這裡可能和微信做了資源混淆工作有關,開始的時候通過整型值死活沒找到,最後無意間用了這種方式找到了。所以以後我們可以先用標准方案去public.xml中找到id對應的整型值,如果沒找到,在使用這種方式進行查找即可。

上面找到這個字符串定義的地方,直接點擊進入即可:

這裡可以看到了,使用了系統提供的ContextMenu類進行菜單定義的,這裡就需要你對這個類了解了。後面添加菜單就必須用add方法來進行添加了,不過這個方法還是比較簡單的,參數都比較好理解主要是菜單組的id值,菜單自身的id值,菜單名稱,然後在設置點擊事件即可。下面我們繼續看這個方法在哪裡被調用了:

不過這個方法跟蹤沒有結果,猜想他可能是一個抽象方法,所以就去他定義的地方進行查看y類:

果然是一個抽象方法,這裡在跟蹤就可以了:

點擊查找結果:

繼續看這段代碼之前的方法和類定義:

這裡有一個變量fHr,也就是菜單創建的回調接口,在往上面查看:

到這裡就看明白了,在ChattingUI有一個內部靜態類a,在這個類內部開始創建菜單,然後定義一個fHr變量代表菜單創建的回調接口類型,然後在onCreateContextMenu回調方法中進行子菜單添加工作。

好了上面就分析了菜單的創建代碼,下面咋們就開始操練了,還是得借助Xposed進行攔截了,這次攔截哪個呢?咋們可以攔截ChattingUI這個類的靜態內部類a,然後我們自己在定義一個創建菜單的接口,去替換fHr變量的值,最後我們只要在我們的回調接口中操作即可:

這裡攔截代碼也是比較簡單的,主要是定義我們自己的回調接口,然後在替換fHr值即可,再來看看接口定義:

這裡才是最關鍵的代碼了,在onCreateContextMenu回調方法中創建一個菜單,但是這裡有一個問題就是怎麼獲取到菜單組的id值,這個我們還得回到開始的那個添加菜單代碼:

看到,這裡他是先通過view的tag得到dd對象,然後在調用position屬性即可,那麼我們操作也就簡單了,繼續使用反射機制就可以得到這個值了。代碼如上。

代碼編寫完之後再次運行之後,重啟設備生效,打開一個聊天室然後選中一條消息:

哈哈看到這個菜單選項了,咋們點擊之後就可以跳轉到發布頁面了:

五、知識概要與技巧總結

好了到這裡我們就完成了本文提到的如何將本地小視頻發布到朋友圈功能實現,下面來總結一下本文的實現步驟以及能夠學習到的逆向技巧:

1、首先猜想微信發布視頻的頁面中的幾個重要元素信息:標題,視頻信息,地理位置等,然後這些信息可能在其他頁面通過intent傳遞過來的,那麼應該不可能傳遞整個視頻數據,而是視頻路徑。

2、帶著猜想就去實踐,使用命令找到發布視頻的頁面activity名稱,然後去jadx中找到這個類分析intent中的字段,果然能夠得到五個重要的參數信息:Kdescription,KSightDraftEntrance,KSightThumbPath,KSightPath,sight_md5。

3、然後有了這五個字段再次猜想每個字段的含義,然後就直接做了一個簡單的實驗,在本地存放視頻和封面圖,然後在代碼中構造一個intent,啟動即可。

4、但是在啟動頁面的時候發現有一個問題就是微信應該做了頁面啟動的安全檢查,有些頁面只能在應用中其他頁面啟動,所以這裡還需要得到微信中的一個頁面。這裡就用了聊天界面,依然使用adb命令獲取聊天頁面類名稱,然後借助Xposed進行這個頁面的onResume方法攔截,然後在攔截之後啟動發布視頻頁面。

5、實驗之後發現既然可以直接調用起來,說明上面的第一步猜想對了,那幾個字段我們也猜對了,但是這時候發現點擊發送的時候出現了失敗現象。然後分析失敗的原因有兩個:一個是微信服務器對發布的視頻做了時長和大小限制,還有一個原因是視頻的MD5碼計算錯了。我們通過修改本地視頻的大小和時長之後再次實驗發現還是失敗,所以可以猜想應該是視頻的MD5碼計算錯誤了,微信自己有一個算法,所以得找到這個算法邏輯。

6、下面就是常規路線借助Jadx的查找方法調用功能進行跟蹤,在這個過程中學到一個技巧就是如果發現一個方法沒有被調用有可能是因為這個方法是抽象的,具體得去抽象類中定義的地方繼續跟蹤才有結果。

7、最終跟蹤到了MD5碼的算法,我們為了簡單,直接把那幾個方法拷貝出來改一下直接使用,計算視頻的MD5碼,再次實驗之後發現發送成功了。

8、在最後發現一個問題,就是微信的很多頁面都叫做LauncherUI,所以如果攔截這個方法的onResume方法然後就發送視頻的話會出現問題,導致微信啟動失敗。所以這裡就想弄一個事件來控制發送操作。

9、在聊天頁面中選中一條消息之後可以彈出一個菜單選項,決定在這裡添加一項來觸發發送操作,這裡定位到菜單的創建過程中,用到了前一篇文章中提到的查找資源id方法,但是這裡需要注意的是可能微信自己做了資源混淆策略導致這個方法查找id值是失敗的,最後直接使用R.string.xxx這種方式找到了。

學習到的技巧:

1、新的逆向突破口,快速定位頁面,使用adb shell dumpsys activity top命令即可。

2、使用Jadx進行方法跟蹤時候如果發現沒有結果,可能這個方法是抽象的,需要找到這個抽象方法最原始的定義的地方繼續跟蹤即可。

3、微信可能做了資源混淆(或者以後遇到做了資源混淆的apk)的時候,如果發現通過public.xml中的id值查找不到結果,可以直接使用R.xxx.xxx進行查找id值。

六、說明

1、其實本文還可以做一個效果,就是上面在看到聊天界面選中一個消息的時候彈出一個我們自己定義的菜單,可以獲取到這個消息的類型(視頻,文字,圖片,表情等),以及具體信息,直接發送分享。而這個就需要解析選中之後的消息內容了,當然這個是在本文的項目代碼中已經做了。這裡我就不做分析了。

2、因為本文使用了微信6.3.9版本,所以這裡進行攔截的方法有:

com.tencent.mm.ui.LauncherUI的onResume方法。

com.tencent.mm.ui.chatting.ChattingUI.a的構造方法,替換fHr變量值。

對於每一個版本混淆之後的類名會發生變化,所以不要一味的用本文提到的代碼去實踐,要先看懂所有的逆向流程,具體版本具體分析才是王道。

嚴重聲明

本文的目的只有一個,分享更多逆向知識以及逆向技巧,沒有任何商業目的操作,如果有人利用本文知識實現任何商業目的帶來的一切法律責任將由操作者本身負責。與本文和作者沒有任何關系。也由衷的希望每位讀者能夠秉著技術學習的態度閱讀。

七、總結

本文就詳細介紹完了利用Xposed框架實現微信發送本地小視頻的功能,對於這個功能個人認為還是有用的,但是對於有些人可能並沒有那麼用,因為現在在朋友圈中發布視頻的人會很少,因為即使發布了由於流量的限制不會有什麼效果的。然後就是其實微信對於小視頻做了還是有很多限制的,而這些限制都是在服務端進行的,比如視頻的校驗,時長,大小等。這也就粉碎了小編想發布一個幾G的電影到朋友圈的夢想。最後當然還是希望每位讀者能夠從本文學習到更多的逆向技巧,小編沒寫這樣逆向文章就會很累,感覺自己被掏空了一樣,所以大家看完一定要記得多多點贊啦,如果有打賞就更好了!

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved