基礎知識

本章為您介紹安卓自動化相關的基礎知識,請務必閱讀本章內容,後面不再贅述。安卓自動化與常規網頁自動化存在很大區別,但也有許多共性。在常規網頁自動化中,可以簡單地透過 F12 開發者工具查看網頁佈局、元素 ID 等資訊,進而使用 XPath 獲取元素進行點擊、等待等操作。安卓環境邏輯類似,您也可以透過名為選擇器的東西來選定元素並進行點擊、判斷等操作,因此不必擔心難以入門。

移動與網頁自動化的共性與區別

移動端的自動化與網頁自動化之間有許多共性,當然也有不少區別。我們以 Selenium 為例:通常,使用 Selenium 進行網頁控制需要三樣東西:其一,瀏覽器;其二,WebDriver;其三,Selenium。移動端同理:手機相當於瀏覽器,FIRERPA 相當於 WebDriver,FIRERPA 的 Python 用戶端程式庫 lamda 相當於 Selenium,並且它們的目標一致,都是執行模擬使用者操作,實現測試、資料蒐集或任務自動執行。它們都是透過腳本驅動、對元素進行定位、點擊、截圖、判斷等操作。這麼看,二者還是挺相像的。

但它們也有所不同。首先,移動端自動化需要一台手機和一台電腦,而網頁自動化在您自己的電腦上即可進行。其次,它們使用的並非同一套方案。網頁端常見工具如 Selenium、Puppeteer、Playwright;移動端則通常是 FIRERPA、AutoJS、Appium、uiautomator2 等。

對於網頁端,常見的定位方式主要是基於 HTML DOM 結構的 XPath 或 CSS 選擇器,元素層級相對直觀。而對於移動端,常見的定位方式則是選擇器;當然,安卓應用介面也使用 XML 佈局,您也可以透過 XML 進行 XPath 選擇。通常,網頁端自動化無需過多考慮相容性問題,大部分情況下透過固定瀏覽器版本和啟動解析度即可解決裝置差異帶來的相容性問題。但對於安卓端,由於品牌、型號、螢幕大小、系統版本等不同,可能對自動化程式碼的相容性產生影響。不過也請不必擔心,雖然有影響,但程度有限。

各種自動化工具的區別

上文提到,我們舉例的幾種安卓端常用自動化工具之間也有很大區別。首先表明立場:FIRERPA 是所有自動化工具中最穩定、功能最全、最強大,也最適合專案化管理和應用的。

備註

我們的立場並非偏見,而是基於 6 年來不斷的探索與優化而形成。您走過的路線、踩過的坑,我們基本都經歷過。

常見的 AutoJS 及衍生產品屬於自身控制自身類,需要在裝置上安裝 APK 並透過 JavaScript 編寫腳本進行操作。AutoJS 通常只能進行自動化操作,優點是適合新手或業餘使用,入門門檻低。但其本身的設計不適合大規模的腳本控制、管理與更新,處於去中心化、無管理的狀態,無法進行精確的大規模控制。

自動化基本流程

通常您需要先預研方案:是只進行常規自動化,還是在自動化的同時獲取應用執行資料?通常有兩種資料獲取方案:其一,透過中間人進行 HTTP/S 通訊截獲;其二,透過 Hook 進行資料截獲。中間人方式較為簡單,適合常規使用,但對部分應用可能無效。Hook 方案需要大量逆向知識,入門困難,不適合新手,適用於邊緣場景。

中間人資料獲取

中間人方案較簡單,您只需在文件中找到 安裝中間人憑證設定代理 的相關內容,配合 mitmproxy 即可實現。若不清楚,還可參考官方 startmitm.py 腳本,其中已為您寫好所有邏輯,可以直接複製或複用。

Hook 資料獲取

Hook 方案需要具備初級及以上的逆向能力,若此前未了解,可暫不考慮。總的來說,Hook 方案是透過編寫 Frida 腳本,鉤住相關函式呼叫,獲取參數或返回值並提交,然後注入應用等流程。您可在 使用 Frida 上報資料 章節了解簡單 Demo 和使用方法。

自動化程式碼

自動化程式碼也是不可或缺的,因為您需要透過自動化來觸發相關邏輯。編寫自動化程式碼通常遵循以下流程。首先,打開 FIRERPA 的遠端桌面,您會看到如下介面。

遠端桌面

現在,打開您想要自動化操作的 APP,隨後點擊遠端桌面右上角的「小眼睛」圖示,您會看到如下介面。此時選擇要操作的元素,點擊即可查看元素資訊。

小撇步

