android 內聯 hook

來源:互聯網
上載者:User

標籤:add   b16   ref   不同   write   寄存器   arm   必須   ram   

先回顧下 x86 下的內聯 hook.
1.原理是找到你要 hook 的地址。
2.儲存這個地址原來的資料。(這裡要儲存至少 5 個位元組的資料因為一個 call指令為 5 個位元組
3.把這個地址修改成 call 0Xxxxx(5 個位元組 ) 也就是對應 opcode 為 E9 0Xxxxx 後面四個位元組為一個函數地址
4.填充0Xxxxx 公式為 自己的函數地址-當前地址-5
5.把原來的那個 5 個位元組的 opcode 還原重新從 hook點開始執行
arm 下
第一點有 倆種模式Arm模式與Thumb模式
在Arm版本7及以上的體系中,其指令集分為Arm指令集和Thumb指令集。Arm指令為4位元組對齊,每條指令長度均為32位;Thumb指令為2位元組對齊,又分為Thumb16、Thumb32,其中Thumb16指令長度為16位,Thumb32指令長度為32位。
第二點函數調用指令為:
B系列指令:B、BL、BX、BLX
PC寄存器 相當於 eip
第三點不這倆種模式流水線級數不同。arm一般為 3 級 。也就是說在 arm模式下 pc 指向下一條指令的向一條。因為 hook是 pc 要回退 4 個位元組(4位元組對齊)
因此對應:

LDR PC, [PC, #-4]addr

而Thumb(32位)不用回退

LDR.W PC, [PC, #0]addr

因為也就相當於 LDR.W PC, [PC, #0]/LDR PC, [PC, #-4] 對應x86 中的 call 對應 opcode
call : E9
LDR.W PC, [PC, #0]:0x00F0DFF8 (LDR.W強制以 4 位元組)
LDR PC, [PC, #-4] :0xE51FF004
後面就與 x86 方式一樣了修改地址:

x86 call 0XxxxxarmLDR PC, [PC, #-4]Thumb(32位)addrLDR.W PC, [PC, #0]addr

最後要注意一個非常容易忽略的點就是地址一般為 4 個位元組,也就是說Thumb(32位)的每條指令是 2 個位元組對齊的因此只能 2 個位元組的寫。而 arm 每條指令為 4 位元組對齊。因此應該考慮有時候只有 2 位元組,也就必須後倆個位元組用 nop填充。因為指令沒有 4 位元組對齊為非法指令。
也就是寫法為:

//開始 hook//arm 方式就一種//thumb 方式有倆種  一種是轉成arm 再 hook  一種是直接 hookstatic void doInlineHook(struct inlineHookItem *item){    //修改頁屬性    mprotect((void *) PAGE_START(CLEAR_BIT0(item->target_addr)), PAGE_SIZE * 2, PROT_READ | PROT_WRITE | PROT_EXEC);    if (item->proto_addr != NULL) {        *(item->proto_addr) = TEST_BIT0(item->target_addr) ? (uint32_t *) SET_BIT0((uint32_t) item->trampoline_instructions) : item->trampoline_instructions;    }    //Arm指令為4位元組對齊,每條指令長度均為32位;Thumb指令為2位元組對齊,    // 又分為Thumb16、Thumb32,其中Thumb16指令長度為16位,Thumb32指令長度為32位。    //這裡要注意的是:    //Arm處理器採用3級流水線來增加處理器指令流的速度,也就是說程式計數器R15(PC)總是指向“正在取指”的指令,    // 而不是指向“正在執行”的,即PC總是指向當前正在執行的指令地址再加2條指令的地址。比如當前指令地址是0×8000,    // 那麼當前pc的值,在thumb下面是0×8000 + 2*2, 在arm下面是0×8000 + 4*2。    //對於Arm指令集,跳轉指令為:    //    //LDR PC, [PC, #-4]  要回退一條    //addr    //    //LDR PC, [PC, #-4]對應的機器碼為:0xE51FF004,addr為要跳轉的地址。    //該跳轉指令範圍為32位,對於32位系統來說即為全地址跳轉。    //對於Thumb32指令集,跳轉指令為:    //    //LDR.W PC, [PC, #0]  不要回退剛好指向下一條    //addr    //    //LDR.W PC, [PC, #0]對應的機器碼為:0x00F0DFF8,addr為要跳轉的地址。同樣支援任意地址跳轉。    //thumb 模式(Thumb32指令集)為倆位元組對齊    if (TEST_BIT0(item->target_addr)) {        int i;        i = 0;        //判斷是否為4 位元組對齊 用NOP填充        if (CLEAR_BIT0(item->target_addr) % 4 != 0) {            ((uint16_t *) CLEAR_BIT0(item->target_addr))[i++] = 0xBF00;  // NOP        }        //LDR偽指令 LDR.W 強制32位        //倆個位元組為一組        //LDR.W PC, [PC, #0]對應的機器碼為:0x00F0DFF8  每次一個四位元組要分為倆個2 位元組        ((uint16_t *) CLEAR_BIT0(item->target_addr))[i++] = 0xF8DF;        ((uint16_t *) CLEAR_BIT0(item->target_addr))[i++] = 0xF000; // LDR.W PC, [PC]        //一個四位元組地址  同樣分為倆個2 位元組        //取低四位        ((uint16_t *) CLEAR_BIT0(item->target_addr))[i++] = item->new_addr & 0xFFFF;        //取高四位        ((uint16_t *) CLEAR_BIT0(item->target_addr))[i++] = item->new_addr >> 16;    }    //arm 模式  指令為4位元組對齊    else {        //四個位元組為一組        ((uint32_t *) (item->target_addr))[0] = 0xe51ff004; // LDR PC, [PC, #-4]        //下一條4位元組地址        ((uint32_t *) (item->target_addr))[1] = item->new_addr;    }    mprotect((void *) PAGE_START(CLEAR_BIT0(item->target_addr)), PAGE_SIZE * 2, PROT_READ | PROT_EXEC);    item->status = HOOKED;    cacheflush(CLEAR_BIT0(item->target_addr), CLEAR_BIT0(item->target_addr) + item->length, 0);}

源碼:
https://github.com/ele7enxxh/Android-Inline-Hook
其它部落格地址:
http://ele7enxxh.com/Android-Arm-Inline-Hook.html
https://www.cnblogs.com/mmmmar/p/8185549.html

android 內聯 hook

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.