新聞中心
背景
在Android系統(tǒng)中,進程之間是相互隔離的,兩個進程之間是沒辦法直接跨進程訪問其他進程的空間信息的。那么在android平臺中要對某個app進程進行內(nèi)存操作,并獲取目標進程的地址空間內(nèi)信息或者修改目標進程的地址空間內(nèi)的私有信息,就需要涉及到注入技術(shù)。

通過注入技術(shù)可以將指定so模塊或代碼注入到目標進程中,只要注入成功后,就可以進行訪問和篡改目標進程空間內(nèi)的信息,包括數(shù)據(jù)和代碼。
Android的注入技術(shù)的應用場景主要是進行一些非法的操作和實現(xiàn)如游戲輔助功能軟件、惡意功能軟件。
下面主要進行對zygote注入、ptrace注入、修改so文件注入,這三種注入方式進行詳細解析。
zygote注入
zygote是一個在android系統(tǒng)中是非常重要的一個進程,因為在android中絕大部分的應用程序進程都是由它孵化(fork)出來的,fork是一種進程復用技術(shù)。也就是說在android系統(tǒng)中普通應用APP進程的父親都是zygote進程。
zygote注入目的就是將指定的so模塊注入到指定的APP進程中,這個注入過程不是直接向指定進程進程注入so模塊,而是先將so模塊注入到zygote進程。
在so模塊注入到zygote進程后,在點擊操作android系統(tǒng)中啟動的應用程序APP進程,啟動的App進程中包括需要注入到指定進程的so模塊,太都是由zygote進程fork生成,因而在新創(chuàng)建的進程中都會包含已注入zygote進程的so模塊。
這種的注入是通過間接注入方式完成的,也是一種相對安全的注入so模塊方式。目前xposed框架就是基于zygote注入。
zygote注入so模塊流程
1.通過注入器將要注入的so模塊注入到zygote進程;
2.手動啟動要注入so模塊的APP進程,由于APP進程是通過zygote進程fork出來的,所以啟動的APP進程都包含zygote進程中所有模塊;
3.注入的so模塊劫持被注入APP進程的控制權(quán),執(zhí)行注入so模塊的代碼;
4.注入so模塊歸還APP進程的控制權(quán),被注入進程正常運行。
Zygote注入器的實現(xiàn)流程
(注入器主要是基于ptrace注入shellcode方式的進程注入)
- 通過ptrace進行附加到zygote進程。
- 調(diào)用mmap申請目標進程空間,用于保存注入的shellcode匯編代碼。
- 執(zhí)行注入shellcode代碼(shellcode代碼是注入目標進程中并執(zhí)行的匯編代碼)。
- 調(diào)用munmap函數(shù)釋放申請的內(nèi)存。
- 通過ptrace進行剝離zygote進程。
下面是關鍵的zygote代碼注入實現(xiàn)
ptrace注入
ptrace注入實現(xiàn)上分類:
- 通過利用ptrace函數(shù)將shellcode注入遠程進程的內(nèi)存空間中,然后通過執(zhí)行shellcode加載遠程進程so模塊。
- 通過直接遠程調(diào)用dlopen、dlsym、dlclose等函數(shù)加載被注入so模塊,并執(zhí)行指定的代碼。
ptrace直接調(diào)用函數(shù)注入流程:
- 通過利用ptrace進行附加到要注入的進程;
- 保存寄存環(huán)境;
- 遠程調(diào)用mmap函數(shù)分配內(nèi)存空間;
- 向遠程進程內(nèi)存空間寫入加載模塊名稱和函數(shù)名稱;
- 遠程調(diào)用dlopen函數(shù)打開注入模塊;
- 遠程調(diào)用dlsym函數(shù)或需要調(diào)用的函數(shù)地址;
- 遠程調(diào)用被注入模塊的函數(shù);
- 恢復寄存器環(huán)境;
- 利用ptrace從遠程進程剝離。
關鍵的ptrace直接調(diào)用系統(tǒng)函數(shù)實現(xiàn)
ptrace的shellcode注入原理
shellcode注入就是通過將dlopen/dlsym庫函數(shù)的操作放在shellcode代碼中,注入函數(shù)只是通過對遠程APP進程進行內(nèi)存空間申請,接著修改shellcode 代碼中有關dlopen、dlsymdlclose等函數(shù)使用到的參數(shù)信息,然后將shellcode代碼注入到遠程APP進程申請的空間中,最后通過修改PC寄存器的方式來執(zhí)行shellcode 的代碼。
ptrace注入shellcode的詳細步驟
1.在shellcode中編寫好dlopen、dlsym等函數(shù)的調(diào)用,來加載so模塊和執(zhí)行函數(shù),但需要將參數(shù)地址、函數(shù)地址、寄存器地址先隨便填充值為我們真實地址保留;
2.附加到遠程APP進程、保存APP進程中寄存器的數(shù)據(jù),為后面恢復遠程進程的繼續(xù)執(zhí)行準備;
3.向遠程APP進程申請內(nèi)存空間,選好shellcode存放的具體位置,準備存放shellcode和參數(shù)數(shù)據(jù);
4.計算本地so模塊函數(shù)對應到,遠程APP進程中的so模塊函數(shù)地址,填充到shellcdoe中的參數(shù)中。計算好庫函數(shù)參數(shù)、寄存器存值相對shellcode起始位置的偏移再加上遠程進程中shellcode存放的起始位置,得到的結(jié)果就是遠程進程的內(nèi)存空間中這些參數(shù)存放的位置,將這些地址填充到shellcode的參數(shù)中;
5.設置寄存器的值來讓執(zhí)行庫函數(shù);
6.恢復寄存器的值讓遠程進程繼續(xù)正常執(zhí)行。
關鍵 的ptrace注入shellcode代碼實現(xiàn)
修改ELF文件注入
在android平臺Native層的可執(zhí)行文件SO文件,它是屬于ELF文件格式,通過修改ELF文件格式可以實現(xiàn)對so文件的注入。
通過修改ELF二進制的可執(zhí)行文件,并在ELF文件中添加自己的代碼,使得可執(zhí)行文件在運行時會先執(zhí)行自定義添加的代碼,最后在執(zhí)行ELF文件的原始邏輯。
修改二進制ELF文件需要關注兩個重要的結(jié)構(gòu)體:
ELF Header、Program Header Table
其中ELF Header 它是ELF文件中唯一的,一個固定位置的文件結(jié)構(gòu),它保存著Program Header Table和Section Header Table的位置和大小信息。
Program Header Table 它保存ELF文件的加載過程中各Section的內(nèi)存映射和依賴庫相關信息,用來告訴android系統(tǒng)中如何創(chuàng)建進程映像。
修改ELF文件實現(xiàn)so文件注入實現(xiàn)原理為:通過修改 Program Header Table中的依賴庫信息,添加自定義的so文件信息,APP進程運行加載被該修改過的ELF文件,它也同時會加載并運行自定義的so文件。
Program Header Table表項結(jié)構(gòu)
程序頭表項中的類型選項有如下
當程序頭表項結(jié)構(gòu)中的類型為PT_DYNAMIC也就是動態(tài)鏈接信息的時候,它是由程序頭表項的偏移(p_offset)和p_filesz(大小)指定的數(shù)據(jù)塊指向.dynamic段。這個.dynamic段包含程序鏈接和加載時的依賴庫信息。
修改ELF文件的注入實現(xiàn)過程
1.修改.dynamic段指向的字符串表中添加 自定義的so模塊名稱;
2.通過修改Program Header Table中添加PT_LOAD表項,新添加的表項將保護so模塊名稱的字符串表數(shù)據(jù)映射到內(nèi)存中。同時將Program Header Table移動到文件末尾;
3.修改.dynamic段的數(shù)組數(shù)據(jù),使得指向新的字符串表,并指向自定義的so模塊名稱;
4.修改ELF HEADER結(jié)構(gòu)中 Program Header Table的位置信息,并指向新的Program Header Table。
關鍵ELF文件修改代碼實現(xiàn)
名稱欄目:詳解三種Android平臺注入技術(shù)
本文鏈接:http://m.fisionsoft.com.cn/article/djpsgej.html


咨詢
建站咨詢
