日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Andriod 破解之道(一)

發(fā)布時間:2025/3/15 编程问答 13 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Andriod 破解之道(一) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

# 前言

在Root前提下,我們可以使用Hooker方式綁定so庫,通過逆向方式篡改數(shù)值,從而達(dá)到所謂破解目的。然而,目前無論是軟件加固方式,或是數(shù)據(jù)處理能力后臺化,還是客戶端數(shù)據(jù)真實性驗證,都有了一定積累和發(fā)展,讓此“懶技術(shù)”不再是破解修改的萬金油。再者,閱讀匯編指令,函數(shù)指針替換,壓棧出棧等技術(shù)需要一定技術(shù)沉淀,不利于開發(fā)同學(xué)上手。

兩年前,也是因為懶,很懶,非常懶,堆積了足夠的動力,寫了一個基于人工模擬方式,對一個特定規(guī)則的游戲進(jìn)行暴力破解。我們都知道,人工模擬方式,繞過了大量防破解技術(shù),只要還是人機(jī)交互模式,并且滿足一定的游戲規(guī)則,基本是無法防御的。

以下是一段技術(shù)應(yīng)用視頻,以便大家對文章有個初步認(rèn)識:

大家能夠看到,這段一分鐘的視頻,在50秒的時候就刷爆了游戲分?jǐn)?shù)上限,足見此技術(shù)能力并不亞于傳統(tǒng)的Hooker篡改內(nèi)存地址方式。


技術(shù)實現(xiàn)原理

因涉及到安全方面的考量,本文主要圍繞技術(shù)實現(xiàn)原理和關(guān)鍵技術(shù)點進(jìn)行闡述。