當然也能用程式碼打開,這些後面都會講的。

選擇元素

您可以看到右側的元素資訊,例如 text、resourceId 等。假設我們要點擊這個元素,可編寫如下程式碼,其含義是「點擊 text 為『同意』的元素」。

d(text="同意").click()

備註

這只是示例,選擇器寫法有很多,這裡只介紹最簡單的一種。

好了,最簡單的寫法您已經了解了。現在,請編寫 if/else 等控制邏輯,配合 exists 等介面,您就可以實現一整套自動化操作流程了。看吧,並沒有那麼難。

介面佈局檢視

正常情況下,編寫自動化程式碼離不開介面佈局檢視,這也是獲取選擇器條件的唯一途徑。首先,在瀏覽器中打開裝置的遠端桌面。隨後點擊遠端桌面右上角的眼睛圖示進入佈局檢視,此時可以點擊左側螢幕上的虛線框查看對應元素資訊,將其屬性作為選擇器的參數。再次點擊眼睛圖示將關閉佈局檢視。請注意,佈局檢視不會隨頁面變化自動重新整理,它始終定格在您進入檢視那一刻的螢幕佈局;如需重新整理,請手動按下快捷鍵 Ctrl + R

檢視元素

提示

您也可以在佈局檢視介面按下 Tab 鍵來遍歷查看所有元素。

介面選擇器

介面選擇器(Selector)用於操作安卓元素,您可以將其理解為 XPath 規則,雖然機制不同,但用途相似。在 FIRERPA 中,選擇器類為 Selector,多數情況下您無需直接接觸它。在上文中,您已見過它的用法。完整的 Selector 包含如下可選參數。

比對類型說明
text文本完全比對
textContains文本包含比對
textStartsWith文本起始比對
className類名比對
description描述完全比對
descriptionContains描述包含比對
descriptionStartsWith描述起始比對
clickable可以點擊
longClickable可以長按
scrollable可滾動
resourceId資源ID比對

大多數情況下,僅使用 resourceId、text、description、textContains 等作為參數。如果元素存在正常的 resourceId,應優先使用它作為 Selector,如 d(resourceId="com.xxx:id/mobile_signal");否則可使用 text,如 d(text="點擊進入"),或者更模糊一點 d(textContains="點擊")。description 與 text 同理,但 description 使用的機會較少。

提示

Selector 是由您透過上文所述介面佈局檢視功能獲得的相關主要參數組合而成。

螢幕座標定義

自動化操作的過程中難免會碰到需要透過精確座標或區域座標進行操作的情況。可能您對座標概念還不熟悉,這裡介紹安卓螢幕座標知識。螢幕與圖片一樣,都有解析度。對於安卓螢幕,無論橫屏、豎屏還是自動旋轉,統一把左上角作為原點 (0,0),向右為 X 軸正方向,向下為 Y 軸正方向,形成座標系,如圖所示。

螢幕座標

由上圖可知,螢幕左上角座標為 (0,0),右上角為 (1080,0),左下角為 (0,1920),右下角為 (1080,1920)。您可以根據此資訊換算螢幕上任意點的座標。

備註

無論螢幕原生是豎屏還是橫屏,亦或是自動旋轉,統一以當前方向的左上角作為原點。

螢幕上的點

在 FIRERPA 中,有一些操作(如點擊或截圖)需要您提供區域或座標資訊。對於常見的座標點,我們使用如下定義,它代表螢幕上座標為 (100,100) 的點。

Point(x=100, y=100)

區域的定義

區域指螢幕上的一片矩形區域,其定義稍顯繁瑣,請仔細閱讀。我們用 Bound 表示螢幕上的區域,需要提供四個參數:topleftbottomright。您可能有些困惑,下面請務必仔細理解:top 表示矩形頂部到螢幕頂部的像素距離,left 表示矩形左邊到螢幕左邊的像素距離,right 表示矩形右邊到螢幕左邊的距離,bottom 表示矩形底部到螢幕頂部的距離。簡言之,所有距離都是以螢幕左上角原點為基準的 X/Y 軸距離。下圖輔助理解,手機螢幕仍為 1080x1920,當前為豎屏狀態。

螢幕區域

現在假設螢幕被四等分,我們需要獲取圖中所示的左上和右下兩個區域的定義。根據規則,區域1:矩形頂部到螢幕頂部距離 0 像素,左邊到螢幕左邊距離 0 像素,底部到螢幕頂部距離 960 像素(1920÷2),右邊到螢幕左邊距離 540 像素(1080÷2),所以它的定義為

Bound(top=0, left=0, right=540, bottom=960)

