android應用程式fps meter[幀數顯示]的分析 —— 淺談root的風險 (2)

來源:互聯網
上載者:User
文章目錄
  • ptrace調用
  • 調用細節
  • 小結

上一節已經分析應用程式啟動後,會通過RootTools庫的Shell類,擷取root許可權並執行/data/data/com.aatt.fpsm/files/0,也就是apk包中的res/raw/bin0這個二進位檔案,此二進位檔案再通過ptrace系統調用,去綁定到其他進程中,做一些動作。接下來看一下fps meter這個apk到底是做了什麼動作。

Ptrace調用過程分析

ptrace是提供一個進程式控制制另外一個進程啟動並執行機制,通過它可以查看和更改進程的資料,它也是linux上的偵錯工具gdb的基礎。

ptrace調用

為查看ptrace的系統調用情況,最好的方法是在核心對應的系統調處理函數中將相關資訊列印出來,修改核心的ptrace調用,加入trace,這樣就可以在無源碼的情況下,查看到bin0都使用了哪些ptrace操作請求,這裡主要有:

ptrace: pid=76 req=16 addr=0 data=0ptrace: pid=76 req=12 addr=0 data=be86f938       ptrace: pid=76 req=5 addr=be84fa28 data=7461642f ptrace: pid=76 req=5 addr=be84fa2c data=61642f61 ptrace: pid=76 req=5 addr=be84fa30 data=632f6174 ptrace: pid=76 req=5 addr=be84fa34 data=612e6d6f ptrace: pid=76 req=5 addr=be84fa38 data=2e747461 ptrace: pid=76 req=5 addr=be84fa3c data=6d737066 ptrace: pid=76 req=5 addr=be84fa40 data=6c69662f ptrace: pid=76 req=5 addr=be84fa44 data=302f7365 ptrace: pid=76 req=5 addr=be84fa48 data=6f732e  ptrace: pid=76 req=13 addr=0 data=be86f938       ptrace: pid=76 req=7 addr=0 data=0               ptrace: pid=76 req=12 addr=0 data=be86f938       ptrace: pid=76 req=5 addr=be84f9a8 data=64616f6c ptrace: pid=76 req=2 addr=be84f9ac data=be86f8bc ptrace: pid=76 req=5 addr=be84f9ac data=40f30000 ptrace: pid=76 req=13 addr=0 data=be86f938       ptrace: pid=76 req=7 addr=0 data=0               ptrace: pid=76 req=12 addr=0 data=be86f938       ptrace: pid=76 req=13 addr=0 data=be86f938       ptrace: pid=76 req=7 addr=0 data=0               ptrace: pid=76 req=12 addr=0 data=be86f938       ptrace: pid=76 req=13 addr=0 data=be86f980       ptrace: pid=76 req=7 addr=0 data=0               ptrace: pid=76 req=17 addr=0 data=0              

從trace出來的pid我們可以知道,ptrace是掛到surfaceflinger進程中,對其進行操作修改的,這從該apk的功能來看,確實合理。先看下surfaceflinger的maps資訊(省略了一些非關鍵資訊),這是分析的主要依據:

