A hook framework for arm / arm64 / iOS / Android
tips: any question go to Discord
-
Static Binary Instrumentation for Mach-O [doing]
-
replace function with
replace_call
-
wrap function with
pre_call
andpost_call
-
dynamic binary instrumentation with
dbi_call
-
the power to hook short function(even single one instruction)
-
the power to access registers directly(ex:
reg_ctx->general.regs.x16
) -
it's cute, 70kb+-
Branch Type | Arch/Mode | Trampoline Assembly | Bytes | Range |
---|---|---|---|---|
- | ARM64 | B xxx |
4 | +-(1<<25) |
- | ARM64 | LDR x17, 8 BR x17 .long 0x41414141 .long 0x41414141 |
16 | (1<<64) |
- | ARM/ARM | B xxx |
4 | +-(1<<25) |
- | ARM/ARM | LDR pc, [pc, #-4] .long 0x41414141 |
8 | (1<<32) |
- | ARM/Thumb1 | B xxx |
2 | +-(1<<10) |
- | ARM/Thumb2 | B xxx |
4 | +-(1<<23) |
- | ARM/Thumb2 | LDR pc, [pc, #-[2|4] .long 0x41414141 |
8 | (1<<32) |
git clone --depth 1 [email protected]:jmpews/HookZz.git
# 1: not recommend
export CFLAGS="-DIOS -arch arm64 -miphoneos-version-min=6.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk"
cmake .. \
-DPLATFORM=iOS \
-DARCH=arm64 \
-DSHARED=ON \
-DCMAKE_OSX_SYSROOT="" \
-DCMAKE_BUILD_TYPE=Release
# 2: recommend
cmake .. \
-DCMAKE_TOOLCHAIN_FILE=cmake/ios.toolchain.cmake \
-DIOS_PLATFORM=OS \
-DIOS_ARCH=arm64 \
-DENABLE_ARC=FALSE \
-DENABLE_BITCODE=OFF \
-DDEBUG=OFF \
-DSHARED=ON \
-DPLATFORM=iOS \
-DARCH=armv8 \
-DCMAKE_BUILD_TYPE=Release
make -j4
if you want generate Xcode Project, just replace with cmake -G Xcode
.
export ANDROID_NDK=/Users/jmpews/Library/Android/sdk/ndk-bundle
cmake .. \
-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
-DCMAKE_BUILD_TYPE=Release \
-DANDROID_ABI="armeabi-v7a" \
-DANDROID_STL=c++_static \
-DANDROID_NATIVE_API_LEVEL=android-14 \
-DDEBUG=OFF \
-DSHARED=ON
make -j4
when should i use?
#define FAKE(func) fake_##func
#define ORIG(func) orig_##func
void hook_demo() {
zz_enable_arm_arm64_b_branch();
// find the `AES_set_encrypt_key` symbol address by yourself
int ret = ZzReplace((void *)AES_set_encrypt_key, (void *)FAKE(AES_set_encrypt_key), (void **)&ORIG(AES_set_encrypt_key));
zz_disable_arm_arm64_b_branch();
}
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) {
// Do What you Want.
return origin_fread(ptr, size, nitems, stream);
}
void hook_fread() {
ZzReplace((void *)fread, (void *)fake_fread, (void **)&origin_fread);
}
void common_pre_call(RegisterContext *reg_ctx, const HookEntryInfo *info)
{
printf("common pre call\n");
}
void hook_open() {
ZzWrap((void *)open, common_pre_call, NULL);
}
void catchDecrypt(RegisterContext *reg_ctx, 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;
ZzDynamicBinaryInstrumentation((void *)finalAddr, catchDecrypt);
}
- not fixed
pld