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(®s,?&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,?®s?)?==?-1?)DPRINTF("dlopen?error\n");ptrace_getregs(pid,?®s);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动态库注入的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解决 error: command 's
- 下一篇: 孕妇梦到很多乌龟是什么意思