shadowhook is an inline hook library for Android apps.

android-inline-hook

README 中文版

shadowhook is an inline hook library for Android apps.

shadowhook is a module of "the android-inline-hook project".

Features

  • Support Android 4.1 - 12 (API level 16 - 31).
  • Support armeabi-v7a and arm64-v8a.
  • Support hook for the whole function, but does not support hook for the middle position of the function.
  • Support to specify the hook location by "function address" or "library name + function name".
  • Automatically complete the hook of "newly loaded dynamic library" (only "library name + function name"), and call the optional callback function after the hook is completed.
  • Multiple hooks and unhooks can be executed concurrently on the same hook point without interfering with each other (only in shared mode).
  • Automatically avoid possible recursive calls and circular calls between proxy functions (only in shared mode).
  • The proxy function supports unwinding backtrace in a normal way.
  • Integrated symbol address search function.
  • MIT licensed.

Documentation

shadowhook Manual

Quick Start

You can refer to the sample app in app module, or refer to the hook/unhook examples of commonly used system functions in systest module.

1. Add dependency in build.gradle

shadowhook is published on Maven Central, and uses Prefab package format for native dependencies, which is supported by Android Gradle Plugin 4.0+.

allprojects {
    repositories {
        mavenCentral()
    }
}
android {
    buildFeatures {
        prefab true
    }
}

dependencies {
    implementation 'com.bytedance.android:shadowhook:1.0.2'
}

2. Add dependency in CMakeLists.txt or Android.mk

CMakeLists.txt

find_package(shadowhook REQUIRED CONFIG)

add_library(mylib SHARED mylib.c)
target_link_libraries(mylib shadowhook::shadowhook)

Android.mk

include $(CLEAR_VARS)
LOCAL_MODULE           := mylib
LOCAL_SRC_FILES        := mylib.c
LOCAL_SHARED_LIBRARIES += shadowhook
include $(BUILD_SHARED_LIBRARY)

$(call import-module,prefab/shadowhook)

3. Specify one or more ABI(s) you need

android {
    defaultConfig {
        ndk {
            abiFilters 'armeabi-v7a', 'arm64-v8a'
        }
    }
}

4. Add packaging options

If you are using shadowhook in an SDK project, you may need to avoid packaging lib shadowhook.so into your AAR, so as not to encounter duplicate lib shadowhook.so file when packaging the app project.

android {
    packagingOptions {
        exclude '**/libshadowhook.so'
    }
}

On the other hand, if you are using shadowhook in an APP project, you may need to add some options to deal with conflicts caused by duplicate libshadowhook.so file.

android {
    packagingOptions {
        pickFirst '**/libshadowhook.so'
    }
}

5. Initialize

shadowhook supports two modes (shared mode and unique mode). The proxy function in the two modes is written slightly differently. You can try the unique mode first.

import com.bytedance.shadowhook.ShadowHook;

public class MySdk {
    public static void init() {
        ShadowHook.init(new ShadowHook.ConfigBuilder()
            .setMode(ShadowHook.Mode.UNIQUE)
            .build());
    }
}

6. Hook and Unhook

#include "shadowhook.h"

void *shadowhook_hook_sym_addr(
    void *sym_addr,
    void *new_addr,
    void **orig_addr);

void *shadowhook_hook_sym_name(
    const char *lib_name,
    const char *sym_name,
    void *new_addr,
    void **orig_addr);

typedef void (*shadowhook_hooked_t)(
    int error_number,
    const char *lib_name,
    const char *sym_name,
    void *sym_addr,
    void *new_addr,
    void *orig_addr,
    void *arg);

void *shadowhook_hook_sym_name_callback(
    const char *lib_name,
    const char *sym_name,
    void *new_addr,
    void **orig_addr,
    shadowhook_hooked_t hooked,
    void *hooked_arg);

int shadowhook_unhook(void *stub);
  • shadowhook_hook_sym_addr: hook a function address.
  • shadowhook_hook_sym_name: hook the symbol name of a function in a dynamic library.
  • shadowhook_hook_sym_name_callback: Similar to shadowhook_hook_sym_name, but the specified callback function will be called after the hook is completed.
  • shadowhook_unhook: unhook.