# cat /proc/76/mapsmaps:  root@android:/proc/76 # cat maps                                                 400a8000-400a9000 r-xp 00000000 5d:10 241        /system/bin/surfaceflinger  400a9000-400aa000 r--p 00000000 5d:10 241        /system/bin/surfaceflinger  400aa000-400ab000 rw-p 00000000 00:00 0   400ab000-400b9000 r-xp 00000000 5d:10 167        /system/bin/linker  400b9000-400ba000 r--p 00000000 00:00 0   400ba000-400bb000 r--p 0000e000 5d:10 167        /system/bin/linker  400bb000-400bc000 rw-p 0000f000 5d:10 167        /system/bin/linker  400bc000-400c6000 rw-p 00000000 00:00 0   400c6000-400f5000 r-xp 00000000 5d:10 771        /system/lib/libsurfaceflinger.so  400f5000-400fa000 r--p 0002e000 5d:10 771        /system/lib/libsurfaceflinger.so  400fa000-400fb000 rwxp 00033000 5d:10 771        /system/lib/libsurfaceflinger.so  400fb000-400fc000 rw-p 00034000 5d:10 771        /system/lib/libsurfaceflinger.so  ................40146000-40147000 ---p 00000000 00:00 0   40147000-40149000 r--p 00045000 5d:10 644        /system/lib/libc.so  40149000-4014b000 rw-p 00047000 5d:10 644        /system/lib/libc.so  4014b000-40156000 rw-p 00000000 00:00 0   ................401d3000-40210000 r-xp 00000000 5d:10 606        /system/lib/libEGL.so  40210000-40212000 r--p 0003c000 5d:10 606        /system/lib/libEGL.so  40212000-40216000 rw-p 0003e000 5d:10 606        /system/lib/libEGL.so  ................40306000-4030e000 r--s 00000000 00:0a 2126       /dev/__properties__ (deleted)  4030e000-4040c000 r--p 00000000 00:0a 2687       /dev/binder  4040c000-4040d000 ---p 00000000 00:00 0   4040d000-4050c000 rw-p 00000000 00:00 0          [stack:125]  ................40b7a000-40b80000 rw-p 00000000 00:00 0          [heap]  ................40c39000-40c3c000 r-xp 00000000 5d:10 1031       /system/vendor/lib/hw/hwcomposer.default.so  40c3c000-40c43000 ---p 00000000 00:00 0   40c43000-40c44000 r--p 00002000 5d:10 1031       /system/vendor/lib/hw/hwcomposer.default.so  40c44000-40c45000 rw-p 00003000 5d:10 1031       /system/vendor/lib/hw/hwcomposer.default.so  40c45000-40c46000 ---p 00000000 00:00 0   40c46000-40d45000 rw-p 00000000 00:00 0          [stack:184]  40d45000-40d46000 ---p 00000000 00:00 0   40d46000-40e45000 rw-p 00000000 00:00 0          [stack:187]  40e45000-40e47000 rw-p 00000000 00:00 0   ................4163c000-41641000 r-xp 00000000 5d:20 311        /data/data/com.aatt.fpsm/files/0.so  41641000-41642000 r--p 00004000 5d:20 311        /data/data/com.aatt.fpsm/files/0.so  41642000-41643000 rw-p 00005000 5d:20 311        /data/data/com.aatt.fpsm/files/0.so  ................bea46000-bea67000 rw-p 00000000 00:00 0          [stack]  ffff0000-ffff1000 r-xp 00000000 00:00 0          [vectors]  

從maps資訊中,其實已經能看出一些門道了:

4163c000-41641000 r-xp 00000000 5d:20 311        /data/data/com.aatt.fpsm/files/0.so  41641000-41642000 r--p 00004000 5d:20 311        /data/data/com.aatt.fpsm/files/0.so  41642000-41643000 rw-p 00005000 5d:20 311        /data/data/com.aatt.fpsm/files/0.so  

這個資訊可以看出,fps meter中的0.so,被注入到surfaceflinger中,這在android的安全規則中是不可能的。也就是說surfaceFlinger已經被入侵感染了,不是原來的surfaceFlinger了!

繼續分析之前,首先還是看一下ptrace的操作,上述的trace中,request id就是各個ptrace請求命令。這裡用到的有如下幾個:

   Request

Macro

Description

16

PTRACE_ATTACH

Attach到被調試進程,attach之後,被調試進程將暫停執行

12

PTRACE_GETREGS

擷取被調試線程的各個寄存器值

5

PTRACE_POKEDATA  

修改記憶體位址的值

13

PTRACE_SETREGS

設定寄存器的值

7

PTRACE_CONT

繼續執行暫停程式

2

PTRACE_PEEKDATA

從被調試進程的指定記憶體位置讀取資料

17

PTRACE_DETACH

停止對進程的調試,恢複其常態運行

調用細節

為瞭解更細節的資訊,需要更詳盡的trace,繼續將相關的輸入輸出參數都列印出來,結合上面的maps資訊,對每一步的ptrace調用,詳細分析流程如下:

ptrace_request: pid=76 req=16 addr=0 data=0  ptrace_request: pid=76 req=12 addr=0 data=beb68938   PTRACE_GETREGS:           r0 00000003  r1 c0186201      r2 bea66ac8  r3 bea66ac4           r4 40b7e020  r5 40b7dff0      r6 40b7e050  r7 00000036           r8 00000001  r9 40b7dff8      sl 00000000  fp bea66b7c           ip 402bbf24  sp bea66aa8      lr 4012b9f5  pc 40117ffc  cpsr 80000010  

這裡是attach到surfaceflinger線程,暫停surfaceflinger線程的執行,然後擷取暫停時的寄存器資料。對於這裡分析的fps meter的注入入侵,需要儲存surfaceflinger線程暫停點的寄存器資訊,入侵完畢後再恢複現場,繼續surfaceflinger的正常運行。

