【Android 逆向】函数拦截 ( ARM 架构下的插桩拦截 | 完整代码示例 )
生活随笔
收集整理的這篇文章主要介紹了
【Android 逆向】函数拦截 ( ARM 架构下的插桩拦截 | 完整代码示例 )
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
文章目錄
- 一、ARM 架構下的插樁攔截
- 二、完整代碼示例
一、ARM 架構下的插樁攔截
ARM 架構下的跳轉指令 : 下面的二進制數(shù)都是十六進制數(shù) ; 323232 位指令 ;
04 F0 1F E5 00 00 00 00 , B target ;
B 指令是無條件跳轉指令 , 04 F0 1F E5 是對應的機器碼 ;
在 【Android 逆向】函數(shù)攔截 ( 修改內存頁屬性 | x86 架構插樁攔截 ) 一、修改內存頁屬性 基礎上 , 先修改內存頁屬性 , 取得修改內存的權限 ;
然后開始進行函數(shù)攔截 ;
首先 , 拼裝 ARM 架構下的無條件跳轉指令 ;
/* B 無條件跳轉指令 */unsigned char code[] = { 0x04,0xF0,0x1F,0xE5,0x00,0x00,0x00,0x00 };然后 , 設置跳轉指令的絕對地址 ; 注意這里與 x86 的跳轉指令不同 , x86 設置的跳轉地址是相對地址 , arm 的跳轉地址是絕對地址 ;
/* arm 的跳轉是絕對地址跳轉 , 傳入 pStub 函數(shù)指針即可 */*(unsigned*)(code + 4) = (unsigned)pStub;最后 , 將 arm 跳轉指令二進制機器碼拷貝到函數(shù)開始位置 ;
/* 將機器碼復制到函數(shù)開始位置 */memcpy(pFunc, code, sizeof(code));二、完整代碼示例
下面是 插樁函數(shù)攔截 的代碼 , 兼容 x86 與 arm 架構 ;
注意 : 寫完之后推薦刷新 CPU 高速緩存 , 調用 cache_flush 系統(tǒng)調用函數(shù) ;
/** unsigned char* pFunc* unsigned char* pStub* 上述兩個參數(shù)分別是兩個函數(shù)指針* * 注意 : 寫完之后要刷新 CPU 高速緩存 , 調用 cache_flush 系統(tǒng)調用函數(shù)*/ int write_code(unsigned char* pFunc, unsigned char* pStub) {/* 獲取 pFunc 函數(shù)入口 , 先獲取該函數(shù)所在內存頁地址 */void* pBase = (void*)(0xFFFFF000 & (int)pFunc);/* 修改整個內存頁屬性 , 修改為 可讀 | 可寫 | 可執(zhí)行 , * 避免因為內存訪問權限問題導致操作失敗* mprotect 函數(shù)只能對整個頁內存的屬性進行修改 * 每個 內存頁 大小都是 4KB */int ret = mprotect(pBase, 0x1000, PROT_WRITE | PROT_READ | PROT_EXEC);/* 修改內存頁屬性失敗的情況 */if (ret == -1) {perror("mprotect:");return -1;} #if defined(__i386__) // arm 情況處理/* E9 是 JMP 無條件跳轉指令 , 后面 4 字節(jié)是跳轉的地址 */unsigned char code[] = { 0xE9,0,0,0,0 };/* 計算 pStub 函數(shù)跳轉地址 , 目標函數(shù) pStub 地址 - 當前函數(shù) pFunc 地址 - 5 * 跳轉指令 跳轉的是 偏移量 , 不是絕對地址值*/*(unsigned*)(code + 1) = pStub - pFunc - 5;/* 將跳轉代碼拷貝到 pFunc 地址處 , 這是 pFunc 函數(shù)的入口地址 */memcpy(pFunc, code, sizeof(code)); #else // arm 情況處理/* B 無條件跳轉指令 */unsigned char code[] = { 0x04,0xF0,0x1F,0xE5,0x00,0x00,0x00,0x00 };/* arm 的跳轉是絕對地址跳轉 , 傳入 pStub 函數(shù)指針即可 */*(unsigned*)(code + 4) = (unsigned)pStub;/* 將機器碼復制到函數(shù)開始位置 */memcpy(pFunc, code, sizeof(code)); #endifreturn 0; }/* C/C++ 中的 hook 函數(shù)方式 */ void hook_func(uint8_t* pApi, uint8_t* pUser, uint8_t* pStub, size_t size) {unsigned char code[64] = { 0 };memcpy(code, pApi, size);write_code(pApi, pUser);write_code(size + pStub, size + pApi);memcpy(pStub, code, size); }總結
以上是生活随笔為你收集整理的【Android 逆向】函数拦截 ( ARM 架构下的插桩拦截 | 完整代码示例 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 逆向】函数拦截 ( 修
- 下一篇: 【Android 逆向】函数拦截实例 (