1. 程式人生 > >Android"掛逼"修煉之行---支付寶螞蟻森林能量自動收取插件開發原理解析

Android"掛逼"修煉之行---支付寶螞蟻森林能量自動收取插件開發原理解析

obj 沒有 dad 51cto dex ble dex文件 set 職業生涯規劃

一、前言
關於支付寶的螞蟻森林能量收取這個非常有重大意義的東西,本人表示非常認同,這個網上也是一直有人覺得馬雲是一個非常有遠見的男人,的確雖然很多人覺得馬雲不會技術但是很能說,但是他說的都慢慢實現了,先不管這個種樹到底能不能落實,馬雲的確在帶領著阿裏幫助世界地球變得越來越美好,而隔壁的企鵝公司暫時不評論。我們如果玩過能量收取都知道他有一個弊端就是每天早起收能量有時候會發現自己的能量被別人全部偷完了很不爽,而且自己在收取的時候也會發現非常的慢和難受,特別在好友比較多的時候。所以針對這麽多問題就開發了一個自動收取的插件,還記得當初偷菜插件嗎?和那個類似可以設置指定時間自動收取和偷取被人的能量的一款插件。
歡迎工作一到五年的Java工程師朋友們加入Java架構開發:854393687
本群提供免費的學習指導 架構資料 以及免費的解答

不懂得問題都可以在本群提出來 之後還會有職業生涯規劃以及面試指導

二、尋找突破口
不多說了接下來就開始分析如何編寫這個插件,我們現在寫插件都是基於Xposed的,而之前說過支付寶有防止Xposed的功能,所以我們得先把這個功能給幹掉,不了解的同學可以點擊這裏進行查看,那有的同學就好奇了為什麽不用輔助功能做模擬點擊呢?這個後面分析你就知道了,沒法用輔助功能進行模擬點擊的。接下來我們先找突破口,這個沒的說一切從我們肉眼獲取,分析界面信息:

技術分享圖片

這裏看到了嗎?非常奇怪的是頁面非常簡單,在我們沒有寫這個插件之前我以為這個頁面很簡單,是一個列表而已,但是不是。就是一個View,其實到後面會知道他是一個WebView而已。所以這裏就解釋了之前有的同學說用輔助功能做模擬點擊,這裏可以發現完全做不了的。所以我們得換個思路找突破口。因為這個頁面不管是一個什麽樣的View,我們只要找到一個核心點即可。那麽這裏在給大家介紹一個尋找突破口的方法了,因為這裏沒有太多的字符串信息,也沒法用搜索大法了。那麽可以查看當前調用了哪些方法來找突破口,很多人想到了我之前寫的icodetools工具了,但是那個工具這裏不適合因為支付寶的包太大了,如果用那個工具會發現頁面完全卡死了,那麽該怎麽辦呢?

這個可以借助DDMS工具自帶的方法調用棧信息了,不過可惜的是這個獲取的前提是這個應用出於可調試狀態,也就是要在DDMS列表中出現。那麽支付寶肯定是不可以調試的,所以讓他出於可調試的我們可以這麽做反編譯支付寶之後修改xml的android:debuggable="true"屬性,然後回編譯即可。這裏有兩個問題在我實際操作的過程中,一個是支付寶反編譯修改添加都沒有問題,但是回編譯可能有問題。那麽可以直接用AXMLEditor工具進行xml的二進制文件修改,然後簽名,可惜的是支付內部有校驗,這裏用了kstools麽有效果,可能是他內部用了其他的簽名校驗邏輯。到這裏我們難道還需要先破解他的簽名校驗嗎?感覺寫個插件得解決很多問題。不過這裏在告訴他家一個小工具就是可以臨時修改設備的系統調試狀態值mprop工具,這個我在之前脫360殼的時候介紹過了,不過這個工具現在有更新版本了。後面給出下載地址。工具使用非常方便:

技術分享圖片

在目錄下找到指定cpu型號的mprop文件拷貝到設備目錄下,然後修改權限為可執行的,然後直接運行三條命令即可:

# 修改init進程中的ro屬性判斷邏輯
/data/local/tmp# ./mprop
# 然後修改系統調試屬性值
/data/local/tmp# setprop ro.debuggable 1
# 恢復init默認邏輯,之後就無法再修改ro屬性了
/data/local/tmp# ./mprop -r