ptrace: pid=76 req=5 addr= bea66a28 data=7461642f ptrace: pid=76 req=5 addr= bea66a2c data=61642f61 ptrace: pid=76 req=5 addr= bea66a30 data=632f6174 ptrace: pid=76 req=5 addr= bea66a34 data=612e6d6f ptrace: pid=76 req=5 addr= bea66a38 data=2e747461 ptrace: pid=76 req=5 addr= bea66a3c data=6d737066 ptrace: pid=76 req=5 addr= bea66a40 data=6c69662f ptrace: pid=76 req=5 addr= bea66a44 data=302f7365 ptrace: pid=76 req=5 addr= bea66a48 data=006f732e  

這裡的req=5就是PTRACE_POKEDATA,修改棧上的資料,修改的指標是addr=0xbea66a28, 則以上幾個POKEDATA的調用,作用將(char )addr[]的內容修改為:“/data/data/com.aatt.fpsm/files/0.so”,這即是要注入的so的路徑。

ptrace_request: pid=76 req=13 addr=0 data=beb68938   PTRACE_SETREGS:           r0 bea66a28  r1 00000000      r2 bea66ac8  r3 bea66ac4           r4 40b7e020  r5 40b7dff0      r6 40b7e050  r7 00000036           r8 00000001  r9 40b7dff8      sl 00000000  fp bea66b7c           ip 402bbf24  sp bea66a28      lr 00000000  pc 400b00ad  cpsr 80000030   ptrace_request: pid=76 req=7 addr=0 data=0  

調用PTRACE_SETREGS設定寄存器,然後再調用PTRACE_CONT執行。
這裡面設定的寄存器,主要變動如下:

  • R0:應參數,是字串“/data/data/com.aatt.fpsm/files/0.so”的指標
  • sp : 堆棧地址,也是字串的指標位置
  • lr: 函數返回地址
  • pc:需要注入代碼的起始地址

這裡的lr是0,程式出錯後跳到0去,肯定會出現異常,導致程式停止,調試端進程可以通過waitpid得知該次注入的代碼已經被執行。

pc的地址 400b00ad,從上節的maps表中可以看到,這是android的動態連接器linker中的代碼,PC是位於linker的代碼位移位置:400b00ad-400ab000=50ad的位置。50ad說明實際位移是0x50AC,最低位的1表明是thumb指令。

那這個位置具體是什麼呢(肯定是某個函數)?這個函數沒有匯出符號,我也沒看出來,不過從參數和上下文分析,猜測可能是dlopen,不然用so作參數,調用linker的函數幹嘛呢? 寫個小程式驗證了一下:

#define LOG_TAG "TEST"#include <dlfcn.h>#include <unistd.h>#include <cutils/log.h>int main(int argc, char *argv){ALOGD("dlopen:%p dlsym:%p", (void*)dlopen, (void*)dlsym);while(1){sleep(100);}}

運行後,輸出的結果:

D/TEST    (27539): dlopen:0x4002d0ad dlsym:0x4002d019

對比此測試進程的maps資訊:

root@android:/ # cat /proc/27539/maps40025000-40026000 r-xp 00000000 5d:10 1304       /system/bin/test_linker40026000-40027000 r--p 00000000 5d:10 1304       /system/bin/test_linker40027000-40028000 rw-p 00000000 00:00 040028000-40036000 r-xp 00000000 5d:10 144        /system/bin/linker40036000-40037000 r--p 00000000 00:00 040037000-40038000 r--p 0000e000 5d:10 144        /system/bin/linker40038000-40039000 rw-p 0000f000 5d:10 144        /system/bin/linker...400d5000-400dd000 r--s 00000000 00:0a 2180       /dev/__properties__ (deleted)beb4d000-beb6e000 rw-p 00000000 00:00 0          [stack]ffff0000-ffff1000 r-xp 00000000 00:00 0          [vectors]

4002d0ad-40028000=50ad, 正好驗證,確定這個ptrace是讓surfaceflinger調用linker中的dlopen,載入/data/data/com.aatt.fpsm/files/0.so

so庫載入完成後,系統waitpid返回,再看一下寄存器:

ptrace_request: pid=76 req=12 addr=0 data=beb68938   PTRACE_GETREGS:           r0 400be054  r1 00000000      r2 00000001  r3 004b4001           r4 40b7e020  r5 40b7dff0      r6 40b7e050  r7 00000036           r8 00000001  r9 40b7dff8      sl 00000000  fp bea66b7c           ip 00000000  sp bea66a28      lr 00001ffc  pc 00000000  cpsr 80000010 