For example, let's try to hook art::ArtMethod::Invoke:

void *orig = NULL;
void *stub = NULL;

typedef void (*type_t)(void *, void *, uint32_t *, uint32_t, void *, const char *);

void proxy(void *thiz, void *thread, uint32_t *args, uint32_t args_size, void *result, const char *shorty)
{
    // do something
    ((type_t)orig)(thiz, thread, args, args_size, result, shorty);
    // do something
}

void do_hook()
{
    stub = shadowhook_hook_sym_name(
               "libart.so",
               "_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc",
               (void *)proxy,
               (void **)&orig);
    
    if(stub == NULL)
    {
        int err_num = shadowhook_get_errno();
        const char *err_msg = shadowhook_to_errmsg(err_num);
        LOG("hook error %d - %s", err_num, err_msg);
    }
}

void do_unhook()
{
    shadowhook_unhook(stub);
    stub = NULL;
}
  • _ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc is the function symbol name of art::ArtMethod::Invoke processed by C++ Name Mangler in libart.so. You can use readelf to view it. The C function does not have the concept of Name Mangler.
  • The symbol name of art::ArtMethod::Invoke is different in previous versions of Android M. This example is only applicable to Android M and later versions. If you want to achieve better Android version compatibility, you need to handle the difference in function symbol names yourself.

Contributing

Contributing Guide

License

shadowhook is licensed by MIT License.

shadowhook uses the following third-party source code or libraries:

  • queue.h
    BSD 3-Clause License
    Copyright (c) 1991, 1993 The Regents of the University of California.
  • tree.h
    BSD 2-Clause License
    Copyright (c) 2002 Niels Provos [email protected]
  • linux-syscall-support
    BSD 3-Clause License
    Copyright (c) 2005-2011 Google Inc.
  • xDL
    MIT License
    Copyright (c) 2020-2021 HexHacking Team