執行這三個命令之後就可以了,然後在查看這個屬性值:

技術分享圖片

這裏已經成功修改了系統的調試狀態為1了,那麽設備中所有的應用都可以出於調試狀態了,即使沒有android:debuggable="true"屬性的應用。所以可以看到這個小工具的作用是非常的大了,而且也看到在逆向操作中如果有一些輔助小工具的話,效率是非常高的,這個工具大家也一定要記住他,在你以後逆向過程中肯定還會用到。然後我們在打開DDMS就可以看到支付寶主進程就出現了:

技術分享圖片

然後我們選擇左上角那個可以獲取當前方法執行的堆棧信息,然後彈出對話框我們選擇下面一個,就是實時的每個方法都獲取,避免丟失關鍵方法,但是這個會有很多大的效率問題也就是點擊確定之後你的支付寶應用會卡死,所以這裏操作的時候是在進入螞蟻森林的頁面那一刻才點擊OK,然後等頁面加載完成就立即點擊結束也是右上角那個按鈕即可:

技術分享圖片

點擊結束之後就生成了trace文件,這個文件路徑在標題欄中可以看到:
技術分享圖片

我們可以保存這個trace文件,然後利用Tracer.jar工具直接打開查看:
技術分享圖片

這裏也是可以直接分析方法棧信息調用的,這個工具是一個同學給我的,我覺得可能沒有DDMS中自帶的好用,但是看個人習慣吧,這個工具也會在後面給出。繼續回到DDMS的界面分析:

技術分享圖片

這裏有一個類似於網絡請求的接口,首先到這裏我們通過這些類的字樣知道那個頁面應該是H5頁面,也就是不是原始本地的頁面,而是一個WebView頁面,通過方法棧來看可能是UCWebView,這個是UC瀏覽器自定義的一個內核webview,因為UC被阿裏收購了用UC也是無可厚非的。那麽先不管他是什麽Webview了,我們之前去看這個方法。

三、逆向分析代碼
我們用jadx直接打開支付寶應用,可惜會發現直接卡死,這裏我用Mac都是的,因為支付寶比×××還狠,已經8個dex文件了,所以還是得分包打開,最後找到了:
技術分享圖片

到這裏我們會發現一個點就是支付寶內部有一個打印日誌的類H5Log,他應該封裝了系統打印日誌的,我們先不管他內部怎麽實現的,直接hook這個類的這個方法,通過一些日誌來快速分析行為和得到我們想要的:
技術分享圖片

然後然後我們通過打印日誌看看效果,因為這裏會很多日誌信息,所以通過它的tag作為過濾條件,這裏的tag是H5RpcUtil:
技術分享圖片

這裏又發現adb logcat 命令還是那麽好用,Windows中用findstr進行過濾即可,在打印信息中會發現一些特殊信息,比如每次執行完成之後的response是一個json數據:

技術分享圖片

而且發現了一個重要的信息就是我們肉眼在頁面看到的好友排行榜信息,先不管把這些信息json格式化一下:

技術分享圖片

到這裏感覺特別激動,通過信息發現正是好友列表信息,而且有一個關鍵字段canCollectEnergy表示這個用戶是否有能量可以收取的,所以到這裏我們發現僅僅通過日誌信息就可以找到突破口了,還找到了關鍵信息。所以對於一個線上的應用每家公司應該在最後的發包階段對應用中所有的日誌代碼全部刪除,這裏是全部刪除而不是僅僅加上一些開關來控制。只有刪除才是最安全的,現在有些安全公司就是這麽做的,內部有一個發包審核和自動刪除應用所有打印日誌代碼,從這裏看如果沒有日誌我們還是需要去分析這個方法的:
技術分享圖片

這個方法最後是返回了一個H5Response類。那麽到這裏我們已經找到返回結果了,那麽這個返回結果執行前是有什麽信息呢?比如參數等,而且這裏看到好友列表默認是分頁,每頁是20個用戶信息,所以後面我們肯定得獲取所有的好友信息,應該有個參數來進行操作,所以為了更加直觀看數據,直接hook這個H5RpcUtil.rpcCall方法,這個方法有十幾個參數,其中有一個坑就是JSONObject格式的,其實他是阿裏的fastjson包的對象,導致操作過程中始終沒hook成功:
技術分享圖片

