導讀:模擬點選是指透過指令碼、系統指令完成一些自動化點選的操作,不需要人為點選,一般應用在自動化測試,幫助閱讀螢幕文字等。本文主要介紹幾種主流的模擬點選技術及應用。
文|李伊洋
網易易盾 Android 安全工程師
背景
模擬點選是指透過指令碼、系統指令完成一些自動化點選的操作,不需要人為點選,一般應用在自動化測試,幫助視障或是老年群體更方便使用手機。但隨著技術的更新,模擬點選也被應用在了不同的場景,如自動化搶紅包、自動聊天等黑灰產場景中。本文主要介紹幾種主流的模擬點選技術及其應用。
軟體場景
對於 View 較多的軟體,如 IM、電商、短影片等軟體,有時會面臨搶紅包、聊天 Bot、搶商品秒殺等自動化指令碼的風險。因為 View 較為複雜,所以這類指令碼往往是依賴於無障礙服務來實現的。因為系統層的支援,導致無障礙服務對 View 操作十分便利。對於不依賴無障礙的模擬點選工具而言,想要讀取 View 是很困難的,例如想要知道一個使用者名稱,需要截圖 OCR 匹配字型檔,所以對於這部分內容,無障礙服務具有天然的優勢。
自動化搶紅包
自動化搶紅包有違開發商的初衷,破壞了公平競爭的環境,容易引起使用者的不滿和投訴,不利於應用的長久可持續發展。
自動聊天
一些交友類 APP 內有聊天收費模式,這便吸引了黑灰產透過指令碼自動聊天來謀利,比如下面的指令碼,可自動接收和回覆訊息。其原理還是用了模擬點選,自動輸入文字和點選傳送按鈕,但是配合精選的問答庫,使得其可信度很高。
這樣的做法破壞了廠商的營銷策略,是從廠商這裡“薅羊毛”。
遊戲場景
對於遊戲而言,常見的場景是指令碼批次開新號、群控操作、指令碼掛機以及指令碼快速操作等。這類的模擬點選工具往往帶有很強的識圖、識色功能,通常可以根據幾個畫素點的顏色來判斷遊戲是否進入了需要操作的階段,例如進入副本等。
自動掛機指令碼
在部分 SLG 遊戲中,允許玩家間進行資源交易,原本這能夠拉近玩家間的距離,帶動身邊人一起遊玩,但是因為批次掛機指令碼,導致原本玩家會從黑灰廠商那裡用現金購買資源,這就會導致資源貶值,破壞遊戲貨幣系統,影響遊戲正常運轉。
自動日常任務、批次起新號
大部分的遊戲在新手期往往會有大量的獎勵,例如抽卡遊戲,批次開啟的新號會有人一直購買。相較於遊戲中的充值抽卡,透過購買擁有新手獎勵的新號去賭運氣,成本會更低廉。但對於遊戲方而言,這部分收益就白白流失了,由黑灰產商家賺去了。同理還有批次完成日常任務,其本意是為了保證使用者不流失,能夠每日都上線,但是黑灰廠商可以批次操作大量的賬號完成每日任務,其核心思路與批次起新號類似,透過積少成多的獎勵,給只想要特定種類的人抽卡使用,或者“代肝”,使原本保證玩家上線的手段失效,給遊戲方造成巨大的損失。
自動跑環、跑任務
在類傳奇遊戲中,自動跑環的指令碼也十分常見,與上一種行為類似,一般也是用於批次開新號使用,這樣也會破壞遊戲公平性,影響貨幣體系。
除此之外,模擬點選對於軟體和遊戲的危害還有很多,出於篇幅的考慮就不再一一展示。下文將從技術角度分析這些模擬點選的實現方式。
現狀及原理
從市面上的指令碼工具來看,較為出名的有“按鍵精靈”、“觸動精靈”、“Auto.js”等軟體。從他們的實現原理來看,Android 端的模擬點選可以說是多種多樣的。
在早期,“按鍵精靈”等軟體透過向 "/dev/input/event*" 路徑下寫入資料,從而實現模擬點選,不過這樣做法會修改檔案許可權,很容易被檢測出來。
於是後來,各種花樣的模擬點選手法就多了起來,下文將分類來詳細介紹。
無障礙服務
AccessibilityService(無障礙服務類):對於無障礙服務而言,最強大的內容並不在於對座標的點選模式,事實上,直到 Android7.0+ 版本才開始支援對任意座標的點選、長按、拖動等操作點選模式。
而除開直接對 View 控制元件屬性的讀取,無障礙服務也可以對 View 控制元件進行操作,比如說按鈕的點選長按、文字框的輸入、多選框的選擇、下拉框的選擇等。
現如今,主要針對遊戲的模擬點選工具也開始慢慢加入無障礙服務的模式,例如“按鍵精靈”與“一鍵玩”等,因為其不依賴 root 的性質,導致很多沒有 root 的玩家也可以體驗到指令碼。
View 控制元件操作
無障礙服務在實現類中繼承 AccessibilityService,並重寫具體的方法,它會被指定的事件觸發, AccessibilityService 的觸發的事件(Event)是:android.view.accessibility.AccessibilityEvent 類。
具體實現方法是重寫 onAccessibilityEvent 方法,以開源的無障礙工具 Auto.js 為例。
透過上圖可知,在服務被指定事件觸發後,有一個 rootInActiveWindow 的變數,該變數由 AssessibilityService 中的方法——getRootInActiveWindow() 獲得,這個方法返回的是使用者當前最希望被操作的那個視窗的根節點。當呼叫這個方法之後,AccessibilityService 應用就根據獲得的這個根節點去遍歷所有的子節點,直到找到我們想要的那個子節點。
Activity 的圖形是樹狀結構的,以前文所述的無障礙指令碼為例,能發現其最上層的根節點是一個 FrameLayout 佈局。
遍歷這個根節點的所有子節點後,就可以獲得想要操作的視窗中的所有 View 資訊,例如文字、ID、Class、父子關係等一系列內容。在 AccessibilityNodeInfo 節點類中,存在 performAction 方法,該方法就可以將想要的操作直接傳送給 View。
對於甲方廠商而言,雖然可以一刀切地只使用 Touch 監聽,但這樣會使原本為殘障人士而設定的無障礙服務失去意義。所以需要結合更多的檢測方法,用來判斷是模擬點選工具帶來的不正當使用,而不影響殘障人士的正常使用。
手勢操作
與模擬點選類工具不同,無障礙並沒有將所有的點選事件拆分為一個個原子事件(down、up、move 等),而是將手勢看作一個整體去執行。AccessibilityService 中的 dispatchGesture 方法實現了對手勢的分發,以一個 Auto.js 指令碼為例,這段 JS 程式碼實現了模擬三個手指下滑。
Auto.js 工具層轉換為 Java 層:
構造器,轉換為一個手勢:
完成分發:
目前,越來越多的遊戲類外掛開始採用這種方式以補充對非 root 玩家的覆蓋,不論是開發門檻還是使用門檻都十分簡單。從上述內容也能看出,這種做法也能保證相容性,無需修改現有指令碼,就能直接用到無障礙服務的外掛版本中。可見在未來,模擬點選類外掛工具相容無障礙服務將會是越來越常見的情況。
非無障礙服務
對於非無障礙服務實現的模擬點選,實際上是參考了 shell 命令中 input 的實現。
透過原始碼分析可知:
該方法的實現依賴於系統 API 中的 injectInputEvent 介面,然而對於任何想要從應用外實現模擬點選的工具來說,該方法面臨的第一個問題就是許可權問題。在 Android 的點選事件分發流程中,native 函式 injectInputEvent 會對傳入點選事件的 PID 與 UID 進行許可權校驗,如果未能獲取到許可權,就會導致點選流程分發失敗。
因此,要使用該功能必須在應用中宣告 Manifest.permission.INJECT_EVENTS 許可權,同時需要該應用使用 root 或者 adb 許可權啟動時,才可以獲取到該許可權,使用該方法實現模擬點選具備更好的效能和更高的隱匿性,也是目前黑灰產中應用廣泛的技術之一。
檢測
早期的檢測一般依賴系統 API 獲取已開啟的無障礙服務列表,透過黑名單判斷是否是惡意應用,從而進行攔截,或者藉助已安裝應用列表的採集,判斷是否有點選工具的痕跡,方式簡單粗暴,且在風控場景中誤傷率也較高。而隨著改包技術、隱私合規的推動,以及 Android 系統正逐步限制對應用安裝列表的獲取,使得行為檢測、點選流程的識別將會成為未來用於識別模擬點選的更可靠的方案。
總結
從網易易盾《2021年遊戲安全白皮書》的資料能夠看出,如今對於遊戲廠商而言,更多是受到模擬點選類外掛的困擾。不同於侵入性的記憶體外掛,模擬點選類外掛侵入性更低,檢測難度更大,使用門檻卻相較於其他型別外掛更低。使用者們只要開啟無障礙服務或是使用 adb,就可以使用模擬點選類外掛廠商和指令碼開發者們精心準備好的指令碼。
模擬點選類外掛對廠商們的影響是很大的,不論是破壞軟體的營銷策略,還是破壞遊戲的生態體系,都會影響到正常使用者的使用體驗,影響遊戲廠商的收益與口碑。但對於廠商來說,也不能簡單粗暴地切斷所有的模擬點選,特別是軟體的無障礙服務。
近年來,隨著智慧裝置的普及,老年人、殘障人士等大量不方便使用智慧裝置的人群,也對使用智慧裝置存在一定的需求。市場也在逐漸完善無障礙服務,所以廠商們也需要考慮到無障礙服務與模擬點選的正面影響,要結合 AI 等多維度去判斷模擬點選是否作為了不正當方式在使用。