首页
社区
课程
招聘
[原创] HookZz 一款有些不一样的 Hook 框架
发表于: 2017-9-1 12:19 19121

[原创] HookZz 一款有些不一样的 Hook 框架

2017-9-1 12:19
19121

前言

花了有些时间写这个 hookzz 框架. 白话文说下, 单指令的 hook, 无惧短函数和不定参数函数, 可以 hook 指令地址(指令片段), 可以 RuntimeCodePatch, 还有很多其他玩法. Move to HookZz

下面直接复制粘贴 README.md 了.

HookZzModules 是基于 HookZz 搞得一些模块. 可以在更方便的在 反调试 / hook_objc_msgSend / hook_MGCopyAnswer 做一些工作.

如果希望了解原理请 Move to HookFrameworkDesign

What is HookZz ?

a cute hook framwork.

still developing, for arm64/IOS now!

ref to: frida-gum and minhook and substrate.

special thanks to frida-gum's perfect code and modular architecture, frida is aircraft carrier, HookZz is boat.

Features

  • HookZz-Modules help you to hook.
  • the power to access registers directly
  • hook function with replace_call
  • hook function with pre_call and post_call
  • hook address(a piece of code) with pre_call and half_call
  • (almost)only one instruction to hook(i.e.hook short funciton, even only one instruction)
  • runtime code patch, without codesign limit
  • it's cute

Getting Started

Move to HookZz Getting Started

How it works ?

Move to HookFrameworkDesign.md

Docs

Move to HookZz docs

Example

Move to HookZz example

Modules

Move to HookZzModules

Quick Example No.1

Read It Carefully!

#include "hookzz.h"
#include <string.h>
#include <stdarg.h>
#include <stdio.h>

int (*orig_printf)(const char * restrict format, ...);
int fake_printf(const char * restrict format, ...) {
    puts("call printf");

    char *stack[16];
    va_list args;
    va_start(args, format);
    memcpy(stack, args, 8 * 16);
    va_end(args);

    // how to hook variadic function? fake a original copy stack.
    // [move to detail-1](56bK9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3A6E0M7r3g2%4M7#2)9J5k6h3N6A6N6r3S2#2j5W2)9J5k6h3W2G2i4K6u0r3x3U0l9I4y4#2)9J5c8U0l9^5i4K6u0r3x3U0W2Q4x3V1k6H3N6$3&6Q4x3V1k6Q4x3U0g2q4y4#2)9J5y4e0W2r3i4K6t1#2b7f1c8Q4x3U0g2q4y4g2)9J5y4e0R3%4i4K6t1#2b7V1c8Q4x3U0g2q4y4W2)9J5y4e0V1#2i4K6t1#2b7U0m8Q4x3U0g2q4y4g2)9J5y4e0V1J5i4K6t1#2z5p5y4Q4x3U0g2q4y4q4)9J5y4f1t1^5i4K6t1#2z5p5c8Q4x3U0g2q4y4g2)9J5y4f1q4q4i4K6t1#2z5f1q4Q4x3U0g2q4y4g2)9J5y4e0S2r3i4K6t1#2z5o6u0Q4x3U0g2q4y4W2)9J5y4e0V1#2i4K6t1#2b7U0m8Q4x3U0g2q4y4#2)9J5y4e0W2m8i4K6t1#2z5o6c8Z5L8$3!0C8i4K6u0r3i4K6t1&6
    // [move to detail-2](5e2K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6B7L8i4m8W2N6%4y4Q4x3V1k6t1L8$3!0C8h3Y4A6y4L8$3c8#2L8r3g2K6i4K6u0r3N6s2u0W2k6g2)9J5c8X3#2S2M7%4c8W2M7W2)9J5c8V1q4F1N6r3W2p5k6h3u0#2k6@1u0&6M7r3q4K6M7#2)9J5z5b7`.`.
    int x = orig_printf(format, stack[0], stack[1], stack[2], stack[3], stack[4], stack[5], stack[6], stack[7], stack[8], stack[9], stack[10], stack[11], stack[12], stack[13], stack[14], stack[15]);
    return x;
}

void printf_pre_call(RegState *rs, ThreadStack *threadstack, CallStack *callstack) {
    puts((char *)rs->general.regs.x0);
    STACK_SET(callstack, "format", rs->general.regs.x0, char *);
    puts("printf-pre-call");
}

void printf_post_call(RegState *rs, ThreadStack *threadstack, CallStack *callstack) {
    if(STACK_CHECK_KEY(callstack, "format")) {
        char *format = STACK_GET(callstack, "format", char *);
        puts(format);
    }
    puts("printf-post-call");
}

__attribute__((constructor)) void test_hook_printf()
{
    void *printf_ptr = (void *)printf;

    ZzBuildHook((void *)printf_ptr, (void *)fake_printf, (void **)&orig_printf, printf_pre_call, printf_post_call);
    ZzEnableHook((void *)printf_ptr);
    printf("HookZzzzzzz, %d, %p, %d, %d, %d, %d, %d, %d, %d\n",1, (void *)2, 3, (char)4, (char)5, (char)6 , 7, 8 , 9);
}

breakpoint with lldb. Read It Carefully!

