XPosed外掛自動生成支付寶收款二維碼
接下來,就需要反編譯支付寶的apk,然後看一下這個類的實現,這裡會有兩個問題:
1. 我們都知道二維碼是把一些資訊寫入二維碼圖片中,那麼支付二維碼都需要寫入哪些資訊呢?
2. 知道了寫入資訊,那接下來便是如何生成一個二維碼了。
關於第一個問題,很容易想到,我們要能夠設定備註和金額,所以這兩個資訊也是必須的,其它還需要哪些資訊呢?需要我們看一下具體程式碼,首先就是onCreate方法:剛一進入onCreate,我們就能看到請求了一個UserInfo型別的資料,根據名稱應該知道和使用者資訊相關,再看下面的this.c
程式碼塊(1)中看到從preference中讀取了一些字串型別的變數,從key的名稱看應該是和生成二維碼地址有關的資訊,但是前兩個變數的預設值是空,也就是你第一次進入這個頁面的時候,應該讀取出來是空值,之後某些地方會對他們進行賦值。
程式碼塊(2)是建立了一些服務介面類,從名稱看第一個最符合生成二維碼相關的資訊,如果檢視這個介面CollectMoneyRpc的宣告,會發現猜測是正確的,其中的一些方法就是設定金額,備註等資訊。
這些是設定金額和備註相關的Rpc服務介面,之後的程式碼會用到這些介面方法去設定金額和備註並返回資訊。
繼續下面的分析,之後onCreate程式碼就是獲取UI元件相關變數,設定點選監聽等等,比較重要的肯定是設定金額的按鈕:
其中設定金額的點選監聽事件是內部類bi,整個onCreate還有一個b()方法比較可疑,如果檢視該方法的話,會發現是在主執行緒中最終呼叫了一個a(boolean z, ImageView imageView)的方法,該方法可以明顯看出是用來真正生成二維碼並顯示在ImageView上:
至此,onCreate的流程分析完畢,收穫不小,幾乎所有相關的初始化工作都是在這裡進行了,總結一下看到的程式碼流程:
1. 獲取使用者id,有可能會根據id來設定二維碼中的資訊?
2. 獲取RPC遠端呼叫服務介面。
3. 設定和金額相關的按鈕點選監聽。
4. 呼叫生成二維碼方法生成二維碼,這裡就是你第一次進入該頁面而沒有設定任何金額和備註資訊是現實的預設支付二維碼。
那接下來,我們首先看一下設定金額和備註按鈕點選時,會發生什麼,方法就是上面提到的內部類bi:
直接看onClick方法,有兩個分支,如果PayeeQRActivity.this.j是空值,會啟動PayeeQRSetMoneyActivity,這個Activity肯定是設定金額和備註的activity了,至於this.j是什麼?先讓我們去看一下新的PayeeQRSetMoneyActivity,這個activity啟動的方式是startActivityForResult,那麼當該activity finish的時候,會回撥到PayeeQRActivity的onActivityResult,讓我們來看一下這幾個流程,先來看一下PayeeQRSetMoneyActivity:
首先依舊會請求一個CollectMoneyRpc服務介面,看來是要在這裡實際設定金額,然後會有個一sessionId,這個sessionId具體是什麼值我沒有找到,但是不影響繼續分析,然後根據支付寶設定金額頁面UI來看,最終會點選【確認】按鈕完成設定,也就是圖中的this.e和監聽回撥ct,ct最終的處理方法是該類的a方法:
一個真正使用rpc介面進行非同步呼叫的函式,RpcRunner的兩個引數第一個是非同步呼叫介面,第二個是處理返回結果,都非常簡單,下面那個帶引數的a方法,就是回撥結果呼叫的處理方法,他把處理post到主執行緒,執行cv方法,cv方法很重要,因為他是真正呼叫成功後返回結果的地方:
已經可以看到,結果中包含這些項:codeId,qr_money,beiZhu,qrCodeUrl,qrCodeUrlOffline,從名稱就都可以知道是什麼作用,然後通過呼叫setResult和finish把結果返回給PayeeQRActivity,而在PayeeQRActivity中的onActivityResult,無非就是去讀取這些結果然後生成二維碼,還記得生成二維碼的方法嗎?就是那個b()函式(最終呼叫的是a(boolean z, ImageView imageView)這個方法)。所以最好再來看一下生成二維碼的方法,需要用到什麼東西:
方法邏輯很清晰,用到哪些類,傳入哪些引數,都很清楚了,最後使用ZXingHelper的genCodeImageView方法生成二維碼並更新到ImageView上顯示,具體邏輯就不貼圖展示和分析了,以上就是程式碼層面上的分析,那麼做一下總結:
1. 關於之前說的第一個問題,生成二維碼用到哪些資訊並且怎樣生成,現在很清楚的知道,至少需要金額和備註,然後使用的是Rpc服務介面CollectMoneyRpc去生成二維碼資訊。
2. 關於之前的第二個問題,怎樣生成二維碼影象,這個也很清晰了,就是使用上面的a(boolean z, ImageView imageView)這個方法了。
那麼接下來就是根據這些分析結果來構造hook的條件了
一、先來看如何構造1提到的條件:
我們從前面分析的程式碼知道需要一個CollectMoneyRpc介面,他是通過下面的呼叫來生成的:
關鍵點是這個mMicroApplicationContext是怎麼來的,這個需要追溯到基類BaseActivity中,有個ActivityHelper輔助類,其中又再次使用LauncherApplicationAgent來獲取這個值,這個值是在LauncherApplicaitonAgent建構函式中來構造的,LauncherApplicationAgent又是一個單例類,他有個init方法,一看就是用來做初始化的,我們去hook這個init方法,然後反射拿到成員變數mMicroApplicationContext,直接給出程式碼:
拿到這個CollectMoneyRpc後,我們就可以根據設定金額以及備註引數進行呼叫了,反射從呼叫結果中拿到上面分析的哪些codeId,url,等等:
二、最後構造之前的2提到的條件:
已經說過真正生成二維碼是在哪個a(boolean, ImageView)方法中進行的,只要去按照這個方法中的引數構造,然後在反射使用ZXingHelper這個輔助類去寫二維碼圖片就可以實現了,直接給出程式碼:
三、總結
使用XPosed開發外掛還是新手,需要學習的東西還有很多,這次分析支付寶程式碼,使用的是舊版本的支付寶,最新版支付寶,jadx即使分包載入,我的電腦還是會卡死。。。支付寶程式碼反編譯後,還是很清晰的,混淆的不是很嚴重,但是從中也能看到支付寶的複雜性以及架構上的合理性,研究他的程式碼也能學到很多的東西,估計這個工作我還會持續進行。已經把整個工程上傳到github,文末是地址,如果這個東西不小心觸犯了誰的利益或者影響了軟體安全,可以聯絡我刪除,再次宣告,僅僅是個人學習目的使用,請勿他用,謝謝!!
AlipayQRHook開源地址:https://github.com/wayu002/AlipayQRHook