Comments
  • proxy函数没用调用

    proxy函数没用调用

    ShadowHook Version

    1.0.3

    Android OS Version

    11

    Android ABIs

    armeabi-v7a, arm64-v8a

    Device Manufacturers and Models

    pixel2xL

    Describe the Bug

    demo里面hook了 android_get_device_api_level, 结果显示hook成功了,但是proxy没有执行。请问是使用不对么。

    cStub = shadowhook_hook_sym_name(
                "libc.so",
                "android_get_device_api_level",
                (void *) cProxy,
                nullptr
        );
    
        if(cStub != nullptr) {
            LOGE("libc hook成功");
        } else{
            LOGE("libc hook失败");
        }
    
    void* cProxy() {
        LOGE("cproxy");
    }
    

    libc.so里面符号表里也是这个: image

  • hook 递归调用的函数崩溃

    hook 递归调用的函数崩溃

    ShadowHook Version

    1.0.3

    Android OS Version

    8.0.1

    Android ABIs

    arm64-v8a

    Device Manufacturers and Models

    Samung Galaxy

    Describe the Bug

    正常情况下函数调用链 A->B->C->B->.....,此时hook B函数,hook的函数体没有做任何操作,直接调用原始方法,在经过C再次进入B之后崩溃,实际hook的是libart的DexFile::Open 错误信息: 2022-06-16 09:25:18.291 A/DEBUG: signal 4 (SIGILL), code 1 (ILL_ILLOPC), fault addr 0x7a02bbf204 2022-06-16 09:25:18.291 A/DEBUG: x0 0000000000000001 x1 000000000000008c x2 00000079f580e7a8 x3 000000008bd76d86 2022-06-16 09:25:18.291 A/DEBUG: x4 00000079f580e7a0 x5 0000000000000000 x6 0000000000000000 x7 0000007fe61a09e8 2022-06-16 09:25:18.291 A/DEBUG: x8 0000007a02bbf200 x9 0000000000000001 x10 000000000000019f x11 0000000000000003 2022-06-16 09:25:18.291 A/DEBUG: x12 0000007a0060d708 x13 2e7265746c696631 x14 000d7c633a084230 x15 0000a8a620ea48ae 2022-06-16 09:25:18.291 A/DEBUG: x16 0000007a00eb3cc0 x17 00000079d6834608 x18 0000000000000000 x19 0000007fe61a09e8 2022-06-16 09:25:18.291 A/DEBUG: x20 00000079f580e7a0 x21 0000007fe61a09d8 x22 0000007a0277e0f4 x23 0000007a0277e048 2022-06-16 09:25:18.291 A/DEBUG: x24 0000007fe61a0bc0 x25 0000007a0277e048 x26 0000000000000001 x27 0000007a006d78a0 2022-06-16 09:25:18.291 A/DEBUG: x28 0000007a0277e0f4 x29 0000007fe61a0990 x30 0000007a003b6fcc 2022-06-16 09:25:18.291 A/DEBUG: sp 0000007fe61a0960 pc 0000007a02bbf204 pstate 0000000000000000 2022-06-16 09:25:18.291 A/DEBUG: backtrace: 2022-06-16 09:25:18.291 A/DEBUG: #00 pc 0000000000000204 [anon:shadowhook-enter:0000007a02bbf000] 2022-06-16 09:25:18.292 A/DEBUG: #01 pc 000000000004afc8 /system/lib64/libart.so (offset 0x358000)

  • Hook dlopen function crashes on mumu emulator

    Hook dlopen function crashes on mumu emulator

    ShadowHook Version

    1.0.3

    Android OS Version

    6.0.1

    Android ABIs

    armeabi-v7a

    Device Manufacturers and Models

    MuMu

    Describe the Bug

    1、application中初始化shadow 2、mainactivity statsic中load native-lib.so 3、native-lib.so的JNI_Onload中hook dlopen,代码使用的是unittest中的dlopen示例

    ============shadowhook_tag的日志如下========== shadowhook_tag: shadowhook: shadowhook init(mode: UNIQUE, debuggable: true), return: 0, real-init: yes shadowhook_tag: sdk_verison : 23 shadowhook_tag: shadowhook: hook_sym_name(linker, __dl__Z9do_dlopenPKciPK17android_dlextinfo, 0xc60151d) ... shadowhook_tag: task: hook dlopen/do_dlopen internal. target-address f7768ca0 shadowhook_tag: switch: get dlinfo info: target_addr f7768ca0, sym_name __dl__Z9do_dlopenPKciPK17android_dlextinfo, sym_sz 522, load_bias f775d000, pathname /system/bin/linker shadowhook_tag: exit: gap, f779ad10 - f779b000 (load_bias f775d000, 3dd10 - 3e000), NFZ 1, READABLE 1 shadowhook_tag: exit: gap, f77a21d0 - f77a3000 (load_bias f775d000, 451d0 - 46000), NFZ 0, READABLE 1 shadowhook_tag: exit: gap fill zero, f779ad10 - f779b000 (load_bias f775d000, 3dd10 - 3e000), READABLE 1 shadowhook_tag: exit: gap resize, f779ad10 - f779aff8 (load_bias f775d000, 3dd10 - 3dff8) shadowhook_tag: exit: in-library alloc, at f779ad18 (load_bias f775d000, 3dd18), len 8 shadowhook_tag: exit: alloc in library, exit f779ad18, pc f7768ca8, distance 32070, range [-2000000, 1fffffc] shadowhook_tag: a32 rewrite: type 0, inst 83535657 shadowhook_tag: a32: hook (WITH EXIT) OK. target f7768ca0 -> exit f779ad18 -> new c107749 -> enter ef3d0000 -> remaining f7768ca4 shadowhook_tag: switch: hook(invisible) in UNIQUE mode OK: target_addr f7768ca0, new_addr c107749 shadowhook_tag: linker: hook dlopen OK, return: 0 shadowhook_tag: switch: get dlinfo info: target_addr f7768ca0, sym_name __dl__Z9do_dlopenPKciPK17android_dlextinfo, sym_sz 522, load_bias f775d000, pathname /system/bin/linker shadowhook_tag: exit: gap, f779ad10 - f779b000 (load_bias f775d000, 3dd10 - 3e000), NFZ 1, READABLE 1 shadowhook_tag: exit: gap, f77a21d0 - f77a3000 (load_bias f775d000, 451d0 - 46000), NFZ 0, READABLE 1 shadowhook_tag: exit: gap resize, f779ad10 - f779aff8 (load_bias f775d000, 3dd10 - 3dff8) shadowhook_tag: exit: in-library alloc, at f779ad20 (load_bias f775d000, 3dd20), len 8 shadowhook_tag: exit: alloc in library, exit f779ad20, pc f7768ca8, distance 32078, range [-2000000, 1fffffc] shadowhook_tag: a32 rewrite: type 1, inst ea00c81c shadowhook_tag: a32: hook (WITH EXIT) OK. target f7768ca0 -> exit f779ad20 -> new c60151d -> enter ef3d0100 -> remaining f7768ca4 shadowhook_tag: switch: hook in UNIQUE mode OK: target_addr f7768ca0, new_addr c60151d shadowhook_tag: shadowhook: hook_sym_name(linker, __dl__Z9do_dlopenPKciPK17android_dlextinfo, 0xc60151d) OK. return: 0xf3b375b0. 0 - OK

    ===========报错堆栈信息如下================== 2022-09-21 16:50:24.659 3113-3113/com.test.unity A/libc: Fatal signal 4 (SIGILL), code 2, fault addr 0xf7768ca8 in tid 3113 (com.test.unity) 2022-09-21 16:50:24.761 314-314/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 2022-09-21 16:50:24.761 314-314/? A/DEBUG: Build fingerprint: 'OnePlus/OnePlus2/OnePlus2:6.0.1/MMB29M/1447841200:user/release-keys' 2022-09-21 16:50:24.761 314-314/? A/DEBUG: Revision: '0' 2022-09-21 16:50:24.761 314-314/? A/DEBUG: ABI: 'x86' 2022-09-21 16:50:24.761 314-314/? A/DEBUG: pid: 3113, tid: 3113, name: com.test.unity >>> com.test.unity <<< 2022-09-21 16:50:24.761 314-314/? A/DEBUG: signal 4 (SIGILL), code 2 (ILL_ILLOPN), fault addr 0xf7768ca8 2022-09-21 16:50:24.763 314-314/? A/DEBUG: eax 00000000 ebx f779cfe4 ecx 0000006c edx 0000000b 2022-09-21 16:50:24.763 314-314/? A/DEBUG: esi f3b37760 edi f779d034 2022-09-21 16:50:24.763 314-314/? A/DEBUG: xcs 00000023 xds 0000002b xes 0000002b xfs 0000006b xss 0000002b 2022-09-21 16:50:24.763 314-314/? A/DEBUG: eip f7768ca8 ebp ffa6c324 esp ffa5d8f4 flags 00010202 2022-09-21 16:50:24.763 314-314/? A/DEBUG: backtrace: 2022-09-21 16:50:24.763 314-314/? A/DEBUG: #00 pc 00000ca8 /system/bin/linker (offset 0xb000) 2022-09-21 16:50:24.763 314-314/? A/DEBUG: #01 pc 0000002a 2022-09-21 16:50:24.782 314-314/? A/DEBUG: Tombstone written to: /data/tombstones/tombstone_01 2022-09-21 16:50:24.782 314-314/? E/DEBUG: AM write failed: Broken pipe 2022-09-21 16:50:24.785 740-760/system_process I/BootReceiver: Copying /data/tombstones/tombstone_01 to DropBox (SYSTEM_TOMBSTONE) 2022-09-21 16:50:24.787 740-3134/system_process W/ActivityManager: Force finishing activity com.test.unity/com.unity3d.player.UnityPlayerActivity 2022-09-21 16:50:24.787 740-3134/system_process E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 116)

  • Build Error

    Build Error

    shadowhook Version

    1.0.3

    Android OS Version

    10

    Android ABIs

    armeabi-v7a, arm64-v8a

    Device Manufacturers and Models

    any

    Describe the Bug

    [CXX1405] error when building with cmake using /Users/jarrettye/Documents/Workspace/Android/InlineHookDemo/app/src/main/cpp/CMakeLists.txt: Build command failed. Error while executing java process with main class com.google.prefab.cli.AppKt with arguments {--build-system cmake --platform android --abi arm64-v8a --os-version 21 --stl c++_static --ndk-version 21 --output /Users/jarrettye/Documents/Workspace/Android/InlineHookDemo/app/.cxx/Debug/52k576n3/prefab/arm64-v8a/prefab /Users/jarrettye/.gradle/caches/transforms-3/c46ec3f0af32bc2a9539f97e0d92f6fd/transformed/shadowhook-1.0.3/prefab}

    Exception in thread "main" java.lang.IllegalArgumentException: Only schema_version 1 is supported. shadowhook uses version 2. at com.google.prefab.api.Package.(Package.kt:46) at com.google.prefab.cli.Cli$packages$2.invoke(Cli.kt:124) at com.google.prefab.cli.Cli$packages$2.invoke(Cli.kt:95) at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74) at com.google.prefab.cli.Cli.getPackages(Cli.kt) at com.google.prefab.cli.Cli.validate(Cli.kt:172) at com.google.prefab.cli.Cli.run(Cli.kt:189) at com.github.ajalt.clikt.parsers.Parser.parse(Parser.kt:168) at com.github.ajalt.clikt.parsers.Parser.parse(Parser.kt:16) at com.github.ajalt.clikt.core.CliktCommand.parse(CliktCommand.kt:258) at com.github.ajalt.clikt.core.CliktCommand.parse$default(CliktCommand.kt:255) at com.github.ajalt.clikt.core.CliktCommand.main(CliktCommand.kt:273) at com.github.ajalt.clikt.core.CliktCommand.main(CliktCommand.kt:298) at com.google.prefab.cli.AppKt.main(App.kt:28)

  • Support for x86 and x86_64

    Support for x86 and x86_64

    the Feature, Motivation and Pitch

    Hello @caikelun, Is there any plan for supporting x86 and x86_64 architectures?

    Alternatives

    No response

    Additional context

    No response

  • Build Error

    Build Error

    ShadowHook Version

    1.0.3

    Android OS Version

    android 11

    Android ABIs

    arm64-v8a

    Device Manufacturers and Models

    Redmi k40

    Describe the Bug

    CMake Error at CMakeLists.txt:9 (find_package):
      Could not find a package configuration file provided by "shadowhook" with
      any of the following names:
    
        shadowhookConfig.cmake
        shadowhook-config.cmake
    
      Add the installation prefix of "shadowhook" to CMAKE_PREFIX_PATH or set
      "shadowhook_DIR" to a directory containing one of the above files.  If
      "shadowhook" provides a separate development package or SDK, be sure it has
      been installed.
    

    here is my unsolved project https://github.com/BlackBoxing/BlackBox

