• Хук функции в Android shared object?

    @MichaelOne Автор вопроса
    jcmvbkbc, очень странно, но при пошаговом выполнении кода - то есть установке брейкпоинта на ARMHook функцию и пошаговом выполнении с отслеживанием изменений в коде CoolFunc - выявило, что патчится код замечательно и управление переходит на мою функцию как и надо. Однако, если я не выполняю код пошагово и просто ставлю брейкпоинт на CoolFunc, которая вызывается уже после установки хука функцией "hook", то хук применяется "частично" - как я описывал выше, то есть не заменяется опкод бранча, со всеми вытекающими последствиями.
    Очень странное и нестабильное поведение получается, из-за чего я не могу понять где и в чём именно проблема.
  • Хук функции в Android shared object?

    @MichaelOne Автор вопроса
    Дамп из gdb под спойлером:
    spoiler
    Dump of assembler code for function ARMHook(unsigned int, unsigned int):
       0x9741d958 <+0>:     push    {r11, lr}
       0x9741d95c <+4>:     mov     r11, sp
       0x9741d960 <+8>:     sub     sp, sp, #96, 0  ; 0x60
       0x9741d964 <+12>:    sub     r2, r11, #14, 0
       0x9741d968 <+16>:    ldr     r3, [pc, #500]  ; 0x9741db64 <ARMHook(unsigned int, unsigned int)+524>
       0x9741d96c <+20>:    add     r3, pc, r3
       0x9741d970 <+24>:    ldr     r12, [pc, #500] ; 0x9741db6c <ARMHook(unsigned int, unsigned int)+532>
       0x9741d974 <+28>:    ldr     r12, [pc, r12]
       0x9741d978 <+32>:    ldr     r12, [r12]
       0x9741d97c <+36>:    str     r12, [r11, #-4]
       0x9741d980 <+40>:    str     r0, [sp, #24]
       0x9741d984 <+44>:    str     r1, [r11, #-20] ; 0xffffffec
    => 0x9741d988 <+48>:    ldrb    r0, [r3]
       0x9741d98c <+52>:    strb    r0, [r11, #-14]
       0x9741d990 <+56>:    ldrb    r0, [r3, #1]
       0x9741d994 <+60>:    strb    r0, [r11, #-13]
       0x9741d998 <+64>:    ldrb    r0, [r3, #2]
       0x9741d99c <+68>:    strb    r0, [r11, #-12]
       0x9741d9a0 <+72>:    ldrb    r0, [r3, #3]
       0x9741d9a4 <+76>:    strb    r0, [r11, #-11]
       0x9741d9a8 <+80>:    ldrb    r0, [r3, #4]
       0x9741d9ac <+84>:    strb    r0, [r11, #-10]
       0x9741d9b0 <+88>:    ldrb    r0, [r3, #5]
       0x9741d9b4 <+92>:    strb    r0, [r11, #-9]
       0x9741d9b8 <+96>:    ldrb    r0, [r3, #6]
    --Type <RET> for more, q to quit, c to continue without paging--c
       0x9741d9bc <+100>:   strb    r0, [r11, #-8]
       0x9741d9c0 <+104>:   ldrb    r0, [r3, #7]
       0x9741d9c4 <+108>:   strb    r0, [r11, #-7]
       0x9741d9c8 <+112>:   ldrb    r0, [r3, #8]
       0x9741d9cc <+116>:   strb    r0, [r11, #-6]
       0x9741d9d0 <+120>:   ldrb    r0, [r3, #9]
       0x9741d9d4 <+124>:   strb    r0, [r11, #-5]
       0x9741d9d8 <+128>:   add     r0, r2, #6, 0
       0x9741d9dc <+132>:   sub     r1, r11, #20, 0
       0x9741d9e0 <+136>:   str     r0, [sp, #44]   ; 0x2c
       0x9741d9e4 <+140>:   movw    r0, #4
       0x9741d9e8 <+144>:   str     r0, [sp, #40]   ; 0x28
       0x9741d9ec <+148>:   str     r1, [sp, #36]   ; 0x24
       0x9741d9f0 <+152>:   str     r0, [sp, #32]
       0x9741d9f4 <+156>:   ldr     r0, [sp, #40]   ; 0x28
       0x9741d9f8 <+160>:   str     r0, [sp, #28]
       0x9741d9fc <+164>:   ldr     r0, [sp, #28]
       0x9741da00 <+168>:   cmn     r0, #1, 0
       0x9741da04 <+172>:   beq     0x9741da24 <ARMHook(unsigned int, unsigned int)+204>
       0x9741da08 <+176>:   ldr     r0, [sp, #44]   ; 0x2c
       0x9741da0c <+180>:   ldr     r1, [sp, #36]   ; 0x24
       0x9741da10 <+184>:   ldr     r2, [sp, #32]
       0x9741da14 <+188>:   ldr     r3, [sp, #28]
       0x9741da18 <+192>:   bl      0x9741cdf4 <__memcpy_chk@plt>
       0x9741da1c <+196>:   str     r0, [sp, #48]   ; 0x30
       0x9741da20 <+200>:   b       0x9741da40 <ARMHook(unsigned int, unsigned int)+232>
       0x9741da24 <+204>:   ldr     r0, [sp, #44]   ; 0x2c
       0x9741da28 <+208>:   ldr     r1, [sp, #36]   ; 0x24
       0x9741da2c <+212>:   ldr     r2, [sp, #32]
       0x9741da30 <+216>:   str     r0, [sp, #16]
       0x9741da34 <+220>:   bl      0x9741ce00 <memcpy@plt>
       0x9741da38 <+224>:   ldr     r0, [sp, #16]
       0x9741da3c <+228>:   str     r0, [sp, #48]   ; 0x30
       0x9741da40 <+232>:   ldr     r0, [pc, #288]  ; 0x9741db68 <ARMHook(unsigned int, unsigned int)+528>
       0x9741da44 <+236>:   ldr     r1, [sp, #24]
       0x9741da48 <+240>:   and     r1, r1, r0
       0x9741da4c <+244>:   ldr     r2, [sp, #24]
       0x9741da50 <+248>:   add     r2, r2, #10, 0
       0x9741da54 <+252>:   movw    r3, #4095       ; 0xfff
       0x9741da58 <+256>:   add     r2, r2, r3
       0x9741da5c <+260>:   and     r2, r2, r0
       0x9741da60 <+264>:   ldr     r3, [sp, #24]
       0x9741da64 <+268>:   and     r0, r3, r0
       0x9741da68 <+272>:   sub     r0, r2, r0
       0x9741da6c <+276>:   str     r0, [sp, #12]
       0x9741da70 <+280>:   mov     r0, r1
       0x9741da74 <+284>:   ldr     r1, [sp, #12]
       0x9741da78 <+288>:   movw    r2, #2
       0x9741da7c <+292>:   bl      0x9741cde8 <mprotect@plt>
       0x9741da80 <+296>:   mvn     r1, #0, 0
       0x9741da84 <+300>:   ldr     r2, [sp, #24]
       0x9741da88 <+304>:   sub     r3, r11, #14, 0
       0x9741da8c <+308>:   str     r2, [r11, #-28] ; 0xffffffe4
       0x9741da90 <+312>:   str     r1, [r11, #-32] ; 0xffffffe0
       0x9741da94 <+316>:   str     r3, [r11, #-36] ; 0xffffffdc
       0x9741da98 <+320>:   movw    r1, #10
       0x9741da9c <+324>:   str     r1, [r11, #-40] ; 0xffffffd8
       0x9741daa0 <+328>:   ldr     r1, [r11, #-32] ; 0xffffffe0
       0x9741daa4 <+332>:   str     r1, [r11, #-44] ; 0xffffffd4
       0x9741daa8 <+336>:   ldr     r1, [r11, #-44] ; 0xffffffd4
       0x9741daac <+340>:   cmn     r1, #1, 0
       0x9741dab0 <+344>:   beq     0x9741dad0 <ARMHook(unsigned int, unsigned int)+376>
       0x9741dab4 <+348>:   ldr     r0, [r11, #-28] ; 0xffffffe4
       0x9741dab8 <+352>:   ldr     r1, [r11, #-36] ; 0xffffffdc
       0x9741dabc <+356>:   ldr     r2, [r11, #-40] ; 0xffffffd8
       0x9741dac0 <+360>:   ldr     r3, [r11, #-44] ; 0xffffffd4
       0x9741dac4 <+364>:   bl      0x9741cdf4 <__memcpy_chk@plt>
       0x9741dac8 <+368>:   str     r0, [r11, #-24] ; 0xffffffe8
       0x9741dacc <+372>:   b       0x9741daec <ARMHook(unsigned int, unsigned int)+404>
       0x9741dad0 <+376>:   ldr     r0, [r11, #-28] ; 0xffffffe4
       0x9741dad4 <+380>:   ldr     r1, [r11, #-36] ; 0xffffffdc
       0x9741dad8 <+384>:   ldr     r2, [r11, #-40] ; 0xffffffd8
       0x9741dadc <+388>:   str     r0, [sp, #8]
       0x9741dae0 <+392>:   bl      0x9741ce00 <memcpy@plt>
       0x9741dae4 <+396>:   ldr     r0, [sp, #8]
       0x9741dae8 <+400>:   str     r0, [r11, #-24] ; 0xffffffe8
       0x9741daec <+404>:   ldr     r0, [pc, #116]  ; 0x9741db68 <ARMHook(unsigned int, unsigned int)+528>
       0x9741daf0 <+408>:   ldr     r1, [sp, #24]
       0x9741daf4 <+412>:   ldr     r2, [sp, #24]
       0x9741daf8 <+416>:   add     r2, r2, #10, 0
       0x9741dafc <+420>:   str     r0, [sp, #4]
       0x9741db00 <+424>:   mov     r0, r1
       0x9741db04 <+428>:   mov     r1, r2
       0x9741db08 <+432>:   bl      0x9741f2b0 <__clear_cache>
       0x9741db0c <+436>:   ldr     r0, [sp, #24]
       0x9741db10 <+440>:   ldr     r1, [sp, #4]
       0x9741db14 <+444>:   and     r0, r0, r1
       0x9741db18 <+448>:   ldr     r2, [sp, #24]
       0x9741db1c <+452>:   add     r2, r2, #10, 0
       0x9741db20 <+456>:   movw    r3, #4095       ; 0xfff
       0x9741db24 <+460>:   add     r2, r2, r3
       0x9741db28 <+464>:   and     r2, r2, r1
       0x9741db2c <+468>:   ldr     r3, [sp, #24]
       0x9741db30 <+472>:   and     r3, r3, r1
       0x9741db34 <+476>:   sub     r1, r2, r3
       0x9741db38 <+480>:   movw    r2, #4
       0x9741db3c <+484>:   bl      0x9741cde8 <mprotect@plt>
       0x9741db40 <+488>:   ldr     r1, [pc, #40]   ; 0x9741db70 <ARMHook(unsigned int, unsigned int)+536>
       0x9741db44 <+492>:   ldr     r1, [pc, r1]
       0x9741db48 <+496>:   ldr     r1, [r1]
       0x9741db4c <+500>:   ldr     r2, [r11, #-4]
       0x9741db50 <+504>:   cmp     r1, r2
       0x9741db54 <+508>:   bne     0x9741db60 <ARMHook(unsigned int, unsigned int)+520>
       0x9741db58 <+512>:   mov     sp, r11
       0x9741db5c <+516>:   pop     {r11, pc}
       0x9741db60 <+520>:   bl      0x9741cdd0 <__stack_chk_fail@plt>
       0x9741db64 <+524>:                   ; <UNDEFINED> instruction: 0x000021b6
       0x9741db68 <+528>:                   ; <UNDEFINED> instruction: 0xfffff000
       0x9741db6c <+532>:   andeq   r3, r0, r4, asr #11
       0x9741db70 <+536>:   strdeq  r3, [r0], -r4
    End of assembler dump.
  • Хук функции в Android shared object?

    @MichaelOne Автор вопроса
    jcmvbkbc, увидел ошибку, исправил. Неверно переписал, извиняюсь.
    Сегфолта теперь нет, однако инструкция так же не перезаписывается :(

    Дамп переменной hookProc:
    0xbe8e250a:     0x00f046fa      0xab385ff8      0x17cf977e      0x2538f098

    Дамп 4 блоков по 4 байта, поэтому в конце "мусор".
    Переменная function равна 0x977eab38.
  • Хук функции в Android shared object?

    @MichaelOne Автор вопроса
    jcmvbkbc, опечатался, в коде без повторов всё, конечно же:
    mprotect((void*)(address & 0xFFFFF000), ((address + sizeof(hookProc) + 0xfff) & 0xfffff000) - (address - 0xfffff000), PROT_READ | PROT_WRITE | PROT_EXEC);
  • Хук функции в Android shared object?

    @MichaelOne Автор вопроса
    Спасибо большое, за ответ!
    Изменил &hookProc[6] на memcpy, а также mprotect на приведённый тобой вариант. Теперь при попытке копирования
    memcpy((void*)address, (void*)hookProc, sizeof(hookProc));
    происходит segfault. Подозреваю, что из-за отсутствия прав на запись по указанному адресу.
    То есть изменённый код выглядит так:
    memcpy(hookProc + 6, &function, sizeof(function));  // Заменить 4 байта нужным адресом.
    mprotect((void*)(address & 0xFFFFF000), (void*)(address & 0xFFFFF000), ((address + sizeof(hookProc) + 0xfff) & 0xfffff000) - (address & 0xfffff000), PROT_READ | PROT_WRITE);
    // "снять защиту" с участка памяти чтобы иметь возможность записи туда.
    memcpy((void*)address, (void*)hookProc, sizeof(hookProc));
    // Скопировать код хука по указанному адресу.
    __builtin___clear_cache((char*)address, (char*)(address + sizeof(hookProc)));
    // ClearCache в версии для андроида.
    mprotect((void*)(address & 0xFFFFF000), (void*)(address & 0xFFFFF000), ((address + sizeof(hookProc) + 0xfff) & 0xfffff000) - (address & 0xfffff000), PROT_READ | PROT_EXEC);


    Дамп памяти до предложенных изменений:
    Дизассемблированный код:
    80 b5           push       { r7, lr }
    6f 46           mov        r7,sp
    2e f5 38 eb     blx        CoolFunction
    00 28           cmp        param_1,#0x0
    0c bf           itE        eq

    Вывод gdb до записи:
    0x949474e0 <_Z12CoolFunction>:        0x466fb580      0xeb38f52e      0xbf0c2800

    после записи:
    0x949474e0 <_Z12CoolFunction>:        0x00f046fa      0xeb38f52e      0xbf0c9503

    Переменная function по адресу 0x95036b38, адрес установки хука, адрес CoolFunction, 0x949474e0.
    Видно, что середина "пропущена".