surfaceflinger進程暫停,這裡讀取寄存器的值,可以看到PC是0,注入的程式執行完畢

ptrace: pid=76 req=5 addr=bea669a8 data=64616f6c ptrace: pid=76 req=2 addr=bea669ac data=40b7e020 ptrace: pid=76 req=5 addr=bea669ac data=40b7e000 

設定地址0xbea669a8的值為"load",讀取的bea669ac值為0x40b7e020,然後再通過PTRACE_POKEDATA將其設定成0x40b7e00,這個地址,位於堆中,應該是malloc出來的一個指標,具體作用不明。

ptrace_request: pid=76 req=13 addr=0 data=beb68938PTRACE_SETREGS:           r0 400be054  r1 bea669a8      r2 00000001  r3 004b4001           r4 40b7e020  r5 40b7dff0      r6 40b7e050  r7 00000036           r8 00000001  r9 40b7dff8      sl 00000000  fp bea66b7c           ip 00000000  sp bea669a8      lr 00000000  pc 400b0019  cpsr 80000030  ptrace_request: pid=75 req=7 addr=0 data=0

PTRACE_CONT執行, 這裡設定的pc:400b0019,可以看到是linker中的位移位置:0x5019,結合剛才寫的測例,就是dlsym函數。這裡就是查詢到load函數的地址。

ptrace_request: pid=76 req=12 addr=0 data=beb68938PTRACE_GETREGS:           r0 4163da81  r1 00000000      r2 400be054  r3 400be054           r4 40b7e020  r5 40b7dff0      r6 40b7e050  r7 00000036           r8 00000001  r9 40b7dff8      sl 00000000  fp bea66b7c           ip 00000000  sp bea669a8      lr 00001ffc  pc 00000000  cpsr 80000010 ptrace_request: pid=75 req=13 addr=0 data=beb68938  PTRACE_SETREGS:           r0 4163da81  r1 00000000      r2 400be054  r3 400be054           r4 40b7e020  r5 40b7dff0      r6 40b7e050  r7 00000036           r8 00000001  r9 40b7dff8      sl 00000000  fp bea66b7c           ip 00000000  sp bea669a8      lr 00000000  pc 4163da81  cpsr 80000030   ptrace_request: pid=76 req=7 addr=0 data=0

 PC為0.so中的函數,在0.so中的位移為:4163da81-4163c000=1a81,這剛好是剛才dlsym查出來的load函數的位置,見IDA pro的反組譯碼資訊:

這樣,就在surfaceflinger中注入了使用者提供的so庫的代碼了!

注入完成後,接下來我們需要恢複之前被暫停surfaceflinger進程的正常執行:

ptrace_request: pid=76 req=12 addr=0 data=beb68938 PTRACE_GETREGS:           r0 00000000  r1 4272d3f3      r2 00000001  r3 40b7dff8           r4 40b7e020  r5 40b7dff0      r6 40b7e050  r7 00000036           r8 00000001  r9 40b7dff8      sl 00000000  fp bea66b7c           ip 40000002  sp bea669a8      lr 0000001e  pc 00000000  cpsr 60000010  ptrace_request: pid=76 req=13 addr=0 data=beb68938 PTRACE_SETREGS:           r0 00000003  r1 c0186201      r2 bea66ac8  r3 bea66ac4           r4 40b7e020  r5 40b7dff0      r6 40b7e050  r7 00000036           r8 00000001  r9 40b7dff8      sl 00000000  fp bea66b7c           ip 402bbf24  sp bea66aa8      lr 4012b9f5  pc 40117ffc  cpsr 80000010    ptrace_request: pid=76 req=7 addr=0 data=0   ptrace_request: pid=76 req=17 addr=0 data=0

寄存器恢複到暫前的樣子,寄生進程從surfaceflinge分離,恢複宿主進程執行。

小結

以上我們可以簡單的比喻一下:寄生進程為bin0,宿主進程為surfaceflinger,寄生進程通過ptrace綁到宿主進程上,咬一口(linker調用),下了一個卵(/data/data/com.aatt.fpsm/files/0.so及load調用)到宿主進程,然後飛走了。

通過詳細分析了注入過程,應該瞭解了用ptrace將需要的庫或代碼植入宿主進程的方法。在不經意間,你啟動並執行正常進程,已經被人為的添加進去可能有害的代碼,這可能對你的資訊安全或者系統穩定性有很大的影響。

不過linux系統相對來說還是很安全的,這裡也並沒有利用什麼漏洞,如果使用者不root系統的話,是很難被注入代碼的。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.