Android支付寶螞蟻森林能量自動收取外掛開發原理解析
阿新 • • 發佈:2018-12-30
轉發一篇高技術含量的文章,原文網址為:https://www.52pojie.cn/thread-794312-1-1.html
一、前言
關於支付寶的螞蟻森林能量收取這個非常有重大意義的東西,本人表示非常認同,這個網上也是一直有人覺得馬雲是一個非常有遠見的男人,的確雖然很多人覺得馬雲不會技術但是很能說,但是他說的都慢慢實現了,先不管這個種樹到底能不能落實,馬雲的確在帶領著阿里幫助世界地球變得越來越美好,而隔壁的企鵝公司暫時不評論。我們如果玩過能量收取都知道他有一個弊端就是每天早起收能量有時候會發現自己的能量被別人全部偷完了很不爽,而且自己在收取的時候也會發現非常的慢和難受,特別在好友比較多的時候。所以針對這麼多問題就開發了一個自動收取的外掛,還記得當初偷菜外掛嗎?和那個類似可以設定指定時間自動收取和偷取被人的能量的一款外掛。
二、尋找突破口
不多說了接下來就開始分析如何編寫這個外掛,我們現在寫外掛都是基於Xposed的,而之前說過支付寶有防止Xposed的功能,所以我們得先把這個功能給幹掉,不瞭解的同學可以點選這裡進行檢視,那有的同學就好奇了為什麼不用輔助功能做模擬點選呢?這個後面分析你就知道了,沒法用輔助功能進行模擬點選的。接下來我們先找突破口,這個沒的說一切從我們肉眼獲取,分析介面資訊:
這裡看到了嗎?非常奇怪的是頁面非常簡單,在我們沒有寫這個外掛之前我以為這個頁面很簡單,是一個列表而已,但是不是。就是一個View,其實到後面會知道他是一個WebView而已。所以這裡就解釋了之前有的同學說用輔助功能做模擬點選,這裡可以發現完全做不了的。所以我們得換個思路找突破口。因為這個頁面不管是一個什麼樣的View,我們只要找到一個核心點即可。那麼這裡在給大家介紹一個尋找突破口的方法了,因為這裡沒有太多的字串資訊,也沒法用搜索大法了。那麼可以檢視當前呼叫了哪些方法來找突破口,很多人想到了我之前寫的icodetools工具了,但是那個工具這裡不適合因為支付寶的包太大了,如果用那個工具會發現頁面完全卡死了,那麼該怎麼辦呢? 這個可以藉助DDMS工具自帶的方法呼叫棧資訊了,不過可惜的是這個獲取的前提是這個應用出於可除錯狀態,也就是要在DDMS列表中出現。那麼支付寶肯定是不可以除錯的,所以讓他出於可除錯的我們可以這麼做反編譯支付寶之後修改xml的android:debuggable="true"屬性,然後回編譯即可。這裡有兩個問題在我實際操作的過程中,一個是支付寶反編譯修改新增都沒有問題,但是回編譯可能有問題。那麼可以直接用AXMLEditor工具進行xml的二進位制檔案修改,然後簽名,可惜的是支付內部有校驗,這裡用了kstools麼有效果,可能是他內部用了其他的簽名校驗邏輯。到這裡我們難道還需要先
在目錄下找到指定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應用安全防護和逆向分析」
成品和原始碼分享~~~ 安裝環境:無需root VirtualXposed 0.13.0 https://vxposed.com/ 支付寶 10.1.35 【VirtualXposed 第一次打支付寶時間比較長】 原始碼地址:https://github.com/yongjun925/autocollectenergy 外掛下載連結: https://pan.baidu.com/s/1e-neHBmoU08XF-hX3hvaCg 提取碼: rk2v 我在小米5 刷rom自帶的xposed裡使用無效,有知道的大神求告知! |