同理,區域2:矩形頂部到螢幕頂部距離 960 像素,左邊到螢幕左邊距離 540 像素,右邊到螢幕左邊距離 1080 像素,底部到螢幕頂部距離 1920 像素,其定義為

Bound(top=960, left=540, right=1080, bottom=1920)

安卓應用的資料

每個安卓應用在裝置上都有專用的資料目錄。通常,應用資料儲存於 /data 目錄下。您可以透過呼叫 d.application("com.example").info() 介面獲取應用的資料目錄。多數情況下,也可以直接 cd/data/user/0/com.example.test 來進入使用者目錄。除 /data 外,部分應用還會在 /sdcard/Android 目錄儲存多媒體等其他檔案。

查看簡訊資料庫

有時,您想查看本機收到的簡訊儲存位置,這非常簡單,甚至透過編寫擴充(extension)可以直接讀取內容並透過 HTTP 介面即時獲取!我們按常規安卓思路介紹,若您的情況不同,請自行發散。在安卓上,簡訊應用的套件名稱通常為 com.android.mms,因此可切換到目錄 /data/user/0/com.android.mms。透過以下操作,您會看到 databases 目錄下有幾個資料庫,其中的 mmssms.db 就是我們要找的。

 λ 10:12 /data/user/0/com.android.mms ➥ ls -la
total 82
drwx------    7 u0_a78   u0_a78        3452 Jan  2  2021 .
drwxrwx--x  381 system   system       53248 May  2 16:46 ..
drwxrws--x    3 u0_a78   u0_a78_c      3452 Jan  2  2021 cache
drwxrws--x    2 u0_a78   u0_a78_c      3452 Jan  2  2021 code_cache
drwxrwx--x    2 u0_a78   u0_a78        3452 Jan  2  2021 databases
drwxrwx--x    7 u0_a78   u0_a78       24576 Feb 26 13:43 files
drwxrwx--x    2 u0_a78   u0_a78        3452 May  4 10:12 shared_prefs
 λ 10:12 /data/user/0/com.android.mms ➥ ls -l databases/
total 504
-rw-rw----    1 u0_a78   u0_a78       24576 Jan  2  2021 dynamic_bubble
-rw-------    1 u0_a78   u0_a78           0 Jan  2  2021 dynamic_bubble-journal
-rw-rw----    1 u0_a78   u0_a78      491520 Feb 27 04:18 mmssms.db
-rw-------    1 u0_a78   u0_a78           0 Jan  2  2021 mmssms.db-journal
 λ 10:12 /data/user/0/com.android.mms ➥

讀取非常簡單,因為安卓上常規應用資料庫均為 SQLite。但安全性較高的應用通常會對資料庫加密。不過,FIRERPA 功能強大,除了支援常規 SQLite,還支援即時讀取微信(SqlCipher)AES-256、企業微信 AES-128、阿里系 SqlCrypto(AES-128)等加密資料庫(前提是您需自行找到金鑰)。下面我們簡單演示讀取系統簡訊內容,一條指令即可,您也可以編寫擴充來讀取。

sqlite3 databases/mmssms.db .dump

輸出可能很多,但您可以快速定位所需資料所在的表,然後自行編寫 SQL 查詢。此方法適用於 98% 的安卓應用,剩餘 2% 為加密資料庫。

查看加密資料庫

對於加密資料庫,需由您自行找到資料庫金鑰或其生成方式。下面簡單介紹如何讀取相關應用的資料庫,僅介紹如何使用 PRAGMA 預設金鑰。若不清楚這是什麼,請先了解 SQLite。

微信系 (sqlcipher)

PRAGMA cipher = "sqlcipher";
PRAGMA legacy = 1;
PRAGMA key = "database-key";

企業微信 (wxsqlite)

PRAGMA cipher = "aes128cbc";
PRAGMA hexkey = "database-key"

阿里系 (sqlcrypto)

PRAGMA cipher = "sqlcrypto";
PRAGMA key = "database-key"

提示

注意,安卓應用的資料庫不一定只放在 databases 目錄下。

查看其他資料

當然,應用資料目錄中不僅有資料庫,還包含應用參數、設定、快取、檔案等,如 shared_prefs(XML 檔案)。我們不做過多介紹,您可以自行探索。

自動化輔助措施

在自動化業務中,並非所有應用都適合使用選擇器定位。有些介面(如遊戲)由於即時渲染,沒有安卓層面的頁面佈局。對於此類應用,您只能藉助 OCR 或圖像比對進行判別。請參閱 文字識別圖像比對 章節了解具體介面與用法。