(lldb) disass -s 0x1815f61d8 -c 3
libsystem_c.dylib`printf:
    0x1815f61d8 <+0>: sub    sp, sp, #0x30             ; =0x30 
    0x1815f61dc <+4>: stp    x20, x19, [sp, #0x10]
    0x1815f61e0 <+8>: stp    x29, x30, [sp, #0x20]
(lldb) c
Process 41408 resuming
HookZzzzzzz, %d, %p, %d, %d, %d, %d, %d, %d, %d

printf-pre-call
call printf
HookZzzzzzz, 1, 0x2, 3, 4, 5, 6, 7, 8, 9
HookZzzzzzz, %d, %p, %d, %d, %d, %d, %d, %d, %d

printf-post-call
(lldb) disass -s 0x1815f61d8 -c 3
libsystem_c.dylib`printf:
    0x1815f61d8 <+0>: b      0x1795f61d8
    0x1815f61dc <+4>: stp    x20, x19, [sp, #0x10]
    0x1815f61e0 <+8>: stp    x29, x30, [sp, #0x20]

Quick Example No.2

Read It Carefully!

#include "hookzz.h"
#include <stdio.h>
#include <unistd.h>

static void hack_this_function()
{
#ifdef __arm64__
    __asm__("mov X0, #0\n"
            "mov w16, #20\n"
            "svc #0x80");
#endif
}

static void sorry_to_exit()
{
#ifdef __arm64__
    __asm__("mov X0, #0\n"
            "mov w16, #1\n"
            "svc #0x80");
#endif
}

void getpid_pre_call(RegState *rs, ThreadStack *threadstack, CallStack *callstack) {
    unsigned long request = *(unsigned long *)(&rs->general.regs.x16);
    printf("request(x16) is: %ld\n", request);
    printf("x0 is: %ld\n", (long)rs->general.regs.x0);
}

void getpid_half_call(RegState *rs, ThreadStack *threadstack, CallStack *callstack) {
    pid_t x0 = (pid_t)(rs->general.regs.x0);
    printf("getpid() return at x0 is: %d\n", x0);
}

__attribute__((constructor)) void test_hook_address()
{
    void *hack_this_function_ptr = (void *)hack_this_function;
    ZzBuildHookAddress(hack_this_function_ptr + 8, hack_this_function_ptr + 12, getpid_pre_call, getpid_half_call);
    ZzEnableHook((void *)hack_this_function_ptr + 8);

    void *sorry_to_exit_ptr = (void *)sorry_to_exit;
    unsigned long nop_bytes = 0xD503201F;
    ZzRuntimeCodePatch((unsigned long)sorry_to_exit_ptr + 8, (zpointer)&nop_bytes, 4);

    hack_this_function();
    sorry_to_exit();

    printf("hack success -.0\n");
}

breakpoint with lldb. Read It Carefully!

(lldb) disass -n hack_this_function
test_hook_address.dylib`hack_this_function:
    0x1000b0280 <+0>:  mov    x0, #0x0
    0x1000b0284 <+4>:  mov    w16, #0x14
    0x1000b0288 <+8>:  svc    #0x80
    0x1000b028c <+12>: ret    

(lldb) disass -n sorry_to_exit
test_hook_address.dylib`sorry_to_exit:
    0x1000b0290 <+0>:  mov    x0, #0x0
    0x1000b0294 <+4>:  mov    w16, #0x1
    0x1000b0298 <+8>:  svc    #0x80
    0x1000b029c <+12>: ret    

(lldb) c
Process 41414 resuming
request(x16) is: 20
x0 is: 0
getpid() return at x0 is: 41414
hack success -.0
(lldb) disass -n hack_this_function
test_hook_address.dylib`hack_this_function:
    0x1000b0280 <+0>:  mov    x0, #0x0
    0x1000b0284 <+4>:  mov    w16, #0x14
    0x1000b0288 <+8>:  b      0x1001202cc
    0x1000b028c <+12>: ret    

(lldb) disass -n sorry_to_exit
test_hook_address.dylib`sorry_to_exit:
    0x1000b0290 <+0>:  mov    x0, #0x0
    0x1000b0294 <+4>:  mov    w16, #0x1
    0x1000b0298 <+8>:  nop    
    0x1000b029c <+12>: ret

[培训]科锐逆向工程师培训第53期2025年7月8日开班!

收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
7a7K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6B7L8i4m8W2N6%4y4Q4x3X3g2Y4K9i4c8Z5N6h3u0Q4x3X3g2A6L8#2)9J5c8Y4A6*7M7s2m8Q4x3V1k6Y4k6i4c8@1K9h3&6Y4i4K6u0V1M7%4c8S2M7Y4c8W2k6q4)9J5c8W2)9J5y4X3&6T1M7%4m8Q4x3@1t1`. 这个文档里面第三步(3.  test  your  demo  dylib)里面的脚本最后一行的/Users/jmpews/Desktop/SpiderZz/Pwntools/Darwin/bin/optool  是个什么东东?
2017-10-5 11:23
0
雪    币: 155
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
只支持64位?
2017-10-10 18:30
0
雪    币: 120
活跃值: (1738)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
4
enlangs 只支持64位?
最近会上  thumb/arm  的,  可以看一下  dev  分支. 
2017-10-10 19:42
0
雪    币: 155
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
jmpews 最近会上 thumb/arm 的, 可以看一下 dev 分支.
好的。
2017-10-11 09:14
0
雪    币: 2791
活跃值: (1736)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
支持安卓吗
2018-1-26 23:21
0
雪    币: 220
活跃值: (4078)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
7
jmpews 最近会上 thumb/arm 的, 可以看一下 dev 分支.
    ZzBuildHook((module_base+0x3264),  (void  *)&new_sub_100009774,  (void  **)&old_sub_100009774,  NULL,  NULL); 
            ZzEnableHook((void  *)(module_base+0x3264));    这样使用对么,,看字节已经修改
2018-1-30 18:13
0
雪    币: 1136
活跃值: (2238)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
8
English  is  so  hard  that  i  can  only  copy  testhookzz  to  Android  for  test  QAQ!
func  name  is  too  abstract
2018-3-26 12:39
0
游客
登录 | 注册 方可回帖
返回