技術(shù)要求:

  • 支持多分辨率
  • 支持多點觸摸
  • 支持輸入速率動態(tài)變更
  • 處理能力峰值需要達(dá)到30fps
  • 實現(xiàn)方式分三步:

  • 劫持屏幕
  • 分析數(shù)據(jù)
  • 模擬輸出

  • 1.劫持屏幕

    先說說劫持屏幕,做過截屏功能的同學(xué)應(yīng)該清楚,Root了之后能訪問設(shè)備“dev/graphic”文件夾,里面有fb0, fb1, fb2三個screen buffer文件。這里用到的是fb0文件。

    拋出一個問題,當(dāng)前主流屏幕分辨率都在1920*1080區(qū)間,一張圖片的緩存能去到2M左右,要達(dá)到30fps的性能指標(biāo),光是屏幕數(shù)據(jù)的讀寫耗時,就滿足不了要求。怎么做呢?

    一般在做圖像處理的時候都會想到parallel programming。然而,這里的圖片是時間相關(guān)的,不適宜采用多線程任務(wù)派發(fā)。

    懶人一番思量后,發(fā)現(xiàn)一條捷徑,共享內(nèi)存讀取,請看以下代碼。

    mapbase = mmap(0, **mapsize, PROT_READ, MAP_SHARED, fd, offset);

    這行代碼廣泛存在于各個截屏代碼片段中,精髓在于PROT_READ 和 MAP_SHARED上。先科普一下mmap參數(shù)中這兩個參數(shù)吧。

    prot : 映射區(qū)域的保護(hù)方式。可以為以下幾種方式的組合:

    • PROT_EXEC 映射區(qū)域可被執(zhí)行
    • PROT_READ 映射區(qū)域可被讀取
    • PROT_WRITE 映射區(qū)域可被寫入
    • PROT_NONE 映射區(qū)域不能存取

    flags : 影響映射區(qū)域的各種特性。在調(diào)用mmap()時必須要指定MAP_SHARED 或MAP_PRIVATE。

    • MAP_FIXED 如果參數(shù)start所指的地址無法成功建立映射時,則放棄映射,不對地址做修正。通常不鼓勵用此旗標(biāo)。
    • MAP_SHARED 對映射區(qū)域的寫入數(shù)據(jù)會復(fù)制回文件內(nèi),而且允許其他映射該文件的進(jìn)程共享。
    • MAP_PRIVATE 對映射區(qū)域的寫入操作會產(chǎn)生一個映射文件的復(fù)制,即私人的“寫入時復(fù)制”(copy on write)對此區(qū)域作的任何修改都不會寫回原來的文件內(nèi)容。
    • MAP_ANONYMOUS建立匿名映射。此時會忽略參數(shù)fd,不涉及文件,而且映射區(qū)域無法和其他進(jìn)程共享。
    • MAP_DENYWRITE只允許對映射區(qū)域的寫入操作,其他對文件直接寫入的操作將會被拒絕。
    • MAP_LOCKED 將映射區(qū)域鎖定住,這表示該區(qū)域不會被置換(swap)。



    因為我們不需要寫屏,所以prot只需要采用PORT_READ;而我們期望避免屏幕數(shù)據(jù)的多次創(chuàng)建,flags就需要用到MAP_SHARED,這樣文件句柄fd指向的內(nèi)存塊數(shù)據(jù)就會實時變更,無需多次創(chuàng)建,拷貝,釋放數(shù)據(jù)。


    2.分析數(shù)據(jù)

    截取到屏幕數(shù)據(jù)就好辦了,對每一幀進(jìn)行數(shù)據(jù)處理,這里完全就是算法問題了。懶人都用搓算法,大概的思路就是:7*7宮格,對于所有相連的兩個同色item做了橫向映射表和縱向映射表,然后輪尋處理5連,4連和3連。里面還有一些涉及到實現(xiàn)細(xì)節(jié)的映射表重置與預(yù)判,因為不是本文重點,就帶過了。

    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. 模擬輸出

    算法會輸出當(dāng)前屏幕的一個模擬手勢操作隊列,最精彩的當(dāng)然放到最后,也是此工程的技術(shù)點,怎么模擬輸出手勢的問題。

    Android所給予的截屏和模擬操作分別為 adb screenshot 和 adb shell sendevent (根據(jù)android版本,有些機(jī)型用的是input event,記得沒錯的話~)
    所有需要adb處理的指令,都不能采用高并發(fā)方式調(diào)用,要不然要么機(jī)器重啟,要么指令堵塞。所以adb這條路不通。
    怎么辦呢?

    懶人又一番思量后,linux系統(tǒng)大都采用文件buffer,直接將指令寫文件吧。其實adb也是寫文件,不過adb做了一層轉(zhuǎn)譯,這里涉及到設(shè)備層指令代碼,不同機(jī)型定義的指令代碼不盡相同。

    要完成此任務(wù),首先要弄清楚幾件事情:

  • 一個點擊事件的構(gòu)成是怎樣的
  • 一個滑動事件的構(gòu)成多了什么
  • 事件的指令代碼分別代表什么


  • 萬能的adb給了我一些思路,adb shell getevent,會打印出當(dāng)前event的指令。再科普一下,event有很多,包括compass_sensor,light_sensor,pressure_sensor,accelerometer_sensor等等。
    我們這里監(jiān)聽的是,touchscreen_sensor。



    有了上面的指導(dǎo)信息,要構(gòu)建一個模擬操作函數(shù)就很容易了。操作屏幕打印出想要的模擬的手勢,然后寫下來就好了。一共會有這么幾個模擬操作函數(shù)需要創(chuàng)建:


    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串?dāng)_問題,也就不需要記數(shù)了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坐標(biāo)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// 數(shù)據(jù)同步到設(shè)備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:// 結(jié)束符event.type = 0x0;event.code = 0x0;event.value = 0x0;write(global.fd_event, &event, sizeof(event));pthread_mutex_unlock(&global.writeEventLock); }

    建議大家在動手寫模擬輸入模塊之前,先仔細(xì)研讀Android input事件機(jī)制,對于個人程序修為大有裨益。有時間我會單獨寫一個技術(shù)文檔供大家參考,目前就此帶過了。


    調(diào)試

    因為我是個懶人,能偷懶的地方都會花時間深研。以下,是個人針對本項目調(diào)試的一些懶技巧,以供各位參考。

    下面是在Debug模式下生成的8張連續(xù)圖片。能看到每個小宮格的右上方都打印出了當(dāng)前識別的顏色。如果當(dāng)前宮格需要被移動,則采用雙色繪制表明移動的方向,上下雙色表示需要上下移動,左右雙色表示需要左右移動。



    此外,調(diào)測程序的時候必不可少的就是單步回歸了,以下是設(shè)計的Dummy模式,以驗證Bug修復(fù)效果。

    int loadImageData(const LPSTR device, GGLSurface *gr_framebuffer,Var_ScreenInfo *vi, Fix_ScreenInfo *fi, ssize_t* mapsize) { #ifdef TEST_DUMMYreturn test_dummy("/mnt/sdcard/screenss.bmp", &gr_framebuffer, &vi, &fi); #elsereturn get_framebuffer(device, &gr_framebuffer, &vi, &fi, &mapsize); #endif }



    至此,主要關(guān)鍵技術(shù)已經(jīng)簡述完畢,謝謝大家。


    # 后記

    大家如果仔細(xì)看了這篇文章,會發(fā)現(xiàn)視頻中的游戲版本,和截屏圖片的版本是不一致的。視頻是我在13年的時候錄的,截屏是因為KPI考核要求寫文章,臨時又生成一遍的,所以會有版本差異。做這個技術(shù)的初衷就是因為懶,才想到虐爆Android的。從開始到第一個demo出來,大概花了一周的時間,因為思路都比較清晰,后續(xù)的優(yōu)化反而花了一個多月,包括防破解這塊(總不能出個破解然后被人爆菊吧,太侮辱智商了)還是需要仔細(xì)走讀一下底層實現(xiàn)。其中也請教了當(dāng)時公司安全部的哥們,知道了更多關(guān)于軟件實現(xiàn)機(jī)制,也深知安全的重要性,所以這段代碼一直只存留在我的代碼實驗室,以前不會,現(xiàn)在不會,以后也不會開源發(fā)布,所以請各位海涵了。有興趣的同學(xué)可以通過自己的努力實現(xiàn)一遍,對個人技術(shù)的提高會有很大幫助。

    這篇技術(shù)文檔的確只覆蓋了一些關(guān)鍵技術(shù)節(jié)點,還有較多和當(dāng)前程序不相關(guān)的技術(shù)并沒有被涵蓋,例如底層加固技術(shù),動態(tài)底層Binary Dex加載技術(shù)(在Art下需要有一定的修改,懶,沒有去深挖了),so庫混淆,屏幕同步,模擬輸入同步等,往后有時間再行一一簡述吧。


    原文地址:?https://yq.aliyun.com/articles/3032?spm=5176.100239.blogcont3033.31.a7Z6Y1

    總結(jié)

    以上是生活随笔為你收集整理的Andriod 破解之道(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。