【Android 逆向】代码调试器开发 ( ptrace 函数 | 读取进程内存数据 )
文章目錄
- 一、讀取進(jìn)程內(nèi)存數(shù)據(jù)
- 二、讀取流程
- 三、完整代碼
一、讀取進(jìn)程內(nèi)存數(shù)據(jù)
使用 ptrace 函數(shù)讀取內(nèi)存數(shù)據(jù) :
ptrace(PTRACE_PEEKTEXT, m_nPid, (void*)pRemoteAddr, 0);傳入的第一個參數(shù)可以是 PTRACE_PEEKTEXT / PTRACE_PEEKDATA / PTRACE_PEEKUSER , 這三個參數(shù)效果相同 ;
傳入的第二個參數(shù)是 進(jìn)程號 PID , ptrace 函數(shù)可以同時調(diào)試多個進(jìn)程 ;
傳入的第三個參數(shù)是內(nèi)存地址 , void* 指針類型的 ;
傳入的第四個參數(shù)默認(rèn)為 0 ;
上述讀取進(jìn)程內(nèi)存數(shù)據(jù)的 ptrace 方法的返回值是一個 4 字節(jié)數(shù)據(jù) , 32 位的設(shè)備上 , 最長只能讀取 4 字節(jié) ; 可以在 for 循環(huán)中讀取內(nèi)存中的數(shù)據(jù) ;
二、讀取流程
讀取進(jìn)程內(nèi)存數(shù)據(jù)時 , 每次最多只能讀取 4 字節(jié)數(shù)據(jù) , 先根據(jù)讀取的大小 , 計(jì)算出讀取次數(shù) ,
// 每次讀取 4 字節(jié) , 讀取次數(shù)為 nSize / 4j = nSize / 4;然后再計(jì)算出最后不足 4 字節(jié)的部分 ,
// 讀取最后不滿 4 個字節(jié)的數(shù)據(jù) remain = nSize % 4;讀取數(shù)據(jù)時 , 先循環(huán) j 次 , 讀取 j x 4 字節(jié)數(shù)據(jù) ,
for (i = 0; i < j; i++) {// 32 位的設(shè)備上 , 最長只能讀取 4 字節(jié) d.val = ptrace(PTRACE_PEEKTEXT, m_nPid, (void*)pRemoteAddr, 0);// 將讀取的數(shù)據(jù)拷貝到 laddr 地址中 memcpy(laddr, d.chars, 4);pRemoteAddr += 4;laddr += 4;}最后再讀取一次末尾不足 4 字節(jié)的數(shù)據(jù) ;
// 讀取最后不足 4 字節(jié)的數(shù)據(jù) if (remain > 0) {d.val = ptrace(PTRACE_PEEKTEXT, m_nPid, (void*)pRemoteAddr, 0);memcpy(laddr, d.chars, remain);}三、完整代碼
使用 ptrace 函數(shù)讀取內(nèi)存完整代碼示例 :
int CPtrace::read(char* pRemoteAddr, char* pBuf, size_t nSize) {uint32_t i = 0, j = 0, remain = 0;// 拷貝數(shù)據(jù)的目的地址 , 該指針需要不斷累加計(jì)算 , 記錄已經(jīng)讀取的數(shù)據(jù)char *laddr;// 聯(lián)合體 , 在同一個內(nèi)存地址上 , 既可以以 long 類型解析這塊數(shù)據(jù) , 也可以以 char 數(shù)組類型解析這塊數(shù)據(jù)union u {long val;char chars[sizeof(long)];} d;// 每次讀取 4 字節(jié) , 讀取次數(shù)為 nSize / 4j = nSize / 4;// 讀取最后不滿 4 個字節(jié)的數(shù)據(jù) remain = nSize % 4;// 設(shè)置讀取數(shù)據(jù)的最終存放地址 laddr = pBuf;for (i = 0; i < j; i++) {// 32 位的設(shè)備上 , 最長只能讀取 4 字節(jié) d.val = ptrace(PTRACE_PEEKTEXT, m_nPid, (void*)pRemoteAddr, 0);// 將讀取的數(shù)據(jù)拷貝到 laddr 地址中 memcpy(laddr, d.chars, 4);pRemoteAddr += 4;laddr += 4;}// 讀取最后不足 4 字節(jié)的數(shù)據(jù) if (remain > 0) {d.val = ptrace(PTRACE_PEEKTEXT, m_nPid, (void*)pRemoteAddr, 0);memcpy(laddr, d.chars, remain);}return PTERR_SUCCESS; }總結(jié)
以上是生活随笔為你收集整理的【Android 逆向】代码调试器开发 ( ptrace 函数 | 读取进程内存数据 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 逆向】代码调试器开发
- 下一篇: 【Android 逆向】代码调试器开发