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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

【Android 逆向】代码调试器开发 ( ptrace 函数 | 向进程内存写出数据 )

發布時間:2025/6/17 Android 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【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 函数 | 向进程内存写出数据 )的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。