android analysis tools, jni trace by native hook, libc hook, write log with caller's addr in file or AndroidLog

编译方法 unix like mkdir "build" cd build cmake .. -DNDK=your_ndk_path/Android/sdk/ndk/22.0.7026061 -DANDROID_ABI=armeabi-v7a make -j8 或者使用andriod studio编

Nov 16, 2022
Take Damage hook hook made to increase weapon damage, the game I made is Free Fire in version 1.65

Take-Damage Simple Take Damage hook hook made to increase weapon damage, the game I made is Free Fire in version 1.65 Bool bool isTakeDemageBool = fal

Jan 1, 2022
Firmware, mechanical and electrical design files for the Inline Filament Diameter Estimator, Lowcost (InFiDEL).
Firmware, mechanical and electrical design files for the Inline Filament Diameter Estimator, Lowcost (InFiDEL).

Inline Filament Diameter Estimator, Lowcost (InFiDEL) Originally created by Thomas Sanladerer A cheap, yet precise filament diameter sensor, intended

Nov 18, 2022
codeless Android hook (experimental)

AppInspect Download app-inspect-v0.0.1.zip AppInspect-0.0.1.apk Install: install Riru module adb push app-inspect-v0.0.1.zip /data/local/tmp adb shel

Oct 21, 2022
Special Apps Remover (U.S.A Android Phones) (ADB ONLY) Supports deleting the applications of some American companies
Special Apps Remover (U.S.A Android Phones) (ADB ONLY) Supports deleting the applications of some American companies

