@spiderzz wrote:
前言
花了有些时间写这个 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
the power to access registers directly
hook function with
replace_call
hook function with
pre_call
andpost_call
hook address(a piece of code) with
pre_call
andhalf_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
Example
Modules
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
Posts: 1
Participants: 1