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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android安全-SO动态库注入

發(fā)布時(shí)間:2023/11/29 Android 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android安全-SO动态库注入 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>

關(guān)于這方面技術(shù),網(wǎng)上已經(jīng)有大把的實(shí)現(xiàn)。在此,我只是記錄下自己的學(xué)習(xí)過程。


0x1 原理

????所謂的SO注入就是將代碼拷貝到目標(biāo)進(jìn)程中,并結(jié)合函數(shù)重定向等其他技術(shù),最終達(dá)到監(jiān)控或改變目標(biāo)進(jìn)程行為的目的。Android是基于Linux內(nèi)核的操作系統(tǒng),而在Linux下SO注入基本是基于調(diào)試API函數(shù)ptrace實(shí)現(xiàn)的,同樣Android的SO注入也是基于ptrace函數(shù),要完成注入還需獲取root權(quán)限。


0x2 流程

????注入過程如下:

????????0x01 獲取目標(biāo)進(jìn)程的pid,關(guān)聯(lián)目標(biāo)進(jìn)程;

????????0x02 獲取并保存目標(biāo)進(jìn)程寄存器值;

????????0x03 獲取目標(biāo)進(jìn)程的dlopen,dlsym函數(shù)的絕對地址;

????????0x04 獲取并保存目標(biāo)進(jìn)程的堆棧,設(shè)置dlopen函數(shù)的相關(guān)參數(shù),將要注入的SO的絕對路徑壓棧;

????????0x05 調(diào)用dlopen函數(shù);

????????0x06 調(diào)用dlsym函數(shù),獲取SO中要執(zhí)行的函數(shù)地址;

????????0x07 調(diào)用要執(zhí)行的函數(shù);

????????0x08 恢復(fù)目標(biāo)進(jìn)程的堆棧,恢復(fù)目標(biāo)進(jìn)程寄存器值,解除關(guān)聯(lián),完成SO動(dòng)態(tài)庫注入;

????????(注:實(shí)際上,0x06和0x07并不屬于SO動(dòng)態(tài)庫注入的步驟,然而僅僅注入是完全沒有意義的,通常我們需要執(zhí)行SO中的函數(shù))


0x3 實(shí)現(xiàn)

????0x01 獲取目標(biāo)進(jìn)程的pid,關(guān)聯(lián)目標(biāo)進(jìn)程:

????????通過遍歷查找/proc/pid/cmdline文件中是否含有目標(biāo)進(jìn)程名process_name,若有則進(jìn)程名對應(yīng)的進(jìn)程號即為pid。接著,直接調(diào)用函數(shù)ptrace_attach(pid)即可完成關(guān)聯(lián)。

????0x02 獲取并保存目標(biāo)進(jìn)程寄存器值:

????? ? 直接調(diào)用ptrace(PTRACE_GETREGS, pid, NULL, &saved_regs),當(dāng)然saved_regs要定義為全局變量。

????0x03 獲取目標(biāo)進(jìn)程的dlopen,dlsym函數(shù)的絕對地址:

????????大概思路是這樣的:首先通過遍歷/proc/pid/maps文件分別得到本進(jìn)程中dlopen函數(shù)所在動(dòng)態(tài)庫的基地址local_module_base和目標(biāo)進(jìn)程dlopen函數(shù)所在動(dòng)態(tài)庫的基地址remote_module_base,接著獲取本進(jìn)程dlopen函數(shù)的絕對地址local_addr =?(void*)dlopen。需要明白的是,不同進(jìn)程中相同的動(dòng)態(tài)庫中的同一個(gè)函數(shù)的偏移地址一定是一樣的,所以目標(biāo)進(jìn)程dlopen函數(shù)的絕對地址為:local_addr - local_module_base +?remote_module_base。dlsym同理,不再詳述。

????0x04 獲取并保存目標(biāo)進(jìn)程的堆棧,設(shè)置dlopen函數(shù)的相關(guān)參數(shù),將要注入的SO的絕對路徑壓棧:

