Andriod破解之道(一)
# 前言
在Root前提下,我們可以使用Hooker方式繫結so庫,通過逆向方式篡改數值,從而達到所謂破解目的。然而,目前無論是軟體加固方式,或是資料處理能力後臺化,還是客戶端資料真實性驗證,都有了一定積累和發展,讓此“懶技術”不再是破解修改的萬金油。再者,閱讀彙編指令,函式指標替換,壓棧出棧等技術需要一定技術沉澱,不利於開發同學上手。
兩年前,也是因為懶,很懶,非常懶,堆積了足夠的動力,寫了一個基於人工模擬方式,對一個特定規則的遊戲進行暴力破解。我們都知道,人工模擬方式,繞過了大量防破解技術,只要還是人機互動模式,並且滿足一定的遊戲規則,基本是無法防禦的。
以下是一段技術應用視訊,以便大家對文章有個初步認識:
大家能夠看到,這段一分鐘的視訊,在50秒的時候就刷爆了遊戲分數上限,足見此技術能力並不亞於傳統的Hooker篡改記憶體地址方式。
技術實現原理
因涉及到安全方面的考量,本文主要圍繞技術實現原理和關鍵技術點進行闡述。
技術要求:
- 支援多解析度
- 支援多點觸控
- 支援輸入速率動態變更
- 處理能力峰值需要達到30fps
實現方式分三步:
- 劫持螢幕
- 分析資料
- 模擬輸出
1.劫持螢幕
先說說劫持螢幕,做過截圖功能的同學應該清楚,Root了之後能訪問裝置“dev/graphic”資料夾,裡面有fb0, fb1, fb2三個screen buffer檔案。這裡用到的是fb0檔案。
丟擲一個問題,當前主流螢幕解析度都在1920*1080區間,一張圖片的快取能去到2M左右,要達到30fps的效能指標,光是螢幕資料的讀寫耗時,就滿足不了要求。怎麼做呢?
一般在做影像處理的時候都會想到parallel programming。然而,這裡的圖片是時間相關的,不適宜採用多執行緒任務派發。
懶人一番思量後,發現一條捷徑,共享記憶體讀取,請看以下程式碼。
mapbase = mmap(0, **mapsize, PROT_READ, MAP_SHARED, fd, offset);
這行程式碼廣泛存在於各個截圖程式碼片段中,精髓在於PROT_READ 和 MAP_SHARED上。先科普一下mmap引數中這兩個引數吧。
prot : 對映區域的保護方式。可以為以下幾種方式的組合:
- PROT_EXEC 對映區域可被執行
- PROT_READ 對映區域可被讀取
- PROT_WRITE 對映區域可被寫入
- PROT_NONE 對映區域不能存取
flags : 影響對映區域的各種特性。在呼叫mmap()時必須要指定MAP_SHARED 或MAP_PRIVATE。
- MAP_FIXED 如果引數start所指的地址無法成功建立對映時,則放棄對映,不對地址做修正。通常不鼓勵用此旗標。
- MAP_SHARED 對對映區域的寫入資料會複製迴檔案內,而且允許其他對映該檔案的程式共享。
- MAP_PRIVATE 對對映區域的寫入操作會產生一個對映檔案的複製,即私人的“寫入時複製”(copy on write)對此區域作的任何修改都不會寫回原來的檔案內容。
- MAP_ANONYMOUS建立匿名對映。此時會忽略引數fd,不涉及檔案,而且對映區域無法和其他程式共享。
- MAP_DENYWRITE只允許對對映區域的寫入操作,其他對檔案直接寫入的操作將會被拒絕。
- MAP_LOCKED 將對映區域鎖定住,這表示該區域不會被置換(swap)。
因為我們不需要寫屏,所以prot只需要採用PORT_READ;而我們期望避免螢幕資料的多次建立,flags就需要用到MAP_SHARED,這樣檔案控制程式碼fd指向的記憶體塊資料就會實時變更,無需多次建立,拷貝,釋放資料。
2.分析資料
擷取到螢幕資料就好辦了,對每一幀進行資料處理,這裡完全就是演算法問題了。懶人都用搓演算法,大概的思路就是:7*7宮格,對於所有相連的兩個同色item做了橫向對映表和縱向對映表,然後輪尋處理5連,4連和3連。裡面還有一些涉及到實現細節的對映表重置與預判,因為不是本文重點,就帶過了。
void Handle_X_Combination() {
LOGE("Handle_X_Combination");
gen_Horizontal_Matrix(6);
get_Horizontal_X_Match();
gen_Vertical_Matrix(0, 6);
get_Vertical_X_Match();
}
下面是程式執行時的Log資訊片段,以供大家參考。
3. 模擬輸出
演算法會輸出當前螢幕的一個模擬手勢操作佇列,最精彩的當然放到最後,也是此工程的技術點,怎麼模擬輸出手勢的問題。
Android所給予的截圖和模擬操作分別為 adb screenshot 和 adb shell sendevent (根據android版本,有些機型用的是input event,記得沒錯的話~)
所有需要adb處理的指令,都不能採用高併發方式呼叫,要不然要麼機器重啟,要麼指令堵塞。所以adb這條路不通。
怎麼辦呢?
懶人又一番思量後,linux系統大都採用檔案buffer,直接將指令寫檔案吧。其實adb也是寫檔案,不過adb做了一層轉譯,這裡涉及到裝置層指令程式碼,不同機型定義的指令程式碼不盡相同。
要完成此任務,首先要弄清楚幾件事情:
- 一個點選事件的構成是怎樣的
- 一個滑動事件的構成多了什麼
- 事件的指令程式碼分別代表什麼
萬能的adb給了我一些思路,adb shell getevent,會列印出當前event的指令。再科普一下,event有很多,包括compass_sensor,light_sensor,pressure_sensor,accelerometer_sensor等等。
我們這裡監聽的是,touchscreen_sensor。
有了上面的指導資訊,要構建一個模擬操作函式就很容易了。操作螢幕列印出想要的模擬的手勢,然後寫下來就好了。一共會有這麼幾個模擬操作函式需要建立:
`
void simulate_long_press_start_event(int touch, int fromX, int fromY);
void simulate_long_press_hold_event(int touch, int fromX, int fromY);
void simulate_long_press_end_event(int touch);
void simulate_press_event(int touch, int fromX, int fromY);
void simulate_move_event(int touch, int fromX, int fromY, int toX, int toY);
`
下面給出一個我寫好的範例出來,大家可以依葫蘆畫瓢,把剩下的寫好。
void simulate_press_event(int touch, int fromX, int fromY) {
pthread_mutex_lock(&global.writeEventLock);
LOGE("simulate_press_event");
INPUT_EVENT event;
// 0. Multi-Touch
// 此專案非必要,因為沒有用到多點觸控,是另一個專案使用到了
event.type = 0x3;
event.code = 0x2f;
event.value = touch;
write(global.fd_event, &event, sizeof(event));
// 1. ABS_MT_TRACKING_ID:
// 理論上必要,因為Android事件輸入是批量處理的,需要用到輸入id,
// 但是這裡偷懶使用了同步鎖,並且沒有多點觸控需求,所以不會有Tracking_ID串擾問題,也就不需要記數了
event.type = 0x3;
event.code = 0x39;
event.value = global.event_id > 60000 ? 10 : global.event_id++;
write(global.fd_event, &event, sizeof(event));
// 2. At screen coordinates:
// 觸控點x,y座標
event.type = 0x3;
event.code = 0x35;
event.value = fromX;
write(global.fd_event, &event, sizeof(event));
event.type = 0x3;
event.code = 0x36;
event.value = fromY;
write(global.fd_event, &event, sizeof(event));
// 4. Sync
// 資料同步到裝置
event.type = 0x0;
event.code = 0x0;
event.value = 0x0;
write(global.fd_event, &event, sizeof(event));
event.type = 0x3;
event.code = 0x39;
event.value = 0xffffffff;
write(global.fd_event, &event, sizeof(event));
// 4. Pure event separator:
// 結束符
event.type = 0x0;
event.code = 0x0;
event.value = 0x0;
write(global.fd_event, &event, sizeof(event));
pthread_mutex_unlock(&global.writeEventLock);
}
建議大家在動手寫模擬輸入模組之前,先仔細研讀Android input事件機制,對於個人程式修為大有裨益。有時間我會單獨寫一個技術文件供大家參考,目前就此帶過了。
除錯
因為我是個懶人,能偷懶的地方都會花時間深研。以下,是個人針對本專案除錯的一些懶技巧,以供各位參考。
下面是在Debug模式下生成的8張連續圖片。能看到每個小宮格的右上方都列印出了當前識別的顏色。如果當前宮格需要被移動,則採用雙色繪製表明移動的方向,上下雙色表示需要上下移動,左右雙色表示需要左右移動。
此外,調測程式的時候必不可少的就是單步迴歸了,以下是設計的Dummy模式,以驗證Bug修復效果。
int loadImageData(const LPSTR device, GGLSurface *gr_framebuffer,
Var_ScreenInfo *vi, Fix_ScreenInfo *fi, ssize_t* mapsize) {
#ifdef TEST_DUMMY
return test_dummy("/mnt/sdcard/screenss.bmp", &gr_framebuffer, &vi, &fi);
#else
return get_framebuffer(device, &gr_framebuffer, &vi, &fi, &mapsize);
#endif
}
至此,主要關鍵技術已經簡述完畢,謝謝大家。
# 後記
大家如果仔細看了這篇文章,會發現視訊中的遊戲版本,和截圖圖片的版本是不一致的。視訊是我在13年的時候錄的,截圖是因為KPI考核要求寫文章,臨時又生成一遍的,所以會有版本差異。做這個技術的初衷就是因為懶,才想到虐爆Android的。從開始到第一個demo出來,大概花了一週的時間,因為思路都比較清晰,後續的優化反而花了一個多月,包括防破解這塊(總不能出個破解然後被人爆菊吧,太侮辱智商了)還是需要仔細走讀一下底層實現。其中也請教了當時公司安全部的哥們,知道了更多關於軟體實現機制,也深知安全的重要性,所以這段程式碼一直只存留在我的程式碼實驗室,以前不會,現在不會,以後也不會開源釋出,所以請各位海涵了。有興趣的同學可以通過自己的努力實現一遍,對個人技術的提高會有很大幫助。
這篇技術文件的確只覆蓋了一些關鍵技術節點,還有較多和當前程式不相關的技術並沒有被涵蓋,例如底層加固技術,動態底層Binary Dex載入技術(在Art下需要有一定的修改,懶,沒有去深挖了),so庫混淆,螢幕同步,模擬輸入同步等,往後有時間再行一一簡述吧。
相關文章
- Java的破解和反破解之道 (轉)Java
- Android破解之道(二)Android
- Andriod PackageManager使用Package
- “桌遊深度”先手的優勢以及破解之道
- 位置不可用資料夾?的破解之道!
- Andriod開發工具
- andriod sdk 安裝
- Andriod 實現一個類微信聊天介面 (二)
- 資料夾拒絕訪問的原因與破解之道
- 俞敏洪:破解組建核心創業團隊之道創業團隊
- [Andriod] 元件化路由跳轉元件化路由
- andriod開發環境搭建,開發環境
- Mybatis學習之道(一)MyBatis
- 如何玩轉andriod遠控(androrat)
- andriod搭建自己的輪詢框架框架
- andriod環境搭建(Mac機器)Mac
- 從全球視野破解中國工業軟體產業發展之道產業
- 像 npm 一樣在 Andriod 專案中引入 Gradle 依賴NPMGradle
- 百度地圖軌跡(Andriod SDK)地圖
- Andriod 網路框架 OkHttp 原始碼解析框架HTTP原始碼
- 本站 andriod-App 下載賊慢APP
- 前端面試之道筆記(一)前端面試筆記
- Andriod專案記憶體洩漏流程記憶體
- 使用mumu模擬器抓包 andriod appAPP
- andriod 原始碼開發,打包so到apk原始碼APK
- CCF YOCSEF天津成功舉辦“行業信創適配‘最後一公里‘破解之道?“技術論壇行業
- Android:隨筆——記錄一些Andriod開發中不常用的庫Android
- 爆料一下,我的面試之道面試
- Excel圖表之道一突破常規Excel
- HT圖形元件設計之道(一)元件
- 破解某小說App(一)APP
- 藥廠潔淨車間網路升級挑戰多?解析銳捷的破解之道
- 大模型如何破解資料困局,WAIC產學研專家共話突圍之道大模型AI
- JS判斷當前裝置是 PC IOS AndriodJSiOS
- 微軟成立新部門,暗示將整合 Win 11和 Andriod微軟
- Andriod Studio如何修改APP軟體名和頭像APP
- Asymco:Andriod應用下載量即將超過iOSiOS
- Andriod給textview文字關鍵字迴圈標亮加粗TextView