一個方向,你可否改變世界?html
先來看看效果圖: java
因爲 Pay 的效果圖被屏蔽,這裏以刷文章的方式呈上。注意:打開「某度」,輸入地址,瀏覽,點擊廣告等操做都是手機自動完成,非人爲手指控制,同時手機非 Root 非無障礙並無鏈接 usb。android
親測還能自動 Pay,自動回覆,自動 Play Music 等等,用句誇大詞說:只有你想不到,沒有作不到。git
說來話長,那我就長話短說,在去年有個朋友讓我幫忙刷某度文章閱讀量,做爲一名程序員,首先想到模擬接口訪問,常常一番折騰就放棄了,大廠的網絡傳輸加密不是那麼好破解的,嘗試了幾種抓包,攔截,改變參數,再次發送的方式,測試並無成功。程序員
同許多程序員同樣,喜歡一條路走到黑,不見南牆不回頭,經過網上搜索大量資料來破解加密,一次次失敗,最終仍是失敗了,不得不佩服某度的網絡安全體系,不是我一個「嫩頭青」能夠破解的。github
那麼問題仍是回到起點,既然不能改變接口環境,那麼只剩下一個笨辦法,手動輸入地址,查閱文章,來達到閱讀量的增長。不過接下來的問題就讓人太尷尬了,那就是效率問題,手動查閱太枯燥效率過低了,那能不能手機自動完成查閱文章的動做,並不須要人工操做呢。shell
答案是確定的,雖然效率低了點,依舊是一種解決方案。說好的長話短說,這話又說多了。安全
你們都知道 Android 調試橋 (adb) 是一個通用命令行工具,其容許您與模擬器實例或鏈接的 Android 設備進行通訊。它可爲各類設備操做提供便利,如安裝和調試應用,並提供對 Unix shell(可用來在模擬器或鏈接的設備上運行各類命令)的訪問。服務器
好比模擬按鍵點擊:微信
adb shell input tap 460 410
複製代碼
點擊屏幕 (460 410) 這點,模擬輸入文本:
adb shell input text hello
複製代碼
輸入文本「hello」,模擬滑動:
adb shell input swipe 300 1000 300 500
複製代碼
參數 300 1000 300 500 分別表示起始點 x 座標,起始點 y 座標,結束點 x 座標,結束點 y 座標。模擬回車,返回鍵:
adb shell input keyevent 66
adb shell input keyevent 4
複製代碼
66 表示回車,4 表示返回鍵。還有常見的 adb install ,adb push 錄屏截圖等等。想查看更多 adb 命令,請連接 awesome-adb。好了,具體看案例。
「某度」自動瀏覽文章爲了如下幾步:
第一步,啓動應用 / 調起 Activity 的命令以下:
adb shell am start [options] <INTENT>
複製代碼
例如:
adb shell am start -n com.tencent.mm/.ui.LauncherUI
複製代碼
表示打開「微信」主界面。參數 com.tencent.mm 表示微信包名 .ui.LauncherUI 表示打開的 Activity 的名稱。查看當前界面 Activity 名稱的方式有許多,這裏推薦 android-TopActivity。以下圖左上角:
獲取到「某度」的包名與主界面的名稱爲, com.baidu.searchbox 與 .MainActivity ,那麼打開「某度」的 adb 命令以下:adb shell am start -n com.baidu.searchbox/com.baidu.searchbox.MainActivity
複製代碼
第二步,點擊頂部輸入框區域,那麼須要獲取到點擊點的座標位置,能夠藉助「開發者選擇」的「指針位置」來獲取:
那麼咱們經過模擬點擊 (431 380) 來模擬點擊輸入框:adb shell input tap 431 380
複製代碼
第三步,輸入瀏覽文章的地址,adb 命令以下:
adb shell input text 'https://na.mbd.baidu.com/je3rqk2?f=cp'
複製代碼
注意:若是你安裝了第三方輸入法,可能會致使輸入錯亂,請在「設置」「語言與輸入法」「虛擬鍵盤」下關閉第三方輸入法。
第四步,回車搜索,adb 命令以下:
adb shell input keyevent 66
複製代碼
注意:文章搜索是異步,需延遲後續操做,在後文中會講到。
第五步,模擬滑動,adb 命令以下:
adb shell input swipe 200 1800 200 0
複製代碼
起點 y 座標 1800 與結束點 y 座標 0 ,相差越大滑動越大,在每一個機型上須要調整,同時滑動到廣告出如今屏幕內的次數可能也不同。具體請在真機上模擬調整。
第六步,點擊推薦廣告,同上獲取到廣告區域的座標點:
對應的 adb 命令以下:adb shell input tap 583 339
複製代碼
第七步,點擊返回鍵的 adb 命令:
adb shell input keyevent 4
複製代碼
總共七步就完成了一次自動瀏覽文章,有小夥伴確定會有疑問,不會每步都執行 DOS 命令吧,這樣比手動點擊還慢呢,那有沒有腳本能夠批處理。
bat (批處理文件類型)就是解決這樣的問題。新建 xx.bat 文件,把如下代碼拷入:
ping 127.0.0.1 -n 2
adb shell am start -n com.baidu.searchbox/com.baidu.searchbox.MainActivity
ping 127.0.0.1 -n 3
adb shell input tap 431 380
adb shell input text https://na.mbd.baidu.com/je3rqk2?f=cp
ping 127.0.0.1 -n 1
adb shell input keyevent 66
ping 127.0.0.1 -n 3
adb shell input swipe 200 1800 200 0
ping 127.0.0.1 -n 2
adb shell input swipe 200 1800 200 0
ping 127.0.0.1 -n 2
adb shell input swipe 200 1800 200 0
ping 127.0.0.1 -n 2
adb shell input swipe 200 1200 200 0
ping 127.0.0.1 -n 2
adb shell input tap 583 339
ping 127.0.0.1 -n 5
複製代碼
保存,確保手機連上電腦,雙擊 xx.bat 文件,發現手機自動打開百度,輸入地址,瀏覽文章,哈哈,這樣方便多了。但還有一個小小的不足,瀏覽完一次文章 xx.bat 就結束了,能不能加個循環語句,讓文章間斷性被瀏覽。因爲並不熟悉 .bat 的寫法,研究了一下,功夫不負有心人,咱們能夠這麼作:
:start
ping 127.0.0.1 -n 2
adb shell am start -n com.baidu.searchbox/com.baidu.searchbox.MainActivity
ping 127.0.0.1 -n 3
adb shell input tap 431 380
adb shell input text https://na.mbd.baidu.com/je3rqk2?f=cp
ping 127.0.0.1 -n 1
adb shell input keyevent 66
ping 127.0.0.1 -n 3
adb shell input swipe 200 1800 200 0
ping 127.0.0.1 -n 2
adb shell input swipe 200 1800 200 0
ping 127.0.0.1 -n 2
adb shell input swipe 200 1800 200 0
ping 127.0.0.1 -n 2
adb shell input swipe 200 1200 200 0
ping 127.0.0.1 -n 2
adb shell input tap 583 339
ping 127.0.0.1 -n 5
adb shell input keyevent 4
adb shell input keyevent 4
adb shell input keyevent 4
adb shell input keyevent 4
adb shell input keyevent 4
goto start
pause
複製代碼
ping 127.0.0.1 -n 1
用於延遲執行,因爲每步操做都是異步,延時時間你能夠根據具體狀況而定。emmm,大功告成,文章被無限週期性瀏覽,但仍是有兩個小小的瑕疵,一是要運行 bat 腳本;二是手機必須連上電腦。針對第一種狀況,可不能夠在 app 內執行 adb shell 命令,最初嘗試提示「permission denied」權限被拒絕,須要 Root 權限,Root 太麻煩,並且用戶也不會贊成,那麼咱們可不能夠繞過 Root 權限?
這個問題一直困擾着我,在這裏很是感謝 gtf 同窗的免Root實現靜默安裝和點擊任意位置(非無障礙)文章,這裏引用他的一段話:
我來問你們個新問題,怎樣讓 app 獲取 root 權限?這個問題答案已經有很多了,網上一查即可知實際上是獲取「Runtime.getRuntime().exec」的流,在裏面用su提權,而後就能夠執行須要 root 權限的 shell 命令,好比掛載 system 讀寫,訪問 data 分區,用 shell 命令靜默安裝,等等。話說回來,是否是和咱們今天的主題有點像,如何使 app 獲取 shell 權限?嗯,其實差很少,思路也相似,由於原本 root 啦, shell 啦,根本就不是 Android 應用層的名詞呀,他們原本就是 Linux 裏的名詞,只不過是 Android 框架運行於 Linux 層之上, 咱們能夠調用 shell 命令,也能夠在shell 裏調用 su 來使shell 獲取 root 權限,來繞過 Android 層作一些被限制的事。然而在 app 裏調用 shell 命令,其進程仍是 app 的,權限仍是受限。因此就不能在 app 裏運行 shell 命令,那麼問題來了,不在 app 裏運行在哪運行?答案是在 pc 上運行。固然不多是 pc 一直連着手機啦,而是 pc 上在 shell 裏運行獨立的一個 java 程序,這個程序由於是在 shell 裏啓動的,因此具備 shell 權限。咱們想一下,這個 Java 程序在 shell 裏運行,創建本地 socket 服務器,和 app 通訊,遠程執行 app 下發的代碼。由於即便拔掉了數據線,這個 Java 程序也不會中止,只要不重啓他就一直活着,執行咱們的命令,這不就是看起來 app 有了 shell 權限?如今真相大白,飛智和黑域用 usb 調試激活的那一下,實際上是啓動那個 Java 程序,飛智是執行模擬按鍵,黑域是監聽系統事件,你想幹啥就職你開發了。「注:黑域和飛智因爲進程管理的須要,實際上是先用 shell 啓動一個 so ,而後再用 so 作跳板啓動 Java 程序,並且 so 也充當守護進程,當 Java 意外中止能夠從新啓動,讀着有興趣能夠自行研究,在此很少作說明」
這裏有一句話說的很是好,「你想幹啥就職你開發了。」 若是調整好參數,我能夠拿到「某信」的付款二維碼,並能截圖上傳,就問你怕不怕?
gtf
同窗的思路,讓我醍醐灌頂,並非繞過 Root 權限,而是在 pc 上在 shell 裏運行獨立的一個 java 程序,,這個程序由於是在 shell 裏啓動的,因此具備 shell 權限。這個 Java 程序在 shell 裏運行,創建本地 socket 服務器,和 app 通訊,遠程執行 app 下發的代碼。由於即便拔掉了數據線,這個 Java 程序也不會中止,只要不重啓他就一直活着,執行咱們的命令,這不就是看起來 app 有了 shell 權限?
你們想想,若是我把 Java 程序部署到遠程服務器上,那麼我能隨時隨地均可以創建 socket ,從而控制手機自動完成想作的事情。
還得再次感謝 gtf
同窗分享了一個簡單的 socket 程序,親測後的效果圖以下:
細節一,經過 javac
運行多個 .java
文件:
D:\>cd D:\AndroidSpace\app_process-shell-use\app\src\main\java\shellService
D:\AndroidSpace\app_process-shell-use\app\src\main\java\shellService>javac -encoding UTF-8 Main.java Service.java ServiceShellUtils.java ServiceThread.java
複製代碼
首先 cd 到 java 目錄,而後執行 javac 命令。注意:指定編碼格式爲 UTF-8 ,否則中文亂碼會致使編譯不經過。編譯過的目錄以下圖:
細節二,多個.class
文件生成
.dex
文件
D:\AndroidSpace\app_process-shell-use\app\src\main\java\shellService>cd..
D:\AndroidSpace\app_process-shell-use\app\src\main\java>dx --dex --output=D:\hello.dex shellService/Main.class shellService/Service.class shellService/Service$CreateServerThread.class shellService/Service$ServiceGetText.class shellService/ServiceShellUtils.class shellService/ServiceShellUtils$ServiceShellCommandResult.class shellService/ServiceThread.class shellService/ServiceThread$1.class
複製代碼
注意,首先須要 cd 到 java 目錄,否則會提示類文件找不到,而後經過 dx --dex 命令生成 .dex 文件,所生成的全部 .class 文件都須要加到命令中。生成的 .dex 文件以下圖:
細節三,app_process 運行 java 程序:D:\AndroidSpace>cd..
D:\>adb push hello.dex /data/local/tmp
hello.dex: 1 file pushed. 1.5 MB/s (8096 bytes in 0.005s)
D:\>adb shell app_process -Djava.class.path=/data/local/tmp/hello.dex /data/local/tmp shellService.Main
>>>>>>Shell鏈嶅姟絝▼搴忚璋冪敤<<<<<<
鏈嶅姟絝繍琛屽湪4521絝彛
複製代碼
首先 cd 到 .dex 目錄,接着把 .dex 文件推到手機 /data/local/tmp
目錄下,最後執行 app_process 命令,由於 utf8 在 Windows shell 裏有問題,因此亂碼了,可是仍是說明咱們成功了。
因爲 adb shell 須要 usb 連上手機才能運行,那麼咱們能夠經過 ADB WiFi 來鏈接手機,運行 app ,DOS 的執行狀況以下:
鍏抽棴Socket
鐩戝惉璇鋒眰鍒版潵鍒欎駭鐢熶竴涓猄ocket瀵硅薄錛屽苟緇х畫鎵ц
鍒涘緩浜嗕竴涓柊鐨勮繛鎺ョ嚎紼?
鐢盨ocket瀵硅薄寰楀埌杈撳靉嫺侊紝騫舵瀯閫犵溮搴旂殑BufferedReader瀵硅薄
鐢盨ocket瀵硅薄寰楀埌杈撳嚭嫺侊紝騫舵瀯閫燩rintWriter瀵硅薄
while寰幆錛氳幏鍙栦粠瀹㈡埛絝鍏ョ殑瀛楃涓?
while寰幆錛氬鎴風榪斿洖 : adb shell input tap 545 980
while寰幆錛氭湇鍔″櫒灝嗚繑鍥烇細###ShellError#sh: <stdin>[1]: adb: not found
while寰幆錛氬噯澶囧埛鏂拌繑鍥?
while寰幆錛氬凡鍒鋒柊榪斿洖
複製代碼
報了 adb: not found
,缺乏 adb 的運行環境。那麼咱們能夠在手機上搭建 adb 運行環境,具體能夠參考手機對手機進行adb指令(OTG),本篇並不會講解如何在手機上搭建 adb 環境,由於在多數狀況下咱們並不會把 Socket 的服務端部署在手機上,而是部署在 pc 上,步驟以下。
運行這個服務端:
public class Main {
public static void main(String[] args){
new ServiceThread().start();
while (true);
}
}
複製代碼
運行客戶端,創建鏈接。注意:HOST = "192.168.xxx.xx" 換成局域網 ip 地址。在 MainActivity 類中直接調用:
runShell("adb shell am start -n com.baidu.searchbox/com.baidu.searchbox.MainActivity");
Thread.sleep(1000);
runShell("adb shell input tap 460 410");
...... 省略其餘
複製代碼
手機自動瀏覽「某度」文章,當這個時候拔去 usb 鏈接,會提示 no devices/emulators found
代表無設備鏈接,在上文中已經提到,這個時候能夠經過 ADB WIFI 鏈接。
總結,手機自動操做操做還不夠成熟,還有一些技術須要攻破,同時也存在了安全隱患。思考,汽車有了自動駕駛,爲啥安卓不能有「自動操做」。
若是以爲本篇文章對你有用,別忘記給小編控件庫點 star ,點 star,點 star
源碼以下:
若是對「自動操做」感興趣的小夥伴,點擊下面二維碼,關注:控件人生