此分支为重构分支仅支持 [Android|iOS]|[ARM64] | 转到分支MASTER(need update)
a hook framework for arm/arm64/ios/android
ref to: frida-gum and minhook and substrate.
special thanks to frida-gum perfect code and modular architecture, frida is aircraft carrier, HookZz is boat, but still with some tricks
-
Static Binary Instrumentation for Mach-O [doing]
-
GOT hook with
pre_call
&post_call
-
replace function with
replace_call
-
wrap function with
pre_call
andpost_call
-
dynamic binary instrumentation with
dbi_call
-
the power to hook short function
-
the power to access registers directly(ex:
rs->general.regs.x15
) -
runtime code patch
-
it's cute, 100kb
git clone --depth 1 git@github.com:jmpews/HookZz.git --branch master-c
mkdir build
cd build
cmake .. \
-DCMAKE_TOOLCHAIN_FILE=cmake/ios.toolchain.cmake \
-DIOS_PLATFORM=OS \
-DIOS_ARCH=arm64 \
-DENABLE_ARC=FALSE \
-DENABLE_BITCODE=OFF \
-DCXX=OFF \
-DX_ARCH=arm64 \
-DX_PLATFORM=iOS \
-DX_SHARED=ON \
-DX_LOG=ON \
-DCMAKE_VERBOSE_MAKEFILE=OFF
make
if you want generate Xcode Project, just replace with cmake -G Xcode
.
mkdir build
cd build
export ANDROID_NDK=/Users/jmpews/Library/Android/sdk/ndk-bundle
cmake .. \
-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
-DANDROID_NDK=$ANDROID_NDK \
-DCMAKE_BUILD_TYPE=Release \
-DANDROID_ABI=arm64-v8a \
-DCXX=OFF \
-DX_ARCH=arm64 \
-DX_PLATFORM=Android \
-DX_SHARED=ON \
-DX_LOG=ON \
-DCMAKE_VERBOSE_MAKEFILE=OFF
https://github.com/jmpews/HookZzAndroidDemo
this trick is used to hook short function. it will use b xxx
replace
ldr x17, #8
br x17
.long 0x1111
.long 0x1111
if you want enable near jump, just add zz_enable_near_jump();
before hook funciton, and stop with zz_disable_near_jump();
RetStatus ZzReplace(void *function_address, void *replace_call, void **origin_call);
size_t (*origin_fread)(void * ptr, size_t size, size_t nitems, FILE * stream);
size_t (fake_fread)(void * ptr, size_t size, size_t nitems, FILE * stream) {
printf("[FileMonitor|fread|model|%p] >>> %ld, %ld\n", ptr, size, nitems);
return origin_fread(ptr, size, nitems, stream);
}
void hook_fread() { ZzReplace((void *)fread, (void *)fake_fread, (void **)&origin_fread); }
RetStatus ZzWrap(void *function_address, PRECALL pre_call, POSTCALL post_call);
void open_pre_call(RegState *rs, ThreadStackPublic *tsp, CallStackPublic *csp, const HookEntryInfo *info) {
char *path = (char *)rs->ZREG(0);
int oflag = (int)rs->ZREG(1);
if (pathFilter(path))
return;
switch (oflag) {
case O_RDONLY:
printf("[FileMonitor|open|R] >>> %s\n", path);
break;
case O_WRONLY:
printf("[FileMonitor|open|W] >>> %s\n", path);
break;
case O_RDWR:
printf("[FileMonitor|open|RW] >>> %s\n", path);
break;
default:
printf("[FileMonitor|open|-] >>> %s\n", path);
break;
}
}
void open_post_call(RegState *rs, ThreadStackPublic *tsp, CallStackPublic *csp, const HookEntryInfo *info) {
}
void hook_open() { ZzWrap((void *)open, open_pre_call, open_post_call); }
RetStatus ZzDynamicBinaryInstrumentation(void *inst_address, DBICALL dbi_call);
void catchDecrypt(RegState *rs, const HookEntryInfo *info) {
printf("descrypt catch by HookZz\n");
}
__attribute__((constructor)) void initlializeTemplate() {
struct mach_header *mainHeader = (struct mach_header *)_dyld_get_image_header(0);
int slide = _dyld_get_image_vmaddr_slide(0);
uintptr_t targetVmAddr = 0x1001152BC;
uintptr_t finalAddr = targetVmAddr + slide - 0x0000000000002170;
printf(">>> ASLR: 0x%x\n", slide);
printf(">>> decrypt address: %p\n", (void *)finalAddr);
ZzDynamicBinaryInstrumentation((void *)finalAddr, catchDecrypt);
}
recommend_email: jmpews@gmail.com
QQ: 858982985