【Android 逆向】Android 进程注入工具开发 ( 远程调用 | x86 架构的返回值获取 | arm 架构远程调用 )
文章目錄
- 前言
- 一、x86 架構的返回值獲取
- 二、ARM 架構遠程調用
前言
在之前的博客
- 【Android 逆向】Android 進程注入工具開發 ( 注入代碼分析 | 獲取 遠程 目標進程 中的 /system/lib/libc.so 動態庫中的 mmap 函數地址 )
- 【Android 逆向】Android 進程注入工具開發 ( 注入代碼分析 | 遠程調用 目標進程中 libc.so 動態庫中的 mmap 函數 二 | 準備參數 | 遠程調用 mmap 函數 )
- 【Android 逆向】Android 進程注入工具開發 ( 注入代碼分析 | 遠程調用 目標進程中 libc.so 動態庫中的 mmap 函數 三 | 等待遠程函數執行完畢 | 寄存器獲取返回值 )
中 , 介紹了 調試進程 遠程調用 遠程進程 的 libc.so 動態庫中的 mmap 函數 , 本博客繼續對該遠程調用過程進行一些補充 ;
一、x86 架構的返回值獲取
遠程調用 返回值獲取 :
在 x86 架構的 CPU 中 , 使用 EAX 寄存器記錄返回值 , 在 ARM 架構的 CPU 中 , 使用 R0 寄存器記錄返回值 ;
遠程調用結束后 , 獲取寄存器數據 , 并讀取 EAX 寄存器值 ;
如果遠程調用的函數的返回值為 void , 那么 EAX 寄存器存放的就是無意義的值 , 可能是上一個函數的返回值 , 可能是計算過程中的一個中間值 ;
二、ARM 架構遠程調用
在 ARM 架構的 CPU 中 , 遠程調用時 ,
- 使用 SP 寄存器存放棧內存首地址 ,
- 使用 PC 指針指向函數地址 , 下一條指令開始執行函數指令 ;
ARM 架構中 , 棧指針存放在 R4 寄存器中 , 但是遠程調用時 , 需要使用 SP 寄存器存放棧指針 , 棧指針指向使用 mmap 分配的內存中 , 該內存中都是函數執行需要的參數 ;
R4 棧指針指向的棧內存有原來函數執行的數據 , 參數或者函數執行過程中的數據 , 這個數據不能動 , 如果修改了該數據 , 調試結束后 , 運行原來的程序 , 會造成不可預知的結果 , 或者崩潰 , 或者運行結果錯誤 ;
// // push remained params onto stack // if (i < num_params) {regs->ARM_sp -= (num_params - i) * sizeof(long);ptrace_writedata(pid, (void*)regs->ARM_sp, (uint8_t*)¶ms[i], (num_params - i) * sizeof(long));}準備好參數棧后 , 將 PC 寄存器指向函數的地址 ;
要判定是否是 thumb 模式 , 如果在該模式下 , 需要將 PC 指針最低位取反 ;
thumb 模式下 , 不能指向奇數地址 , 如果最低位是 1 , 則將其置位 0 ; 如果最低位為 1 , 執行時會報總線錯誤 ;
thumb 模式下 , 需要將 CPSR 寄存器打開 , 設置 CPSR_T_MASK 標志位 ;
regs->ARM_pc = addr;if (regs->ARM_pc & 1) {/* thumb */regs->ARM_pc &= (~1u);regs->ARM_cpsr |= CPSR_T_MASK;}else {/* arm */regs->ARM_cpsr &= ~CPSR_T_MASK;}返回值設置為 0 ;
設置該返回值的作用是 , 為了使 遠程進程崩潰 , 調試程序 可以收回控制權 ;
regs->ARM_lr = 0;上述操作的寄存器值是在本地設置的 , 通過 ptrace_setregs 函數 , 才能將寄存器值設置到遠程進程中 ;
寄存器設置完畢后 , 調用 ptrace_continue 函數 , 恢復 遠程進程的運行 ;
if (ptrace_setregs(pid, regs) == -1|| ptrace_continue(pid) == -1) {printf("error\n");return -1;}總結
以上是生活随笔為你收集整理的【Android 逆向】Android 进程注入工具开发 ( 远程调用 | x86 架构的返回值获取 | arm 架构远程调用 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【错误记录】Android NDK 编译
- 下一篇: 【Android 逆向】Android