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

歡迎訪問 生活随笔!

生活随笔

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

Android

【Android 逆向】Android 进程代码注入原理 ( 进程注入原理 | 远程调用流程 | 获取函数地址 | 设置 IP 寄存器 | mmap 申请内存 | 设置 SP 寄存器 )

發(fā)布時間:2025/6/17 Android 38 豆豆

文章目錄

  • 一、進(jìn)程注入原理
  • 二、遠(yuǎn)程調(diào)用流程 ( 獲取 so 動態(tài)庫地址 | 獲取函數(shù)地址 | 設(shè)置 IP 寄存器 | mmap 申請內(nèi)存 | 設(shè)置 SP 寄存器 )





一、進(jìn)程注入原理



調(diào)試進(jìn)程 Attach 被調(diào)試進(jìn)程 :

工具程序 ( 調(diào)試進(jìn)程 ) 獲取調(diào)試 目標(biāo)進(jìn)程 ( 被調(diào)試進(jìn)程 ) 的權(quán)限 , 調(diào)用 ptrace 函數(shù) , 傳入 PTRACE_ATTACH 參數(shù) ;

如果 目標(biāo)進(jìn)程 Attach 成功 , 該進(jìn)程會自動掛起 , 暫停執(zhí)行指令 ; 并返回 WUNTRACED 狀態(tài)給 工具程序 , 表示 目標(biāo)進(jìn)程 已經(jīng)進(jìn)入 被調(diào)試狀態(tài) ;


調(diào)試進(jìn)程 讀取 被調(diào)試進(jìn)程 寄存器值 :

工具程序 ( 調(diào)試進(jìn)程 ) 調(diào)用 ptrace 函數(shù) , 傳入 PTRACE_GETREGS 參數(shù) , 獲取調(diào)試 目標(biāo)進(jìn)程 ( 被調(diào)試進(jìn)程 ) 的寄存器值 , 獲取成功后 , 返回給 工具程序 ( 調(diào)試進(jìn)程 ) ;

工具程序 ( 調(diào)試進(jìn)程 ) 中拿到寄存器值后 , 保存一份寄存器值 , 之后再進(jìn)行遠(yuǎn)程調(diào)用等操作 , 最后 Detach 解除調(diào)試時 , 必須根據(jù)保存的寄存器值 , 恢復(fù) 目標(biāo)進(jìn)程 ( 被調(diào)試進(jìn)程 ) 的寄存器值 ;


工具程序 ( 調(diào)試進(jìn)程 ) 遠(yuǎn)程調(diào)用 目標(biāo)進(jìn)程 ( 被調(diào)試進(jìn)程 ) :

遠(yuǎn)程調(diào)用 指的是 在 目標(biāo)進(jìn)程 ( 被調(diào)試進(jìn)程 ) 中 , 執(zhí)行 我們想要執(zhí)行的程序 , 一般是加載 SO 動態(tài)庫 或遠(yuǎn)程代碼 , 使用 malloc 分配內(nèi)存 , 然后將代碼復(fù)制到該段內(nèi)存中 , 給這塊內(nèi)存分配可執(zhí)行權(quán)限 ;

一般情況是注入一個 SO 動態(tài)庫 , 每個 SO 動態(tài)庫 都是獨立模塊 , 這樣不會破壞原有的代碼體系 ,

然后 通過 遠(yuǎn)程調(diào)用 , 獲取該內(nèi)存的地址 , 之后就可以使用遠(yuǎn)程調(diào)用執(zhí)行注入的代碼 ;

注入代碼 , 一般是用于修改 進(jìn)程邏輯用的 , 修改 目標(biāo)進(jìn)程 ( 被調(diào)試進(jìn)程 ) 內(nèi)存中的數(shù)據(jù) ;


進(jìn)程注入原理圖 :





二、遠(yuǎn)程調(diào)用流程 ( 獲取 so 動態(tài)庫地址 | 獲取函數(shù)地址 | 設(shè)置 IP 寄存器 | mmap 申請內(nèi)存 | 設(shè)置 SP 寄存器 )



遠(yuǎn)程調(diào)用 的 核心就是 要 準(zhǔn)確的計算 要遠(yuǎn)程調(diào)用的 SO 動態(tài)庫的庫函數(shù) 在內(nèi)存中的地址 ;


內(nèi)存空間是一塊線性的空間 , 內(nèi)存地址從低到高依次線性排列 , 如 0x00 00 00 00 ~ 0x FF FF FF FF , 32 位地址對應(yīng)的指針地址長度都是 4 字節(jié) , 最多訪問 4 GB 的內(nèi)存空間 ;


工具程序 ( 調(diào)試進(jìn)程 ) 又稱為 " 控制進(jìn)程 " , 對應(yīng)下圖的 控制進(jìn)程 , 控制進(jìn)程 在 內(nèi)存中 , 占據(jù)一定的控件 ;

目標(biāo)進(jìn)程 ( 被調(diào)試進(jìn)程 ) 又稱為 " 被控制進(jìn)程 " , 對應(yīng)下圖的 控制進(jìn)程 , 被控制進(jìn)程 在 內(nèi)存中 , 也占據(jù)一定的控件 ;

控制進(jìn)程 與 被控制進(jìn)程 在內(nèi)存中 , 先后順序不確定 ;


下圖的內(nèi)存是 Android 設(shè)備的整體內(nèi)存 ;


在 /proc/pid 對應(yīng) 進(jìn)程的 目錄下 , 有 mmaps 文件 , 在該文件中 , 會記錄所有的 so 動態(tài)庫的 起止 內(nèi)存地址 ;

根據(jù) /proc/pid/mmaps 文件 , 可以獲取 工具程序 ( 調(diào)試進(jìn)程 ) 的 libc.so 的起止地址 , 也可以獲取 目標(biāo)進(jìn)程 ( 被調(diào)試進(jìn)程 ) 的 libc.so 的起止地址 ;

在 libc.so 中存在 dlopen 函數(shù) , dlopen 函數(shù)有一個函數(shù)指針 ( 函數(shù)地址 ) , 該函數(shù)指針可以直接獲取到 , dlopen 的名稱就代表該函數(shù)的地址 , libc.so 的起始地址可以通過 /proc/pid/mmaps 文件確定 , dlopen 函數(shù)在 libc.so 的相對偏移量 ( 如 : 8 字節(jié) ) 也是確定的 , 這樣就可以知道 dlopen 函數(shù)在內(nèi)存中的地址 ;

獲取到 dlopen 函數(shù)地址后 , 將 IP 寄存器設(shè)置成 r_dlopen 函數(shù)地址 ; IP 寄存器存儲將要執(zhí)行的下一條指令的偏移量 ;

通過 mmap 函數(shù) , 分配一塊新內(nèi)存 , SP 寄存器指向這塊新內(nèi)存 , 之后 調(diào)用 ptrace 函數(shù)傳入 PTRACE_CONT 參數(shù) , 繼續(xù)執(zhí)行將控制權(quán)交還給 目標(biāo)進(jìn)程 ( 被調(diào)試進(jìn)程 ) , 繼續(xù)執(zhí)行 , 直到下一個中斷發(fā)生 ; SP 寄存器是堆棧指針寄存器 ;

總結(jié)

以上是生活随笔為你收集整理的【Android 逆向】Android 进程代码注入原理 ( 进程注入原理 | 远程调用流程 | 获取函数地址 | 设置 IP 寄存器 | mmap 申请内存 | 设置 SP 寄存器 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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