Special Apps Remover (U.S.A Android Phones) (ADB ONLY) Supports deleting the applications of some American companies

Apr 28, 2022
First open source android modding library for Geometry Dash Based on Hooking-and-Patching-android-template

Android-ML First open source android modding library for Geometry Dash Based on Hooking-and-Patching-android-template Installation Download this githu

Jul 17, 2022
A simple library that helps Android developers to execute JavaScript code from Android native side easily without using Webview.

AndroidJSModule A simple library that helps Android developers to execute JavaScript code from Android native side easily without using Webview. Insta

May 24, 2022
A customized LGL Android mod menu, containing ESP only for PUBG Mobile 1.3.0 for Android
A customized LGL Android mod menu, containing ESP only for PUBG Mobile 1.3.0 for Android

PUBG Mobile ESP Mod Menu A customized LGL mod menu, containing ESP only for PUBG Mobile 1.3.0 for Android. Everything are fixed so it works with both

Mar 19, 2022
A repository for experimenting with elf loading and in-place patching of android native libraries on non-android operating systems.

droidports: A repository for experimenting with elf loading and in-place patching of android native libraries on non-android operating systems. Discla

Oct 17, 2022
Android NDK samples with Android Studio

NDK Samples This repository contains Android NDK samples with Android Studio C++ integration. These samples use the new CMake Android plugin with C++