所以這裏如果有的同學在使用Xposed進行hook一個方法,但是沒有hook成功,最快找到原因就是把這個hook的代碼外面加一個try...catch,然後catch到異常信息打印出來即可。如果有錯誤直接就可以看到原因了,不然很費勁去找hook失敗的原因。然後我們在運行看看結果:

技術分享圖片

我們進行下拉獲取更多好友列表信息發現打印的參數信息,裏面的第二個參數的確是攜帶了分頁信息,每頁是20條,又每頁的起始點,而且第一個參數其實是命令類型,後面還會有獲取用戶所有可以收取的能量以及收取能量的命令。那麽到這裏我們已經成功的獲取到所有好友信息,並且可以通過解析response的json數據獲取哪些用戶可以有能量收取,那麽怎麽獲取到這個用戶所有的可以收取的能量信息呢?因為有的同學可以有很多能量收取的,這個直接點擊這個用戶進入他的螞蟻森林頁面即可,這時候依然是通過觀察日誌信息,首先還是入口參數信息:

技術分享圖片

這裏看到每次進入一個用戶的能量頁面,都會執行這四條命令,而且其中有三條命令會攜帶當前用戶id,那麽用戶的id信息我們在之前列表返回的json中可以拿到了。再看看能量返回的json數據:

技術分享圖片

還是進行json格式化:
技術分享圖片

果不其然返回的json中會表示這個用戶所有的能量信息,其中的collectStatus字段表示這個能量是否可以收取,那麽我們把這個json進行解析保存可以收取的能量id信息,接下來有了這些id信息,那麽就開始收取了,我們在手動的收取一個能量看看打印的參數信息和返回結果信息:

技術分享圖片

入口參數中的確包含了當前收取的能量id和當前用戶信息,而這兩個參數我們現在已經都能獲取到了,看看收取之後的返回信息:

技術分享圖片

依然去json格式化:
技術分享圖片

返回信息中有是否成功的字段和成功收取的能量數值,這個我們可以解析來標識此次收取是否成功了。

好了到上面我們已經全部分析完了能量獲取流程,我們寫的插件大致操作流程也很簡單,第一次進入螞蟻森林頁面就會獲取第一頁的好友信息,然後我們通過修改頁數起始點進行分頁獲取所有好友信息,然後解析字段獲取有能量收取的用戶id信息進行保存,然後在依次通過用戶id信息獲取每個用戶可以收取的能量id信息進行保存,最後在利用之前的用戶id和能量id信息進行收取能量即可。整個過程全部通過調用上面的那個關鍵方法:H5RpcUtil.rpcCall,因為這個方法是static的,所以調用它很簡單,只要構造具體參數信息即可,而在上面的三個操作中獲取好友列表信息、獲取指定用戶的可收取能量信息、收取能量;這三個步驟打印的參數來看,現在唯一需要搞定的是那個自定義類型的H5PageImpl類:

技術分享圖片

我們看看怎麽才能獲取到這個對象實例,而且我們也發現這個對象實例在每次進入一個新的頁面都是不一樣的,全局搜這個類:
技術分享圖片

這裏發現了很多地方調用,但是有一個H5Fragment最值得懷疑,為什麽呢?因為我們可以看到只有Activity和Fragment可以展示頁面的載體。我們現在看到的是螞蟻森林頁面,又在H5Fragment中搜到他了,當然最值得懷疑和查看了,點擊去查看即可:

技術分享圖片

到這裏我們就要有點應用開發技巧了,Android中的Fragment是無法單獨展示的,一般的用法都是一個Activity中的FragmentManager進行管理展示的,因為可能會有多個Fragment的,所以我們可以先看看當前activity是啥,直接用命令 adb shell dumpsys activity top:
技術分享圖片

這個Activity是H5Activity,可以看到他的當前Fragment的構造參數信息,我們去查看這個activity信息:
技術分享圖片

果不其然有一個類似於FragmentManager的類,點進去進行查看:

技術分享圖片

這裏是每次添加新的H5Fragment類的方法,我們直接hook然後把當前的H5Fragment打印出來看看:
技術分享圖片

通過打印日誌發現每次進入一個頁面這個H5Fragment都是一個新對象,那麽我們知道上面調用rpcCall方法的參數H5PageImpl可以在H5Fragment中獲取到,所以這裏我們就需要這麽做了,就是攔截這個pushFragment方法,然後保存當前最頂端的頁面H5Fragment,然後用反射獲取對應的H5PageImpl對象,最後在調用rpcCall方法執行命令即可,具體這幾個類的關系是什麽樣的,繼續看一下代碼:

技術分享圖片

首先是H5Fragment類中有一個變量是H5ViewHolder類型的變量a:

技術分享圖片

然後是H5ViewHolder類中的有個變量h是保存當前的H5PageImpl類型:
技術分享圖片

而H5PageImpl內部有一個H5WebView類型變量f:

技術分享圖片

看到這裏設置了很多WebView的回調接口信息,所以到這裏就大致清楚螞蟻森林或者說支付寶其他H5頁面的層級關系是:H5Activity.fragmentManager->H5Fragment->H5ViewHolder->H5PageImpl->H5WebView;然後利用webview進行本地交互操作了。

四、編寫Hook代碼
有了上面的分析,這裏繪制了一張圖片,全世界唯獨一份的,以後大家分析支付寶H5頁面都可以按照這個流程來即可:

技術分享圖片

有了這張圖我們對於寫插件那就很簡單了,下面就簡單來分析一下代碼吧,首先我們第一次進入會有兩個返回信息,一個是當前第一頁的好友信息,還有一個是自己的能量信息,所以需要解析兩個,而對於自己的能量直接收取即可,我們可以hook上面的rcpCall方法來獲取每次頁面返回的response信息:
技術分享圖片

然後自動獲取所有的好友列表信息進行保存:
技術分享圖片

這裏需要分頁請求到所有的好友信息保存,請求完成了然後在遍歷所有用戶獲取可以收取的能量信息,發送獲取分頁好友信息的命令也很簡單:

技術分享圖片

查看指定給用戶可以收取能量的命令:

技術分享圖片

開始自動收取能量的命令:

技術分享圖片

我們利用之前分析的那幾個類關系,保存當前的H5Fragment:

技術分享圖片

然後利用反射獲取對應的H5PageImpl對象,最後調用rpcCall方法發送命令請求:

技術分享圖片

還有部分代碼這裏不在詳解了,整個流程貫通之後接下來就是見證奇跡的時刻:

技術分享圖片

看到了只需要幾秒鐘就可以把所有好友的所有能量一偷殆盡,不給自己留下一絲絲的遺憾:
技術分享圖片

而有了這個之後,我們還需要寫個工具就是經過多年偷取能量經驗,每天偷取能量的時間段最佳是早上7.30,中午12.00,晚上5.30,所以我們在這三個時間段自動打開螞蟻森林頁面即可。代碼這裏不在詳細介紹了。到這裏我們就把插件開發完成了。

五、技術總結
從上面的分析可以看到,本文涉及到的技術還是很多的,所以這裏就來總結一下,有時候寫一個插件結果不重要,重要的是在這個過程中我們發現了什麽學到了什麽:

第一、在使用以往的突破口方法(字符串搜索大法,UI界面元素分析等)方法無果的時候,記住一個最新的方法就是獲取當前應用執行片段的所有方法堆棧信息來獲取突破口方法更加便捷。
第二、因為需要使用DDMS獲取當前應用執行片段的方法堆棧信息,但是需要這個應用處於調試狀態,為了不進行反編譯和回編譯操作繁瑣,可以利用mprop工具直接修改系統的調試狀態值。
第三、任何一個應用如果利用頁面H5進行展示功能,那麽他肯定有一個和本地交互的JS對應方法,一般最直接的方法是找到這個頁面的WebView,然後hook他的addJavascriptInterface方法獲取本地JS交互的對象,或者是hook每次都會加載url的幾個回調方法比如WebViewClient接口,或者是WebViewChromeClient等。
第四、支付寶可能為了安全起見或者是性能更或者是動態更新的原因來把很多頁面做成H5了,不得不佩服他把H5頁面做的和本地頁面幾乎無差別還是很厲害的,至少我一開始因為是本地頁面。所以以後分析支付寶的其他頁面如果發現當前的activity是H5Activity的話,那麽就是H5頁面進行加載的。
還是那句話每次寫插件是為了更好的學習更多逆向技巧和思路,有時候結果不重要,重要的是過程,而寫了這麽多插件唯獨感覺這個插件最有實際用途,現在每天用插件收取能量真的是太方便了

Android"掛逼"修煉之行---支付寶螞蟻森林能量自動收取插件開發原理解析