前言 花了有些时间写这个 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](http://jmpews.github.io/2017/08/29/pwn/%E7%9F%AD%E5%87%BD%E6%95%B0%E5%92%8C%E4%B8%8D%E5%AE%9A%E5%8F%82%E6%95%B0%E7%9A%84hook/)
// [move to detail-2](https://github.com/jmpews/HookZzModules/tree/master/AntiDebugBypass)
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
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!