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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android安全-SO动态库注入

發布時間:2023/11/29 Android 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android安全-SO动态库注入 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

關于這方面技術,網上已經有大把的實現。在此,我只是記錄下自己的學習過程。


0x1 原理

????所謂的SO注入就是將代碼拷貝到目標進程中,并結合函數重定向等其他技術,最終達到監控或改變目標進程行為的目的。Android是基于Linux內核的操作系統,而在Linux下SO注入基本是基于調試API函數ptrace實現的,同樣Android的SO注入也是基于ptrace函數,要完成注入還需獲取root權限。


0x2 流程

????注入過程如下:

????????0x01 獲取目標進程的pid,關聯目標進程;

????????0x02 獲取并保存目標進程寄存器值;

????????0x03 獲取目標進程的dlopen,dlsym函數的絕對地址;

????????0x04 獲取并保存目標進程的堆棧,設置dlopen函數的相關參數,將要注入的SO的絕對路徑壓棧;

????????0x05 調用dlopen函數;

????????0x06 調用dlsym函數,獲取SO中要執行的函數地址;

????????0x07 調用要執行的函數;

????????0x08 恢復目標進程的堆棧,恢復目標進程寄存器值,解除關聯,完成SO動態庫注入;

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


0x3 實現

????0x01 獲取目標進程的pid,關聯目標進程:

????????通過遍歷查找/proc/pid/cmdline文件中是否含有目標進程名process_name,若有則進程名對應的進程號即為pid。接著,直接調用函數ptrace_attach(pid)即可完成關聯。

????0x02 獲取并保存目標進程寄存器值:

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

????0x03 獲取目標進程的dlopen,dlsym函數的絕對地址:

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

????0x04 獲取并保存目標進程的堆棧,設置dlopen函數的相關參數,將要注入的SO的絕對路徑壓棧:

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

????0x05 調用dlopen函數:

????????參數設置好后,設置ARM_pc = dlopen_addr,?ARM_lr = 0。調用ptrace_setregs(pid, regs)寫入修改后的寄存器值,調用ptrace_continue( pid )使目標進程繼續運行。(注:dlopen_addr為0x03獲取到的目標進程dlopen函數的絕對地址,ARM_lr = 0的目的在于當目標進程執行完dlopen函數,使目標進程發生異常,從而讓本進程重新獲得控制權)

????0x06 調用dlsym函數,獲取SO中要執行的函數地址:

????????實現方式與調用dlopen函數類似,不再詳述。

????0x07 調用要執行的函數:

????????實現方式與調用dlopen函數類似,不再詳述。

? ??0x08 恢復目標進程的堆棧,恢復目標進程寄存器值,解除關聯,完成SO動態庫注入:

????????調用ptrace_writedata(pid, (uint8_t *)saved_regs.ARM_sp, (uint8_t *)sbuf, sizeof(sbuf))恢復堆棧,調用ptrace_setregs(pid, &saved_regs)恢復寄存器值,調用ptrace_detach(pid)解除關聯,完成SO動態庫注入。


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注入動態庫成功,返回的句柄為:?%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 參考

? ? 玩轉ptrace:http://blog.csdn.net/sealyao/article/details/6710772

????《轉載》linux動態庫注入:http://blog.chinaunix.net/uid-7247280-id-2060516.html

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

轉載于:https://my.oschina.net/u/1777508/blog/664025

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。