【Android 逆向】代码调试器开发 ( ptrace 函数 | 向进程内存写出数据 )
生活随笔
收集整理的這篇文章主要介紹了
【Android 逆向】代码调试器开发 ( ptrace 函数 | 向进程内存写出数据 )
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 一、向進程內存寫出數據
- 二、寫出流程
- 三、完整代碼
一、向進程內存寫出數據
向內存寫出數據 : 每次最多能寫出 4 字節 ;
ptrace(PTRACE_POKETEXT, m_nPid, (void*)pDestAddr, d.val);- 參數一 : 寫出數據標志 PTRACE_POKETEXT ;
- 參數二 : 進程號 PID ;
- 參數三 : 寫出去數據的地址 ;
- 參數四 : 寫出的數據內容 , 4 字節 ;
二、寫出流程
向進程內存寫出數據時 , 每次最多只能寫出 4 字節數據 , 先根據讀取的大小 , 計算出讀取次數 ,
// 每次讀取 4 字節 , 讀取次數為 nSize / 4j = nSize / 4;然后再計算出最后不足 4 字節的部分 ,
// 讀取最后不滿 4 個字節的數據 remain = nSize % 4;讀取數據時 , 先循環 j 次 , 寫出 j x 4 字節數據 ,
for (i = 0; i < j; i++) {// 準備寫出數據 , 從 laddr 拷貝到 d.charsmemcpy(d.chars, laddr, 4);// 32 位的設備上 , 最長只能讀取 4 字節 ptrace(PTRACE_POKETEXT, m_nPid, (void*)pDestAddr, d.val);pDestAddr += 4;laddr += 4;}最后再讀取一次末尾不足 4 字節的數據 ;
讀取的時候 , 如果不足 4 字節 , 我們可以將數據直接讀取出來 , 不影響程序運行 ; 寫出的時候 , 如果寫出數據不足 4 字節 , 是 3 字節 , 那么必須保證最后一位寫出時 , 不會出錯 , 原來進程中 第 4 位是什么數據 , 寫出去時也必須是同樣的數據 , 否則進程運行出錯 ;
先 讀取 當前進程內存的數據 ,
// 一次性必須寫入 4 字節 , 如果不足 4 字節 , 先把數據讀取出來 , 即讀取 4 字節出來 d.val = ptrace(PTRACE_PEEKTEXT, m_nPid, (void*)pDestAddr, 0);然后 , 設置數據 ; 假如數據有 3 字節 , 那么就將上述讀取的 4 字節的前 3 個字節設置成我們要修改的數據 , 這就保證了第 4 個字節不會出錯 ;
// 假如數據有 3 字節 , 那么就將上述讀取的 4 字節的前 3 個字節設置成我們要修改的數據 // 這就保證了第 4 個字節不會出錯 for (i = 0; i < remain; i++) {d.chars[i] = *laddr++;}最后 , 將最終的 4 字節數據寫入進程內存 ;
// 最后將最終的 4 字節數據寫入進程內存ptrace(PTRACE_POKETEXT, m_nPid, (void*)pDestAddr, d.val);//整體寫入部分代碼示例 :
// 寫出末尾不足 4 字節的數據部分 // 讀取的時候 , 如果不足 4 字節 , 我們可以將數據直接讀取出來 , 不影響程序運行 // 寫出的時候 , 如果寫出數據不足 4 字節 , 是 3 字節 , 那么必須保證最后一位寫出時 , 不會出錯 , // 原來進程中 第 4 位是什么數據 , 寫出去時也必須是同樣的數據 , 否則進程運行出錯 if (remain > 0) {// 一次性必須寫入 4 字節 , 如果不足 4 字節 , 先把數據讀取出來 , 即讀取 4 字節出來 d.val = ptrace(PTRACE_PEEKTEXT, m_nPid, (void*)pDestAddr, 0);// 假如數據有 3 字節 , 那么就將上述讀取的 4 字節的前 3 個字節設置成我們要修改的數據 // 這就保證了第 4 個字節不會出錯 for (i = 0; i < remain; i++) {d.chars[i] = *laddr++;}// 最后將最終的 4 字節數據ptrace(PTRACE_POKETEXT, m_nPid, (void*)pDestAddr, d.val);//整體寫入}三、完整代碼
向進程內存寫出數據完整代碼 :
// pDestAddr 寫出地址 , const char* pData 寫出的數據 , size_t nSize 寫出數據大小 int CPtrace::write(char* pDestAddr, const char* pData, size_t nSize) {uint32_t i, j, remain;// 寫出數據的地址 , 該地址需要不斷累加計算 , 記錄寫出的數據地址 const char *laddr;// 聯合體 , 在同一個內存地址上 , 既可以以 long 類型解析這塊數據 , 也可以以 char 數組類型解析這塊數據union u {long val;char chars[sizeof(long)];} d;// 每次讀取 4 字節 , 讀取次數為 nSize / 4j = nSize / 4;// 讀取最后不滿 4 個字節的數據 remain = nSize % 4;// 寫出數據準備 laddr = pData;for (i = 0; i < j; i++) {// 準備寫出數據 , 從 laddr 拷貝到 d.charsmemcpy(d.chars, laddr, 4);// 32 位的設備上 , 最長只能讀取 4 字節 ptrace(PTRACE_POKETEXT, m_nPid, (void*)pDestAddr, d.val);pDestAddr += 4;laddr += 4;}// 寫出末尾不足 4 字節的數據部分 // 讀取的時候 , 如果不足 4 字節 , 我們可以將數據直接讀取出來 , 不影響程序運行 // 寫出的時候 , 如果寫出數據不足 4 字節 , 是 3 字節 , 那么必須保證最后一位寫出時 , 不會出錯 , // 原來進程中 第 4 位是什么數據 , 寫出去時也必須是同樣的數據 , 否則進程運行出錯 if (remain > 0) {// 一次性必須寫入 4 字節 , 如果不足 4 字節 , 先把數據讀取出來 , 即讀取 4 字節出來 d.val = ptrace(PTRACE_PEEKTEXT, m_nPid, (void*)pDestAddr, 0);// 假如數據有 3 字節 , 那么就將上述讀取的 4 字節的前 3 個字節設置成我們要修改的數據 // 這就保證了第 4 個字節不會出錯 for (i = 0; i < remain; i++) {d.chars[i] = *laddr++;}// 最后將最終的 4 字節數據ptrace(PTRACE_POKETEXT, m_nPid, (void*)pDestAddr, d.val);//整體寫入}return PTERR_SUCCESS; }總結
以上是生活随笔為你收集整理的【Android 逆向】代码调试器开发 ( ptrace 函数 | 向进程内存写出数据 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 逆向】代码调试器开发
- 下一篇: 【Android 逆向】代码调试器开发