Nov 19, 2022
MiniDumpWriteDump behavior modification hook

MiniDumpWriteDumpPoC MiniDumpWriteDump behavior modification hook Read the full article in our blog: Adepts Of 0xCC: Hooks On Hoot Off This is a funct

Nov 9, 2022
External warzone cheat with manual mapped driver (function hook), overlay (nvidia hijack), simple esp, no recoil

external_warzone_cheat External warzone cheat with manual mapped driver (function hook), overlay (nvidia hijack), simple esp, no recoil Offsests are N

Nov 14, 2022
Easily hook WIN32 x64 functions

About Library for easy hooking of arbitrary functions in WIN32 x64 executables. Only requires target function address. Disassembles the function prolo

Jun 12, 2022
A crappy hook on SpAcceptLsaModeContext that prints incoming auth attempts. WIP

About Hooks for intercepting SpAcceptLsaModeContext to print any incoming authentication attempts to Beacon. The hook is installed on the Lsass heap t

Dec 11, 2021
A demo of the relevant blog post: Hook Heaps and Live Free
A demo of the relevant blog post: Hook Heaps and Live Free

LockdExeDemo A demo of the relevant blog post: Hook Heaps and Live Free DEMO Explanation There are 2 compile types. The first is an EXE. The EXE requi

Oct 9, 2022
Hook up the OnePlus6(T) tri-state key in PostmarketOS!

OnePlus 6(T) tri-state key support in PostmarketOS As the name suggest, the goal of this little project is to hook up the OnePlus6(T) tri-state key in

Nov 14, 2021
An efficient and versatile system call hook mechanism
An efficient and versatile system call hook mechanism

Zpoline: hooking system calls without pain Zpoline is a novel system call hook mechanism that offers the following advantages. 100 times faster than p

Nov 19, 2022
Simple native jvm class dumper written in C by hook ClassLoader
Simple native jvm class dumper written in C by hook ClassLoader

JVM Native Class Dumper Simple native jvm class dumper written in C by hook ClassLoader What is used for? This tool allows you to dump all java classe

Nov 7, 2022
BokutachiHook - Hook for Lunatic Rave 2 to parse score data and send it to an HTTP server, made specifically for Bokutachi IR.

BokutachiHook Hook for Lunatic Rave 2 to parse score data and send it to an HTTP server, made specifically for Bokutachi IR (https://bokutachi.xyz). T

Sep 12, 2022