????????當(dāng)我們的要執(zhí)行的函數(shù)的某些參數(shù)需要壓入堆棧的時(shí)候,就需要提前保存堆棧狀態(tài),調(diào)用ptrace_readdata(pid, (void *)regs.ARM_sp, (void *)sbuf, sizeof(sbuf)),其中sbuf為char數(shù)組,用來存放堆棧。調(diào)用ptrace_writedata(pid, (void *)regs.ARM_sp, (void *)so_path, strlen(so_path) + 1),其中so_path為SO的絕對路徑。函數(shù)傳參規(guī)則:前四個(gè)參數(shù)分別由寄存器r0、r1、r2、r3存放,超過四個(gè)參數(shù)則壓入堆棧。

????0x05 調(diào)用dlopen函數(shù):

????????參數(shù)設(shè)置好后,設(shè)置ARM_pc = dlopen_addr,?ARM_lr = 0。調(diào)用ptrace_setregs(pid, regs)寫入修改后的寄存器值,調(diào)用ptrace_continue( pid )使目標(biāo)進(jìn)程繼續(xù)運(yùn)行。(注:dlopen_addr為0x03獲取到的目標(biāo)進(jìn)程dlopen函數(shù)的絕對地址,ARM_lr = 0的目的在于當(dāng)目標(biāo)進(jìn)程執(zhí)行完dlopen函數(shù),使目標(biāo)進(jìn)程發(fā)生異常,從而讓本進(jìn)程重新獲得控制權(quán))

????0x06 調(diào)用dlsym函數(shù),獲取SO中要執(zhí)行的函數(shù)地址:

????????實(shí)現(xiàn)方式與調(diào)用dlopen函數(shù)類似,不再詳述。

????0x07 調(diào)用要執(zhí)行的函數(shù):

????????實(shí)現(xiàn)方式與調(diào)用dlopen函數(shù)類似,不再詳述。

? ??0x08 恢復(fù)目標(biāo)進(jìn)程的堆棧,恢復(fù)目標(biāo)進(jìn)程寄存器值,解除關(guān)聯(lián),完成SO動(dòng)態(tài)庫注入:

????????調(diào)用ptrace_writedata(pid, (uint8_t *)saved_regs.ARM_sp, (uint8_t *)sbuf, sizeof(sbuf))恢復(fù)堆棧,調(diào)用ptrace_setregs(pid, &saved_regs)恢復(fù)寄存器值,調(diào)用ptrace_detach(pid)解除關(guān)聯(lián),完成SO動(dòng)態(tài)庫注入。


0x4 代碼

????貼一下主要邏輯代碼:

pid_t?pid?=?find_pid_of("xxx"); ptrace_attach(pid); uint32_t?*inject_so_of(pid_t?pid,?const?char?*so_path)?{int?status?=?0;struct?pt_regs?regs;memcpy(&regs,?&saved_regs,?sizeof(regs));ptrace_readdata(pid,?(void?*)regs.ARM_sp,?(void?*)sbuf,?sizeof(sbuf));ptrace_writedata(pid,?(void?*)regs.ARM_sp,?(void?*)so_path,?strlen(so_path)?+?1);uint32_t?parameters[2];parameters[0]?=?regs.ARM_sp;parameters[1]?=?RTLD_NOW;if?(?ptrace_call(pid,?find_dlopen_addr(pid),?parameters,?2,?&regs?)?==?-1?)DPRINTF("dlopen?error\n");ptrace_getregs(pid,?&regs);uint32_t?r0?=?regs.ARM_r0;DPRINTF("[+2]\t注入動(dòng)態(tài)庫成功,返回的句柄為:?%x\n",?r0);ptrace_setregs(pid,?&saved_regs);ptrace_writedata(pid,?(uint8_t?*)saved_regs.ARM_sp,?(uint8_t?*)sbuf,?sizeof(sbuf));ptrace_detach(pid);return?(uint32_t?*)r0; }

0x5 參考

? ? 玩轉(zhuǎn)ptrace:http://blog.csdn.net/sealyao/article/details/6710772

????《轉(zhuǎn)載》linux動(dòng)態(tài)庫注入:http://blog.chinaunix.net/uid-7247280-id-2060516.html

????發(fā)個(gè)Android平臺上的注入代碼:http://bbs.pediy.com/showthread.php?t=141355

轉(zhuǎn)載于:https://my.oschina.net/u/1777508/blog/664025

總結(jié)

以上是生活随笔為你收集整理的Android安全-SO动态库注入的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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