GithubHelp home page GithubHelp logo

bytedance / bhook Goto Github PK

View Code? Open in Web Editor NEW
1.9K 47.0 295.0 1.57 MB

:fire: ByteHook is an Android PLT hook library which supports armeabi-v7a, arm64-v8a, x86 and x86_64.

Home Page: https://github.com/bytedance/bhook/tree/main/doc#readme

License: MIT License

CMake 0.44% C 91.38% C++ 2.68% Java 5.10% Python 0.39%
android hook plthook plt gothook got native ndk hooking bytedance

bhook's Introduction

ByteHook

简体中文

ByteHook is an Android PLT hook library which supports armeabi-v7a, arm64-v8a, x86 and x86_64.

ByteHook is now used in TikTok, Douyin, Toutiao, Xigua Video, Lark.

If you need an Android inline hook library, please move to ShadowHook.

Features

  • Support Android 4.1 - 14 (API level 16 - 34).
  • Support armeabi-v7a, arm64-v8a, x86 and x86_64.
  • Multiple hooks and unhooks for the same function do not conflict with each other.
  • Hook a single, partial or all of the dynamic libraries in the process.
  • Hook the newly loaded dynamic libraries automatically.
  • Avoid recursive-calls and circular-calls between proxy functions automatically.
  • Support unwinding backtrace in proxy function.
  • MIT licensed.

Documentation

ByteHook Documentation

Quick Start

There is a sample app in the bytehook-sample you can refer to.

1. Add dependency in build.gradle

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

android {
    buildFeatures {
        prefab true
    }
}

dependencies {
    implementation 'com.bytedance:bytehook:1.0.10'
}

Note: ByteHook uses the prefab package schema v2, which is configured by default since Android Gradle Plugin 7.1.0. If you are using Android Gradle Plugin earlier than 7.1.0, please add the following configuration to gradle.properties:

android.prefabVersion=2.0.0

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

CMakeLists.txt

find_package(bytehook REQUIRED CONFIG)

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

Android.mk

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

$(call import-module,prefab/bytehook)

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

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

4. Add packaging options

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

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

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

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

5. Initialize

import com.bytedance.android.bytehook.ByteHook;

public class MySdk {
    public static synchronized void init() {
        ByteHook.init();
    }
}

6. Hook and Unhook

#include "bytehook.h"
bytehook_stub_t bytehook_hook_single(
    const char *caller_path_name,
    const char *callee_path_name,
    const char *sym_name,
    void *new_func,
    bytehook_hooked_t hooked,
    void *hooked_arg);

bytehook_stub_t bytehook_hook_partial(
    bytehook_caller_allow_filter_t caller_allow_filter,
    void *caller_allow_filter_arg,
    const char *callee_path_name,
    const char *sym_name,
    void *new_func,
    bytehook_hooked_t hooked,
    void *hooked_arg);

bytehook_stub_t bytehook_hook_all(
    const char *callee_path_name,
    const char *sym_name,
    void *new_func,
    bytehook_hooked_t hooked,
    void *hooked_arg);

int bytehook_unhook(bytehook_stub_t stub);

These three hook functions are used to hook single, partial, and all caller dynamic libraries in the process.

Notice:

  • If you need to call the original function in the proxy function, please always use the BYTEHOOK_CALL_PREV() macro.
  • Make sure to call BYTEHOOK_POP_STACK() macro before proxy function returning. In the CPP source file, you can also call BYTEHOOK_STACK_SCOPE() macro at the beginning of the proxy function instead.

Contributing

License

ByteHook is licensed by MIT License.

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

bhook's People

Contributors

caikelun avatar colibrow avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bhook's Issues

有人遇到开启hook后native heap明显增加的问题吗

bytehook Version

1.0.0

Android OS Version

10.0

Android ABIs

armeabi-v7a, arm64-v8a

Device Manufacturers and Models

oppo r17

Describe the Bug

用一个demo应用跑的。hook的是mmap malloc等函数。 跳板函数仅调用了BYTEHOOK_STACK_SCOPE 和BYTEHOOK_CALL_PREV。 但是开启后heap native增加了非常多。在真实项目中更明显,多了大几百M
未开启hook
image

开启hook
image

native crash at android 13

bytehook Version

1.0.6

Android OS Version

13

Android ABIs

armeabi-v7a, arm64-v8a

Device Manufacturers and Models

samsung b0q/samsung r8q/ samsung a32

Describe the Bug

我们使用bhook来hook lock的write方法从而监听lock信息,使用如下:

void LockMonitor::LogLockTrace(const void* buf){
    const char* msg = reinterpret_cast<const char*>(buf);

    // B|23086|monitor contention with owner testlock (23548) at void java.lang.Thread.sleep(java.lang.Object, long, int)(Thread.java:-2) waiters=0 blocking from void com.example.nativehookdemo.MainActivity.testLock2$lambda-3(com.example.nativehookdemo.MainActivity)(MainActivity.kt:38)-23086-23086
    // 1 thread name -> owner
    // 2 thread id -> owner name
    // 3 invoke name -> owner method
    // 4 wait thread id ->
    // 5 wait thread name
    // 6 wait thread invoke name

    // duration =
    // start: key = threadname-threadid
    // end: key = threadname-threadid

    switch (msg[0]) {
        // begin
        case 'B': {
            std::string msgStr = msg;
            if (isLockMsg(msgStr)) {
                int pid = getpid();
                int tid = gettid();
                // filter非主线程
                if (pid != tid) {
//                    LOGD("not main thread lock start, process_id: %d, thread_id: %d", pid, tid);
                    return;
                }
                double time = std::chrono::duration_cast<std::chrono::milliseconds>(
                        std::chrono::steady_clock::now().time_since_epoch()).count();
//                LOGD("startTime ms:%s", std::to_string(time).c_str());
                std::string key = std::to_string(pid) + "-" + std::to_string(tid);
                std::string currentThreadName = GetThreadName(tid);

                LockContext *lockContext = new LockContext();
                lockContext->set_wait_thread_id(tid);
                lockContext->set_wait_thread_name(currentThreadName);
                lockContext->set_begin_time_ms(time);
                parseMsgToLockContext(msg, lockContext);
                map_lock_context_[key] = lockContext;
                Notify_java_delay_sample_main_thread_stack(lockContext->get_owner_thread_name(),
                                                           lockContext->get_owner_thread_id());
            }
            break;
        }
        case 'E': {
            int pid = getpid();
            int tid = gettid();
            // filter非主线程
            if (pid != tid) {
                //LOGD("not main thread lock end, process_id: %d, thread_id: %d", pid, tid);
                return;
            }
            double time = std::chrono::duration_cast<std::chrono::milliseconds>(
                    std::chrono::steady_clock::now().time_since_epoch()).count();
            std::string key = std::to_string(pid) + "-" + std::to_string(tid);
            std::map<std::string, LockContext*>::iterator lock_iter;
            lock_iter = map_lock_context_.find(key);
            if (lock_iter != map_lock_context_.end()) {
//                LOGD("endTime ms:%s", std::to_string(time).c_str());
                LockContext* preLockContext = lock_iter->second;
                preLockContext->set_end_time_ms(time);
                // 一个begin->end周期结束 删除掉map中的数据
                map_lock_context_.erase(lock_iter);
                Report(*preLockContext);
                delete preLockContext;
            }
            break;
        }
    }

}

size_t WriteProxy(int fd, const void *buf, size_t count)
{
    // 执行 stack 清理(不可省略)
    BYTEHOOK_STACK_SCOPE();

    if (LockMonitor::Get().isATraceFd(fd)) {
        LockMonitor::Get().LogLockTrace(buf);
    }
    size_t result = BYTEHOOK_CALL_PREV(WriteProxy, fd, buf, count);
    return result;
}

int LockMonitor::LockMonitor::DoHook()
{
    LOGD("hook start");
    try {
        stub_ = bytehook_hook_all(nullptr,
                                  "write",
                                  reinterpret_cast<void *>(WriteProxy),
                                  nullptr,
                                  nullptr);
        LOGD("hook success");
        hooked_ = true;
        return OK;
    } catch (...) {
        return HOOK_FAILED;
    }

}

线上出现了一些android13的native崩溃,崩溃堆栈信息如下:

Thread Check failed: checkpoint != nullptr Checkpoint flag set without pending checkpoint

backtrace:
  #00  pc 0x0000000000051ce8  /apex/com.android.runtime/lib64/bionic/libc.so (abort+164)
  #01  pc 0x00000000006f9f28  /apex/com.android.art/lib64/libart.so (art::Runtime::Abort(char const*)+472)
  #02  pc 0x0000000000016ea8  /apex/com.android.art/lib64/libbase.so (android::base::SetAborter(std::__1::function<void (char const*)>&&)::$_3::__invoke(char const*)+80)
  #03  pc 0x0000000000016450  /apex/com.android.art/lib64/libbase.so (android::base::LogMessage::~LogMessage()+352)
  #04  pc 0x0000000000426030  /apex/com.android.art/lib64/libart.so (art::Thread::RunCheckpointFunction()+364)
  #05  pc 0x00000000003bf274  /apex/com.android.art/lib64/libart.so (void art::Monitor::Lock<(art::LockReason)1>(art::Thread*)+6852)
  #06  pc 0x00000000003bd3a4  /apex/com.android.art/lib64/libart.so (artLockObjectFromCode+352)
  #07  pc 0x0000000000458024  /apex/com.android.art/lib64/libart.so (art_quick_lock_object_no_inline+52)
  #08  pc 0x0000000000ad4824  /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (android.os.MessageQueue.next+324)
  #09  pc 0x0000000000ad0be8  /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (android.os.Looper.loopOnce+104)
  #10  pc 0x0000000000ad0a4c  /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (android.os.Looper.loop+1148)
  #11  pc 0x0000000001a4c3bc  /data/app/~~o4L7s6XTZ3Vo1Db_2KCBGw==/com.xxx.xxx-EzLIXXlEef1QEZ1c_I2GmA==/oat/arm64/base.odex (com.infra.crashhunter.CrashHunter$init$$inlined$let$lambda$1.run+60)
  #12  pc 0x0000000000acced4  /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (android.os.Handler.dispatchMessage+84)
  #13  pc 0x0000000000ad0f88  /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (android.os.Looper.loopOnce+1032)
  #14  pc 0x0000000000ad0a4c  /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (android.os.Looper.loop+1148)
  #15  pc 0x00000000007d9b18  /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (android.app.ActivityThread.main+1480)
  #16  pc 0x0000000000457e00  /apex/com.android.art/lib64/libart.so (art_quick_invoke_static_stub+576)
  #17  pc 0x000000000048c038  /apex/com.android.art/lib64/libart.so (_jobject* art::InvokeMethod<(art::PointerSize)8>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jobject*, _jobject*, unsigned long)+1560)
  #18  pc 0x000000000048b9f8  /apex/com.android.art/lib64/libart.so (art::Method_invoke(_JNIEnv*, _jobject*, _jobject*, _jobjectArray*) (.__uniq.165753521025965369065708152063621506277)+48)
  #19  pc 0x00000000002f2148  /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (art_jni_trampoline+120)
  #20  pc 0x0000000000a38560  /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run+144)
  #21  pc 0x0000000000a43404  /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (com.android.internal.os.ZygoteInit.main+3604)
  #22  pc 0x0000000000457e00  /apex/com.android.art/lib64/libart.so (art_quick_invoke_static_stub+576)
  #23  pc 0x000000000058bbc4  /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeWithVarArgs<_jmethodID*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, std::__va_list)+912)
  #24  pc 0x0000000000609af8  /apex/com.android.art/lib64/libart.so (art::JNI<true>::CallStaticVoidMethodV(_JNIEnv*, _jclass*, _jmethodID*, std::__va_list)+172)
  #25  pc 0x00000000000c0ad0  /system/lib64/libandroid_runtime.so (_JNIEnv::CallStaticVoidMethod(_jclass*, _jmethodID*, ...)+120)
  #26  pc 0x00000000000ccdf8  /system/lib64/libandroid_runtime.so (android::AndroidRuntime::start(char const*, android::Vector<android::String8> const&, bool)+852)
  #27  pc 0x0000000000002568  /system/bin/app_process64 (main+1300)
  #28  pc 0x000000000004a288  /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+96)


你好bytehook_add_dlopen_callback应该怎么用传入data是什么

void bytehook_add_dlopen_callback(bytehook_pre_dlopen_t pre, bytehook_post_dlopen_t post, void *data)
{
bh_core_add_dlopen_callback(pre, post, data);
}

void bytehook_del_dlopen_callback(bytehook_pre_dlopen_t pre, bytehook_post_dlopen_t post, void *data)
{
bh_core_del_dlopen_callback(pre, post, data);
}

Android 9部分设备上hook 失败

bytehook Version

1.0.10

Android OS Version

9.0

Android ABIs

arm64-v8a

Device Manufacturers and Models

vivo y5s, oppo A8

Describe the Bug

现象:hook 失败,在dladdr 之后打印dl_info 的数据,和目标符号不匹配

调试过程:

  1. hook 的时候发现没有打印 hook chain: verify OK,在bh_hook_manager_verify_got_value 失败的代码里加了日志打印。 hook 失败的设备上打印了新增的日志

  2. 在bh_hook_manager_verify_got_value中的 dladdr 之后添加了dl_info 的日志,发现hook 失败时打印出的符号和hook的目标符号对不上
    图2

正常hook的日志 ---- bytehook_tag: check for normal export func: _Z9FindEntryPvRK9ZipStringP8ZipEntry

hook失败的日志 ---- bytehook_tag: check for normal export func: _Z12EndIterationPv

  1. 代码里把 bh_hook_manager_verify_got_value 校验跳过之后,目标符号 hook 正常

异常设备的so:
libandroidfw.so.zip
正常设备的so:
libandroidfw_normal.so.zip

调用代码:
hacker.c.zip

Android 11 没有命中自己App中加载的so

bytehook Version

1.0.5

Android OS Version

11

Android ABIs

arm64-v8a

Device Manufacturers and Models

oppo

Describe the Bug

df702b1fadb03cf625d6cb43ef172f1

我使用bhook去hook自己加载的另一个so,发现没有hook到,map中没找到这个so,pc命中的是base.apk,打印bhook中的bh_elf_manager_iterate_cb,没看到这个so,这个是Android 11的特性?

是否可以对.init_array中的调用进行hook

从原理上来看,bhook执行的时机应该是在dlopen之后?现在有个需求是:dlopen里会执行.init和.init_array区块的代码,我需要hook一个在.init_array区块中执行的函数,从本地尝试来看hook是无效的,原因是dlopen阶段hook还未执行,是否有其他办法可以做到呢?

image

会一直开源并维护吗

亲爱的bhook团队:
1 请问这个项目会一直开源并持续维护吗?
2 可以修改定制这份源码并用于到自己的项目中么?

请问安卓9的open函数hook不到是什么原因。同样代码安卓10是没有问题的。

Android层测试代码:
File file = new File("/storage/emulated/0/1.txt");
try {
FileInputStream fileInputStream = new FileInputStream(file);
byte[] buf = new byte[(int)file.length()];
fileInputStream.read(buf);
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}

c层hook代码:
bytehook_hook_single("libjavacore.so", NULL, "open", open_proxy, open_hooked_callback, NULL);
bytehook_hook_single("libjavacore.so", NULL, "stat", stat_proxy, stat_hooked_callback, NULL);
bytehook_hook_single("libjavacore.so", NULL, "read", read_proxy_auto, read_hooked_callback, NULL);

安卓9的回调显示hook成功了。
bytehook_tag: >>>>> hooked. stub: c6b93ac0, status: 0, caller_path_name: /system/lib/libjavacore.so, sym_name: open, new_func: c5e08ebd, prev_func: e756aefd, arg: 0
安卓10的回调也类似。
bytehook_tag: >>>>> hooked. stub: ba5d3480, status: 0, caller_path_name: /apex/com.android.runtime/lib/libjavacore.so, sym_name: open, new_func: c04afebd, prev_func: edaa2299, arg: 0
但是实际测试中在open入口打印,只有安卓10的设备有响应。
LOG("open hooked path("%s")", pathname);

华为MT7-TL10 hook失败

MainActivity为webview,加载网页时未hook掉connect函数。红米k20 pro及模拟器均正常hook。

bytesig被初始化多次时, 后面的会失败

bytehook Version

1.0.9

Android OS Version

android 13

Android ABIs

arm64-v8a

Device Manufacturers and Models

红米K60

Describe the Bug

项目中同时使用bytehook与shadowhook, 使用源码编译到同一个so.
两个sdk都使用了bytesig模块, 后面启动的会失败.

SHADOWHOOK_ERRNO_INIT_SIGSEGV或者BYTEHOOK_STATUS_CODE_INITERR_SIG

目前通过如下代码临时解决.

static bool init_SIGSEGV = false;
static int last_init_SIGSEGV = 0;
static bool init_SIGBUS = false;
static int last_init_SIGBUS = 0;
int bytesig_init(int signum) {
  if (signum == SIGSEGV && init_SIGSEGV) {
    return last_init_SIGSEGV;
  }
  if (signum == SIGBUS && init_SIGBUS) {
    return last_init_SIGBUS;
  }

  int result = bytesig_init0(signum);

  if (signum == SIGSEGV ) {
    last_init_SIGSEGV = result;
    init_SIGSEGV = true;
  }
  if (signum == SIGBUS ) {
    last_init_SIGBUS = result;
    init_SIGBUS = true;
  }
  return result;
}

mprotect 返回-1

bytehook Version

v1.0.7

Android OS Version

13

Android ABIs

arm64-v8a

Device Manufacturers and Models

xiaomi 13 Ultra

Describe the Bug

05-12 21:16:46.027 1858 3575 E bytehook_tag: JC mprotect result: -1

init 失败 code:24 BYTEHOOK_STATUS_CODE_INITERR_CFI

bhook 的dlopen未监控到加载的so

bytehook Version

1.0.5

Android OS Version

6

Android ABIs

armeabi-v7a

Device Manufacturers and Models

xiaomi 4

Describe the Bug

我通过注册回调函数:
bytehook_add_dlopen_callback(dlopen_pre_callback, dlopen_callback, NULL);
发现加载so后未被监控到。
于是我修改bh_hook_manager_verify_got_value输出了一下日志

rs = dladdr(*((void **)got_addr), &info);
BH_LOG_INFO("dladdr: %s got_addr=%p callee: %s %s", got_addr, info.dli_fname, info.dli_sname);
...
if (NULL == info.dli_sname) {
   ElfW(Sym) *sym = bh_elf_find_export_func_symbol_by_symbol_name(callee_elf, task->sym_name);
   BH_LOG_INFO("callee: %s(%s), sym:%p", callee_elf->pathname, task->sym_name, sym);
   if (NULL != sym && STT_GNU_IFUNC == ELF_ST_TYPE(sym->st_info)) {
      BH_LOG_INFO("hook chain: verify bypass ifunc: %s in %s", task->sym_name, info.dli_fname);
      r = 0;
   }
}

日志如下:
06-22 18:23:57.609 32110-32110/? I/bhook: hook symbol(dlopen) in /system/lib/libart.so
06-22 18:23:57.609 32110-32110/? I/bhook: trampo: created for GOT b4abcbf0 at b5de608c, size 20 + 8 = 28
06-22 18:23:57.609 32110-32110/? I/bhook: hook chain: created for GOT b4abcbf0, orig func ab53e961
06-22 18:23:57.609 32110-32110/? I/bhook: hook chain: add(new) func, GOT b4abcbf0, func b377cf61
06-22 18:23:57.610 32110-32110/? I/bhook: dladdr got_addr=b4abcbf0 callee: /system/lib/libsechook.so (null)
06-22 18:23:57.610 32110-32110/? I/bhook: /system/lib/libsechook.so(dlopen), sym:0x0
06-22 18:23:57.610 32110-32110/? I/bhook: hook chain: del func, GOT b4abcbf0, func b377cf61

这个问题可能是因为dlopen已经被别的库(/system/lib/libsechook.so)hook了,然后bhook就不处理了?

关于hook系统方法kill

我尝试hook系统方法kill,malloc方法已经试过是没有问题,kill方法的现象是本应用不同的so发出kill是可以监控到,但是系统通过kill杀死本应用就没法监控到,想问问是什么原因呢,因为我看了一下系统杀死应用也是通过kill发送SIGKILL,我也尝试把相关的方法一并hook掉(exit,_exit,tgkill,killpg),也是没有监听到。

hook __android_log_print没效果

bytehook Version

1.0.8

Android OS Version

12

Android ABIs

arm64-v8a

Device Manufacturers and Models

小米MIX4

Describe the Bug

`
int my_log_print(int prio, const char *tag, const char *fmt, ...) {
return 0;
}

int disableLogcat() {
bytehook_init(BYTEHOOK_MODE_AUTOMATIC, false);
bytehook_hook_all(nullptr, "__android_log_print", (void *) (my_log_print), nullptr,
nullptr);
}
`
想拦截logcat的输出,但是hook没效果,logcat还是会打印

hook不成功

bytehook Version

1.0.9

Android OS Version

11

Android ABIs

arm64-v8a

Device Manufacturers and Models

vivo x60

Describe the Bug

是想hook libinput.so 里的 send和recv方法 来做onTouch事件的监听, 但是一直不成功 不知道为啥

//__socketcall ssize_t sendto(int __fd, const void* __buf, size_t __n, int __flags, const struct sockaddr* __dst_addr, socklen_t __dst_addr_length);
ssize_t send_proxy(int __fd, const void* __buf, size_t __n, int __flags, const struct sockaddr* __dst_addr, socklen_t __dst_addr_length) {
    LOGD("send_proxy");
    BYTEHOOK_STACK_SCOPE();
    return BYTEHOOK_CALL_PREV(send_proxy, __fd, __buf, __n, __flags,__dst_addr,__dst_addr_length);
}

//__socketcall ssize_t recvfrom(int __fd, void* __buf, size_t __n, int __flags, struct sockaddr* __src_addr, socklen_t* __src_addr_length);
ssize_t recv_proxy(int __fd, void* __buf, size_t __n, int __flags, struct sockaddr* __src_addr, socklen_t* __src_addr_length) {
    LOGD("recv_proxy");
    BYTEHOOK_STACK_SCOPE();
    return  BYTEHOOK_CALL_PREV(recv_proxy, __fd, __buf, __n, __flags,__src_addr,__src_addr_length);
}


    bytehook_hook_all("/system/lib/libinput.so", "sendto", (void *) send_proxy, nullptr, nullptr);
    bytehook_hook_all("/system/lib/libinput.so", "recvfrom", (void *) recv_proxy,
                      nullptr,
                      nullptr);

No signature of method

Build file 'D:\speed\bhook-main\bytehook\build.gradle' line: 5

A problem occurred evaluating project ':bytehook'.

No signature of method: build_82d7azg7qimiazu2jjh6if0dz.android() is applicable for argument types: (build_82d7azg7qimiazu2jjh6if0dz$_run_closure1) values: [build_82d7azg7qimiazu2jjh6if0dz$_run_closure1@5fcfc7ad]

模拟器hook失效

apk中仅有armv7-a的库,通过houdini加载后,bhook失效了。请问这个有解决方法么?

合并bytehook与shadowhook

the Feature, Motivation and Pitch

bytehookshadowhook虽然一个是plt/got hook另一个是inline hook, 两个组件有相同基础xDL, bytesig, bsd, lss ...
合并两边是有某种可能性的.

两个hook框架一个是在caller方, 一个是在callee方进行hook. 如果能用统一的api去写那会很酷.

typedef strlen_t ;

// bytehook
size_t my_strlen(const char* const str)
{
    size_t result = BYTEHOOK_CALL_PREV(my_strlen, strlen_t, str);
    BYTEHOOK_POP_STACK();
    return result;
}
 // shadowhook
strlen_t strlen_backup = ...;
size_t my_strlen(const char* const str)
{
    size_t result = strlen_backup(str);
    return result;
}

他们的代码可以说是相似的,区别是BYTEHOOK_POP_STACKbackup部分.

backup 就是某种 BYTEHOOK_CALL_PREV 可以合并.
BYTEHOOK_POP_STACK应该可以通过自动生成trampline的方式等价去掉.

那么新的通用hook的代码就变成

size_t my_strlen(const char* const str)
{
    size_t result = CALL_PREV(my_strlen, strlen_t, str); // chain to next
    return result;
}

hook_plt("libxxx.so" -> "libc.so", "strlen", my_strlen);  // 注册
hook_inline("libc.so", "strlen", my_strlen);  // 注册
hook_inline("libc.so", "strlen", my_strlen2);  // 注册其他的
hook_inline("libc.so", "strlen", my_strlen3);  // 注册更多

Alternatives

不做修改, 现在的就挺好的

Additional context

No response

夜神模拟器跑unity应用,hook libunity.so

我现在在夜神模拟器7.0.0.8 32位上跑bhook,hook了libunity的fseek函数或者其他函数,fopen等等。我单纯调用bytehook_init没问题,但是一旦调用了bytehook_hook_single去hook函数,也是显示hook成功的,但是后面就闪退了:
2021-12-17 12:12:00.127 5510-5510/? A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0xfff33011 in tid 5510 (xxx.xxx.xxx)
2021-12-17 12:12:00.133 5567-5567/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
2021-12-17 12:12:00.133 5567-5567/? A/DEBUG: Build fingerprint: 'samsung/dream2qltezh/dream2qltechn:7.1/N2G48H/G9550ZHU1AQEE:user/release-keys'
2021-12-17 12:12:00.133 5567-5567/? A/DEBUG: Revision: '12'
2021-12-17 12:12:00.133 5567-5567/? A/DEBUG: ABI: 'x86'
2021-12-17 12:12:00.133 5567-5567/? A/DEBUG: pid: 5510, tid: 5510, name: xxx.xxx.xxx >>> xxx.xxx.xxx <<<
2021-12-17 12:12:00.133 5567-5567/? A/DEBUG: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xfff33011
2021-12-17 12:12:00.133 5567-5567/? A/DEBUG: eax f66d4127 ebx 98724ff4 ecx 00000001 edx fff32e99
2021-12-17 12:12:00.133 5567-5567/? A/DEBUG: esi 989a720c edi fff32e99
2021-12-17 12:12:00.133 5567-5567/? A/DEBUG: xcs 00000073 xds 0000007b xes 0000007b xfs 0000003b xss 0000007b
2021-12-17 12:12:00.133 5567-5567/? A/DEBUG: eip 984fa373 ebp 988c67e4 esp bfa9c334 flags 00010282
2021-12-17 12:12:00.133 5567-5567/? A/DEBUG: backtrace:
2021-12-17 12:12:00.133 5567-5567/? A/DEBUG: #00 pc 00238373 /system/lib/libhoudini.so

我的应用是只打了arm32和arm64的,没打x86,在模拟器上应该是跑的arm32。应该是libhoudini.so转码导致的。用你的demo只打arm32和arm64,在模拟器上跑却没问题。

android 4.4 等版本找不到符号 sigfillset

hi:
之前使用 xhook,看到推荐准备使用 bhook。我看介绍说是支持 android 5 一下的版本的。但是在实际运行过程中出现问题:
cannot locate symbol "sigfillset"

我看代码的确是使用了 sigfillset,网上看了下这个符号是在 android 5 才引入。所以是不是 bhook 其实只支持 android 5 及其以上版本?

Android 5.1.1 AUTO模式时,后加载so无法hook

手机:Xiaomi MI NOTE Pro
系统:Android 5.1.1
bhook: 1.0.3

bytehook_init(BYTEHOOK_MODE_AUTOMATIC, true);
bytehook_hook_all(nullptr, "getaddrinfo", (void*)MY_getaddrinfo, hookCallbac, nullptr);

以上代码执行完后再加载webview,无法hook libwebviewchromium.so
但是,先在加载webview后再执行以上代码,则可以hook到libwebviewchromium.so

c++在Andorid 11上hook android_dlopen_ext会崩溃

感谢作者开源如此优秀的项目!

我在使用项目的过程中碰到如标题的崩溃,以下是相关信息

1.问题描述:
我在自己的热升级工程中引入bhook, 想hook所有的dlopen和android_dlopen_ext实现so的重定向。
我的工程在Android 9上运行正常(hook dlopen),但在Andorid 11上运行会出现崩溃。
我在bhook的sample工程里面也写了相同的hook逻辑,sample却能hook成功,两者代码逻辑相同,只是我的工程使用的是c++,sample中使用的是c语言。我也注意到了文档中提到的,使用c++时要注意BYTEHOOK_CALL_PREV的用法,以及c++要在代理函数前先调用BYTEHOOK_STACK_SCOPE,c语言要在代理函数return之前调用BYTEHOOK_POP_STACK.

2.崩溃堆栈
02-22 17:20:27.714 10324 10324 I crash_dump64: obtaining output fd from tombstoned, type: kDebuggerdTombstone
02-22 17:20:27.715 10324 10324 I crash_dump64: performing dump of process 9832 (target tid = 9832)
02-22 17:20:27.724 10324 10324 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
02-22 17:20:27.724 10324 10324 F DEBUG : Build fingerprint: 'samsung/beyond2qltezc/beyond2q:11/RP1A.200720.012/G9750ZCS5FUE4:user/release-keys'
02-22 17:20:27.724 10324 10324 F DEBUG : Revision: '17'
02-22 17:20:27.724 10324 10324 F DEBUG : ABI: 'arm64'
02-22 17:20:27.724 10324 10324 F DEBUG : Timestamp: 2022-02-22 17:20:27+0800
02-22 17:20:27.724 10324 10324 F DEBUG : pid: 9832, tid: 9832, name: .UnityHotUpdate >>> com.testHU.UnityHotUpdate <<<
02-22 17:20:27.724 10324 10324 F DEBUG : uid: 15104
02-22 17:20:27.724 10324 10324 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x1
02-22 17:20:27.724 10324 10324 F DEBUG : Cause: null pointer dereference
02-22 17:20:27.724 10324 10324 F DEBUG : x0 0000007c552b79b0 x1 0000000000000000 x2 fffffffffffffff0 x3 0000007c553503d0
02-22 17:20:27.724 10324 10324 F DEBUG : x4 0000007c55350400 x5 0000007c553503f7 x6 6964616f6c202d20 x7 6c20646e6120676e
02-22 17:20:27.724 10324 10324 F DEBUG : x8 00000000ffffeef8 x9 0000000000000008 x10 0000000000000000 x11 0000007946106040
02-22 17:20:27.724 10324 10324 F DEBUG : x12 000000000000fa0c x13 000000000003150c x14 000000000003150c x15 000010048b953b17
02-22 17:20:27.724 10324 10324 F DEBUG : x16 0000007c565eb3f0 x17 0000007c565bddf0 x18 0000007c56336000 x19 0000000000000001
02-22 17:20:27.724 10324 10324 F DEBUG : x20 0000000000000002 x21 00000079bebbd4b0 x22 0000007c55399250 x23 0000007c552b79b0
02-22 17:20:27.724 10324 10324 F DEBUG : x24 0000007c55350180 x25 0000000000000000 x26 0000000000000080 x27 0000007fe50bb930
02-22 17:20:27.724 10324 10324 F DEBUG : x28 0000007c565ef898 x29 0000007fe50bba20
02-22 17:20:27.724 10324 10324 F DEBUG : lr 0000007c5652a780 sp 0000007fe50ba8f0 pc 0000007c5652a934 pst 0000000040000000
02-22 17:20:27.823 10324 10324 F DEBUG : backtrace:
02-22 17:20:27.823 10324 10324 F DEBUG : NOTE: Function names and BuildId information is missing for some frames due
02-22 17:20:27.823 10324 10324 F DEBUG : NOTE: to unreadable libraries. For unwinds of apps, only shared libraries
02-22 17:20:27.823 10324 10324 F DEBUG : NOTE: found under the lib/ directory are readable.
02-22 17:20:27.823 10324 10324 F DEBUG : #00 pc 0000000000034934 /apex/com.android.runtime/bin/linker64 (__dl__Z9do_dlopenPKciPK17android_dlextinfoPKv+988) (BuildId: 14e4f7c3a987c01b47ee17cc5aa77135)
02-22 17:20:27.823 10324 10324 F DEBUG : #1 pc 00000000000300e4 /apex/com.android.runtime/bin/linker64 (__loader_android_dlopen_ext+80) (BuildId: 14e4f7c3a987c01b47ee17cc5aa77135)
02-22 17:20:27.823 10324 10324 F DEBUG : #2 pc 0000000000005650 /data/app/~~LsiHOd_FSmJbq-SSP7PHvA==/com.testHU.UnityHotUpdate-YYnePFdQ5JcfcZrQKbgM9A==/lib/arm64/libbytehook.so (BuildId: 18c1050856b1067cc7d3f202858a45eda49eccd7)
02-22 17:20:27.823 10324 10324 F DEBUG : #03 pc 00000000000010b8 /apex/com.android.runtime/lib64/bionic/libdl.so (android_dlopen_ext+12) (BuildId: 2d9a3bc477f6477aad024f334662e2ce)
02-22 17:20:27.823 10324 10324 F DEBUG : #4 pc 000000000000fa08 /data/app/~~LsiHOd_FSmJbq-SSP7PHvA==/com.testHU.UnityHotUpdate-YYnePFdQ5JcfcZrQKbgM9A==/lib/arm64/libhook.so (BuildId: 3a08223a890ee619c8272e246dd1846fed1054b9)
02-22 17:20:27.823 10324 10324 F DEBUG : #05 pc 000000000001ac04 /apex/com.android.art/lib64/libnativeloader.so (android::NativeLoaderNamespace::Load(char const*) const+192) (BuildId: 70d4c953bb1489017528077acb0edcd6)
02-22 17:20:27.823 10324 10324 F DEBUG : #6 pc 000000000000d708 /apex/com.android.art/lib64/libnativeloader.so (OpenNativeLibraryInNamespace+64) (BuildId: 70d4c953bb1489017528077acb0edcd6)
02-22 17:20:27.823 10324 10324 F DEBUG : #07 pc 000000000000d2cc /apex/com.android.art/lib64/libnativeloader.so (OpenNativeLibrary+132) (BuildId: 70d4c953bb1489017528077acb0edcd6)
02-22 17:20:27.823 10324 10324 F DEBUG : #8 pc 0000000000376434 /apex/com.android.art/lib64/libart.so (art::JavaVMExt::LoadNativeLibrary(_JNIEnv*, std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator > const&, _jobject*, _jclass*, std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator >)+2096) (BuildId: e14503791ca790aee59797b668187c00)
02-22 17:20:27.823 10324 10324 F DEBUG : #9 pc 0000000000005130 /apex/com.android.art/lib64/libopenjdkjvm.so (JVM_NativeLoad+416) (BuildId: 375393490f7011c45690bc79b5a6fa2a)
02-22 17:20:27.824 10324 10324 F DEBUG : #10 pc 0000000000081a24 /apex/com.android.art/javalib/arm64/boot.oat (art_jni_trampoline+228) (BuildId: 6f9ff290bb1f57d3f6d08d1d26898736989e8371)
02-22 17:20:27.824 10324 10324 F DEBUG : #11 pc 000000000009a5a8 /apex/com.android.art/javalib/arm64/boot.oat (java.lang.Runtime.loadLibrary0+328) (BuildId: 6f9ff290bb1f57d3f6d08d1d26898736989e8371)
02-22 17:20:27.824 10324 10324 F DEBUG : #12 pc 000000000009b9b4 /apex/com.android.art/javalib/arm64/boot.oat (java.lang.Runtime.loadLibrary0+180) (BuildId: 6f9ff290bb1f57d3f6d08d1d26898736989e8371)
02-22 17:20:27.824 10324 10324 F DEBUG : #13 pc 000000000009f260 /apex/com.android.art/javalib/arm64/boot.oat (java.lang.System.loadLibrary+96) (BuildId: 6f9ff290bb1f57d3f6d08d1d26898736989e8371)
02-22 17:20:27.824 10324 10324 F DEBUG : #14 pc 00000000001347e8 /apex/com.android.art/lib64/libart.so (art_quick_invoke_static_stub+568) (BuildId: e14503791ca790aee59797b668187c00)
02-22 17:20:27.824 10324 10324 F DEBUG : #15 pc 0000000000198eb0 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread
, unsigned int*, unsigned int, art::JValue*, char const*)+232) (BuildId: e14503791ca790aee59797b668187c00)
02-22 17:20:27.824 10324 10324 F DEBUG : #16 pc 000000000030c228 /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+376) (BuildId: e14503791ca790aee59797b668187c00)
02-22 17:20:27.824 10324 10324 F DEBUG : #17 pc 0000000000307340 /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+884) (BuildId: e14503791ca790aee59797b668187c00)
02-22 17:20:27.824 10324 10324 F DEBUG : #18 pc 000000000063de30 /apex/com.android.art/lib64/libart.so (MterpInvokeStatic+548) (BuildId: e14503791ca790aee59797b668187c00)
02-22 17:20:27.824 10324 10324 F DEBUG : #19 pc 000000000012e994 /apex/com.android.art/lib64/libart.so (mterp_op_invoke_static+20) (BuildId: e14503791ca790aee59797b668187c00)
02-22 17:20:27.824 10324 10324 F DEBUG : #20 pc 000000000009ed24 /data/user/0/com.testHU.UnityHotUpdate/tinker/patch-40572dfe/dex/tinker_classN.apk (com.unity3d.player.UnityPlayer.+20)
02-22 17:20:27.824 10324 10324 F DEBUG : #21 pc 00000000002fed1c /apex/com.android.art/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.2255279045661746555)+268) (BuildId: e14503791ca790aee59797b668187c00)
02-22 17:20:27.824 10324 10324 F DEBUG : #22 pc 0000000000629a58 /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+796) (BuildId: e14503791ca790aee59797b668187c00)
02-22 17:20:27.824 10324 10324 F DEBUG : #23 pc 000000000013dff8 /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: e14503791ca790aee59797b668187c00)
02-22 17:20:27.824 10324 10324 F DEBUG : #24 pc 00000000001347e8 /apex/com.android.art/lib64/libart.so (art_quick_invoke_static_stub+568) (BuildId: e14503791ca790aee59797b668187c00)
02-22 17:20:27.824 10324 10324 F DEBUG : #25 pc 0000000000198eb0 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+232) (BuildId: e14503791ca790aee59797b668187c00)
02-22 17:20:27.824 10324 10324 F DEBUG : #26 pc 00000000001cc910 /apex/com.android.art/lib64/libart.so (art::ClassLinker::InitializeClass(art::Thread*, art::Handleart::mirror::Class, bool, bool)+2820) (BuildId: e14503791ca790aee59797b668187c00)
02-22 17:20:27.824 10324 10324 F DEBUG : #27 pc 00000000001a9484 /apex/com.android.art/lib64/libart.so (art::ClassLinker::EnsureInitialized(art::Thread*, art::Handleart::mirror::Class, bool, bool)+156) (BuildId: e14503791ca790aee59797b668187c00)
02-22 17:20:27.824 10324 10324 F DEBUG : #28 pc 0000000000617824 /apex/com.android.art/lib64/libart.so (artAllocObjectFromCodeResolvedRegionTLAB+420) (BuildId: e14503791ca790aee59797b668187c00)
02-22 17:20:27.824 10324 10324 F DEBUG : #29 pc 000000000013ca88 /apex/com.android.art/lib64/libart.so (art_quick_alloc_object_resolved_region_tlab+104) (BuildId: e14503791ca790aee59797b668187c00)
02-22 17:20:27.824 10324 10324 F DEBUG : #30 pc 0000000000021334 /data/user/0/com.testHU.UnityHotUpdate/tinker/patch-40572dfe/dex/oat/arm64/tinker_classN.odex

3.崩溃代码
以下是出现崩溃的代码(代理函数)

static void* new_dlopen_ext(const char* cPath,int flags){ BYTEHOOK_STACK_SCOPE(); DEBUG("new_dlopen_ext path:%s", cPath); void* result = BYTEHOOK_CALL_PREV(new_dlopen_ext, cPath, flags); return result; }

以下是注册逻辑

bytehook_hook_partial(NULL, nullptr, nullptr, "android_dlopen_ext", reinterpret_cast<void *>(new_dlopen_ext), NULL, NULL);

4.崩溃设备信息
设备名称: SAMSUNG 三星S10+
设备model号: SM-G9750
系统版本: 11

5.在sample中不会出现崩溃的代码
代理函数
`
static void* new_dlopen_ext(const char* cPath,int flags){
void* result;
result = BYTEHOOK_CALL_PREV(new_dlopen_ext, strlen_t, cPath, flags);

LOG("new_dlopen %s ", cPath);
BYTEHOOK_POP_STACK();
return result;

}
`

以下是注册逻辑
bytehook_hook_partial(NULL, NULL, NULL, "android_dlopen_ext", (void*)new_dlopen_ext, NULL, NULL);

called in a non-hook status?

bytehook Version

1.0.5

Android OS Version

7.1

Android ABIs

armeabi-v7a

Device Manufacturers and Models

any

Describe the Bug

bhook拦截了dlsym函数
FILE* new_fopen(const char* __path, const char* __mode){
BYTEHOOK_STACK_SCOPE();
return BYTEHOOK_CALL_PREV(new_fopen, __path, __mode);;
}
void* new_dlsym(void* __handle, const char* __symbol){
BYTEHOOK_STACK_SCOPE();
void rs = NULL;
if(strcmp(__symbol, "fopen") == 0) rs = (void
)new_fopen;
else rs = BYTEHOOK_CALL_PREV(new_dlsym, __handle, __symbol);
LOGD("dlsym: %s, func:%p", __symbol, rs);
return rs;
}

如果目标应用通过dlsym来调用fopen的时候会崩溃,我看源码中写有
if (0 == stack->frames_cnt) abort(); // called in a non-hook status?
有啥办法解决吗?

@caikelun hook时机

@caikelun 感谢回复!这两天我尝试了一下,但没有找到比较好的方案。
原因是linker内部的dl_iterate_phdr和dlopen是有互斥锁的,而.init和.init_array调用是在dlopen内部,所以直到dlopen结束前是无法读取到elf的 😭

是否可以从导出符号__dl__ZN6soinfo17call_constructorsEv入手

自动hook新加载的动态库可能没被hook的问题

我在线上使用 bhook,版本 v1.0.3,想 hook 一个动态下载的 so,发现会有 so 已经加载好,但是 bhook 没有自动去 hook 的问题,出现概率比较低。

我找到了一种复现场景,发现是 bhook 没有立即监听到动态库的加载,所以也没有 hook 了:
1.线程 1 去初始化 bhook,调用 Bytehook.init,并且调用 bytehook_hook_single;
2.线程 2 加载某一个 so;

复现的环境和代码我也贴出来:

bhook 版本:v1.0.3
机型:OnePlus6,Android 10

我改了一些代码,让问题复现:

void bh_task_manager_hook(bh_task_manager_t *self, bh_task_t *task)
{
    if(bh_dl_monitor_is_initing())
    {
        static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
        static bool oneshot_refreshed = false;
        if(!oneshot_refreshed)
        {
            bool hooked = false;
            pthread_mutex_lock(&lock);
            if(!oneshot_refreshed)
            {
                BH_LOG_INFO("task_id:%u, hit init", task->id);
                bh_dl_monitor_dlclose_rdlock();
                bh_elf_manager_refresh(bh_core_global()->elf_mgr, false, NULL, NULL);
                BH_LOG_INFO("sleep start...");  // 获取完 maps 停一会,然后 APP 另一个线程去加载新的 so,模拟动态 so 随机加载的场景
                sleep(10);
                BH_LOG_INFO("sleep end...");
                bh_task_hook(task);
                bh_dl_monitor_dlclose_unlock();
                oneshot_refreshed = true;
                hooked = true;
            }
            pthread_mutex_unlock(&lock);
            if(hooked) return;
        }
    }
    else
    {
        // start & check dl-monitor
        if(0 != bh_task_manager_init_dl_monitor(self))
        {
            // For internal tasks in the DL monitor, this is not an error.
            // But these internal tasks do not set callbacks, so there will be no side effects.
            bh_task_hooked(task, BYTEHOOK_STATUS_CODE_INITERR_DLMTR, NULL, NULL);
            return;
        }
    }

    BH_LOG_INFO("task_id:%u start hook", task->id);

    bh_dl_monitor_dlclose_rdlock();
    bh_task_hook(task);
    bh_dl_monitor_dlclose_unlock();
}

大致的流程是 bhook 会先 hook dlopen 系列函数,会先调用一遍 bh_elf_manager_refresh 把当前的 so 信息缓存起来,然后执行 hook dlopen 的任务;如果中途有别的 so 加载,bhook 会漏掉这些新的 so,相当于没监听到。
有个补救措施是 如果后续有新的 so 加载会调用 dlopen,就会触发 bh_elf_manager_refresh 再刷一遍缓存,之前漏掉的 so 也会加进来并且执行它们的 hook 任务,这样表现的情况就是 hook 被延后了。假如后续没有触发 bh_elf_manager_refresh,那么这次的 hook 就失败了

我感觉这种情况无法完全避免,如果对可靠性要求高的话,我可以每隔一段时间调用 refresh 吗?就像 xhook 的那种用法一样

是否遗漏了self->cfi_hook_lock的destroy操作

bytehook Version

1.0.0

Android OS Version

10.0

Android ABIs

armeabi-v7a

Device Manufacturers and Models

Google Pixel 3

Describe the Bug

pthread_mutex_destroy(&(*self)->hook_lock);

老师你好,这个地方是否遗漏了self->cfi_hook_lock的destroy操作?

pthread_mutex_destroy(&(*self)->hook_lock);
#ifdef LP64
pthread_mutex_destroy(&(*self)->cfi_hook_lock);
#endif
pthread_mutex_destroy(&(*self)->dyn_parse_lock);

hook jni 方法失败

bytehook Version

1.0.6

Android OS Version

12

Android ABIs

armeabi-v7a

Device Manufacturers and Models

mix4

Describe the Bug

我尝试hook jni 方法的时候,无法hook jni 方法

这是我的JNI方法

JNIEXPORT void JNICALL
Java_com_lyy_crashhook_NativeLib_stringFromJNI(JNIEnv *env, jobject thiz) {
    LOG("Java_com_lyy_crashhook_NativeLib_stringFromJNI");
}

这是我的Hook代码

    bytehook_hook_single("libhookee.so", NULL, "Java_com_lyy_crashhook_NativeLib_stringFromJNI",
                         (void *) open_proxy_manual,
                         crash_hooked_callback,
                         NULL);

返回结果总是:

hooked. stub: b4000072fbc7f100, status: 13, caller_path_name: /data/app/~~rQpm4GQxSoUuAhD1gtXleA==/com.lyy.invorkhook-qoYvtStS3UiRqUyF-62m4Q==/lib/arm64/libhookee.so, sym_name: Java_com_lyy_crashhook_NativeLib_stringFromJNI, new_func: 72edc6e958, prev_func: 0, arg: 0

可否支持armeabi架构呢?

the Feature, Motivation and Pitch

你好,希望后续可以支持下,还是有一些场景只支持这种架构的,虽然比较老了。

Alternatives

No response

Additional context

No response

bh_elf_tree操作时crash

机型:Android 8.1.0/9/11 Redmi 5 Plus/Redmi K40/Mi 10S/Redmi K30/Redmi 6 Pro
cpuArch:arm64-v8a
bhook版本:1.0.3

#00 pc 000000000001d09c /system/lib64/libc.so (strcmp+28)
#01 pc 00000000000073b4 /data/app/==/lib/arm64/libbytehook.so  (bytehook/src/main/cpp/bh_elf_manager.c:53)
#02 pc 0000000000006fac /data/app/==/lib/arm64/libbytehook.so  (bytehook/src/main/cpp/bh_elf_manager.c:96)
#03 pc 00000000000098b8 /system/bin/linker64 (__dl__Z18do_dl_iterate_phdrPFiP12dl_phdr_infomPvES1_+76)
#04 pc 00000000000092dc /system/bin/linker64 (__dl_dl_iterate_phdr+48)
#05 pc 00000000000011cc /system/lib64/libdl.so (dl_iterate_phdr+8)
(bytehook/src/main/cpp/bh_dl_iterate.c:83)
(bytehook/src/main/cpp/bh_dl_iterate.c:156)
#06 pc 0000000000006ab4 /data/app/==/lib/arm64/libbytehook.so  (bytehook/src/main/cpp/bh_elf_manager.c:132)
#07 pc 0000000000005714 /data/app/==/lib/arm64/libbytehook.so
#08 pc 00000000000011b8 /system/lib64/libdl.so (dlclose+8)
......
#14 pc 0000000000067e50 /system/lib64/libc.so (_ZL15__pthread_startPv+36)
#15 pc 000000000001f280 /system/lib64/libc.so (__start_thread+68)

是在每次dlopen/dlclose的时候刷新elf tree缓存,遍历elf的时候挂了...崩溃的位置在 bh_elf_tree_RB_FIND、bh_elf_tree_RB_NEXT,应该都是同一个问题。
看log好像都是APP在后台发生的

hook 构造函数崩溃问题

bytehook Version

1.0.6

Android OS Version

10.0

Android ABIs

armeabi-v7a

Device Manufacturers and Models

pixel 1

Describe the Bug

希望hook Android libbase.so android::base::LogMessage::LogMessage构造函数,hook代码如下:
`namespace android {
namespace base {

    enum LogSeverity {
        VERBOSE,
        DEBUG,
        INFO,
        WARNING,
        ERROR,
        FATAL_WITHOUT_ABORT,
        FATAL,
    };

    enum LogId {
        DEFAULT,
        MAIN,
        SYSTEM,
    };

    void LogMessage(const char *file, unsigned int line, LogId id, LogSeverity severity,
                    const char *tag, int error) {
        BYTEHOOK_STACK_SCOPE();
        ALOGD("LogMessage %s",file);
        BYTEHOOK_CALL_PREV(LogMessage, file, line, id, severity, tag, error);
    }

    void HookCallback(bytehook_stub_t task_stub, int status,
                      const char *caller_path_name, const char *sym_name,
                      void *new_func, void *prev_func, void *hooked_arg) {
        ALOGE("hook: %s-%s-%d", caller_path_name, sym_name, status);
    }

    void hook(){
        bytehook_hook_single("libart.so", "libbase.so",
                "_ZN7android4base10LogMessageC2EPKcjNS0_5LogIdENS0_11LogSeverityES3_i",
                             reinterpret_cast<void *>(LogMessage), HookCallback, NULL);
   }
}

}`

然后时间运行时在BYTEHOOK_CALL_PREV调用原函数时会崩溃,崩溃栈如下:
image

大佬帮忙看下是怎么回事啊

老哥,BYTESIG_TRY好像不能生效

bytehook Version

1.0.6

Android OS Version

13

Android ABIs

arm64-v8a

Device Manufacturers and Models

Pixel 5

Describe the Bug

老哥,我尝试使用BYTESIG_TRY,发现不能捕获异常,下面是我的测试代码

void init_once(void) {
//    bytesig_init(SIGSEGV);
//    bytesig_init(SIGBUS);
//    bytesig_init(SIGILL);
    bytesig_init(SIGTRAP);
    // ......
}

void crashTest1(void) {
    int i;
    init_once();
    LOG("crashTest");
    int *p = NULL;
    BYTESIG_TRY(SIGABRT)
            {
//                call_some_native_function();
                *p = 2;
            }
        BYTESIG_CATCH(signum, code)
            {
                LOG("signum %d (code %d)", signum, code);
            }
            BYTESIG_EXIT
}

使用这测试代码后,发现还是会出现崩溃
image

求助Dl_info dladdr

demo代码里面有用到:
Dl_info 和 dladdr
在bytehook.h头文件中没有这两个符号的定义,我该怎么用这两个符号?

armeabi-v7a hook失败,用xhook库能成功

bytehook Version

1.0.5

Android OS Version

6.0

Android ABIs

armeabi-v7a

Device Manufacturers and Models

模拟器

Describe the Bug

ANDROID_API < 21, 运行时apilevel=23,尝试修改,默认没走/proc/self/maps,改成走/proc/self/maps部分能成功,不过app会闪退

鲜时光TV APK Android 13平台无法打开

bytehook Version

1.0.0

Android OS Version

13

Android ABIs

armeabi-v7a, arm64-v8a

Device Manufacturers and Models

Mediatek TV

Describe the Bug

com.bytedance.mira.hook crash

04-12 02:17:35.776 6461 6461 I System.out: mira/activity: MiraInstrumentation execStartActivity handleException
04-12 02:17:35.785 6461 6461 W System.err: mira/activity: MiraInstrumentation execStartActivity error. null
04-12 02:17:35.785 6461 6461 W System.err: android.content.ActivityNotFoundException: Unable to find explicit activity class {com.ixigua.android.tv.bestv/com.ixigua.tv.plugin.feed.home.view.HomeActivity}; have you declared this activity in your AndroidManifest.xml, or does your intent not match its declared ?
04-12 02:17:35.785 6461 6461 W System.err: java.lang.reflect.Method.invoke(Native Method)
04-12 02:17:35.785 6461 6461 W System.err: com.bytedance.mira.util.MethodUtils.invokeMethod(SourceFile:161)
04-12 02:17:35.785 6461 6461 W System.err: com.bytedance.mira.hook.delegate.MiraInstrumentation.execStartActivity(SourceFile:165)
04-12 02:17:35.785 6461 6461 W System.err: android.app.Activity.startActivityForResult(Activity.java:5470)
04-12 02:17:35.785 6461 6461 W System.err: android.support.v4.app.BaseFragmentActivityApi16.startActivityForResult(SourceFile:54)
04-12 02:17:35.785 6461 6461 W System.err: android.support.v4.app.FragmentActivity.startActivityForResult(SourceFile:68)
04-12 02:17:35.785 6461 6461 W System.err: android.app.Activity.startActivityForResult(Activity.java:5428)
04-12 02:17:35.786 6461 6461 W System.err: android.support.v4.app.FragmentActivity.startActivityForResult(SourceFile:751)
04-12 02:17:35.786 6461 6461 W System.err: android.app.Activity.startActivity(Activity.java:5926)
04-12 02:17:35.786 6461 6461 W System.err: android.app.Activity.startActivity(Activity.java:5893)
04-12 02:17:35.786 6461 6461 W System.err: com.ixigua.tv.plugin.a.b.x30_a.f(SourceFile:274)
04-12 02:17:35.786 6461 6461 W System.err: com.ixigua.tv.plugin.a.b.x30_a.c(SourceFile:249)
04-12 02:17:35.786 6461 6461 W System.err: com.ixigua.tv.plugin.a.b.x30_a.a(SourceFile:128)
04-12 02:17:35.786 6461 6461 W System.err: com.ixigua.tv.plugin.a.b.x30_b.a(SourceFile:13)
04-12 02:17:35.786 6461 6461 W System.err: com.ixigua.tv.plugin.application.service.PluginService.onSplashCreate(SourceFile:93)
04-12 02:17:35.786 6461 6461 W System.err: com.ixigua.android.tv.module.home.view.MainActivity.a(SourceFile:103)
04-12 02:17:35.786 6461 6461 W System.err: com.ixigua.android.tv.service.launch.a.c(SourceFile:82)
04-12 02:17:35.786 6461 6461 W System.err: com.ixigua.android.tv.service.launch.a.a(SourceFile:34)
04-12 02:17:35.786 6461 6461 W System.err: com.ixigua.android.tv.module.home.view.MainActivity.onCreate(SourceFile:70)
04-12 02:17:35.786 6461 6461 W System.err: android.app.Activity.performCreate(Activity.java:8290)
04-12 02:17:35.786 6461 6461 W System.err: android.app.Activity.performCreate(Activity.java:8269)
04-12 02:17:35.787 6461 6461 W System.err: android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1384)
04-12 02:17:35.787 6461 6461 W System.err: com.bytedance.mira.hook.delegate.MiraInstrumentation.callActivityOnCreate(SourceFile:385)
04-12 02:17:35.787 6461 6461 W System.err: android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3657)
04-12 02:17:35.787 6461 6461 W System.err: android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3813)
04-12 02:17:35.787 6461 6461 W System.err: android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
04-12 02:17:35.787 6461 6461 W System.err: android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
04-12 02:17:35.787 6461 6461 W System.err: android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
04-12 02:17:35.787 6461 6461 W System.err: android.app.ActivityThread$H.handleMessage(ActivityThread.java:2308)
04-12 02:17:35.787 6461 6461 W System.err: android.os.Handler.dispatchMessage(Handler.java:106)
04-12 02:17:35.787 6461 6461 W System.err: android.os.Looper.loopOnce(Looper.java:201)
04-12 02:17:35.787 6461 6461 W System.err: android.os.Looper.loop(Looper.java:288)
04-12 02:17:35.787 6461 6461 W System.err: android.app.ActivityThread.main(ActivityThread.java:7898)
04-12 02:17:35.787 6461 6461 W System.err: java.lang.reflect.Method.invoke(Native Method)
04-12 02:17:35.787 6461 6461 W System.err: com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
04-12 02:17:35.787 6461 6461 W System.err: com.android.internal.os.ZygoteInit.main(ZygoteInit.java:938)

关于符号查找的一个小建议

static ElfW(Sym) *bh_elf_find_import_func_symbol_by_symbol_name(bh_elf_t *self, const char *sym_name)

大佬,你好
关于符号的查找,个人觉得xhook的写法更好:
布隆过滤器对于item存在是有误判的,但对于item不存在是有精准保障的。
所以存在gnu_hash段、sym_name确实不存在于gnu_hash布隆过滤器时,不应该继续查找。

bHook在部分系统上面会报“替换 GOT 值之前,通过 dladdr() 验证函数地址失败。”错误码19

bytehook Version

1.0.10

Android OS Version

Android 14

Android ABIs

arm64-v8a

Device Manufacturers and Models

小米 13 Android 14和Pixel 3XL Android 12

Describe the Bug

bHook在部分系统上面会报“替换 GOT 值之前,通过 dladdr() 验证函数地址失败。” 错误码19,屏蔽下面这块代码
image
能绕过这个报错。

另外屏蔽这块代码之后,后续的hook是成功的,看起来不需要verify the GOT value这个步骤也是可以的。不清楚是不是verify the GOT value这块代码在部分系统上面有兼容问题?

支持C++函数的hook吗

想hook libDexFile.so 中 Dex相关的函数,但是用了C++的几个导出符号,都没有hook上,不知道是不是我调用的问题

Crash at hook __system_property_read_callback

bytehook Version

1.0.9

Android OS Version

13

Android ABIs

arm64-v8a

Device Manufacturers and Models

Xiaomi POCO X3 Pro

Describe the Bug

I'm trying to hook __system_property_read_callback:

#if __ANDROID_API__ >= 26
void __system_property_read_callback(const prop_info* _Nonnull __pi,
    void (* _Nonnull __callback)(void* _Nullable __cookie, const char* _Nonnull __name, const char* _Nonnull __value, uint32_t __serial),
    void* _Nullable __cookie) __INTRODUCED_IN(26);
#endif /* __ANDROID_API__ >= 26 */

I have this code:

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

static std::map<void *, T_Callback> map;

static void
handle_system_property(void *cookie, const char *name, const char *value, uint32_t serial) {

    LOGD("[%s] -> %s", name, value);

    std::string_view prop(name);

    if (prop.compare("ro.product.first_api_level") == 0) value = "25";
    else if (prop.compare("ro.boot.verifiedbootstate") == 0) value = "green";
    else if (prop.compare("ro.secure") == 0 || prop.compare("ro.boot.flash.locked") == 0)
        value = "1";
    else if (prop.compare("ro.debuggable") == 0) value = "0";
    else if (prop.compare("ro.boot.vbmeta.device_state") == 0) value = "locked";
    else if (prop.compare("sys.usb.state") == 0) value = "none";

    map[cookie](cookie, name, value, serial);
}

static void my_hook(const prop_info *pi, T_Callback callback, void *cookie) {
    BYTEHOOK_STACK_SCOPE();
    LOGD("Cookie: %p", cookie);
    map[cookie] = callback;
    BYTEHOOK_CALL_PREV(my_hook, pi, handle_system_property, cookie);
}

static void createHook() {
    bytehook_init(BYTEHOOK_MODE_AUTOMATIC, true);

    LOGD("Trying to get __system_property_read_callback handle...");
    auto handle = bytehook_hook_all(
            nullptr,
            "__system_property_read_callback",
            reinterpret_cast<void *>(my_hook),
            nullptr,
            nullptr
    );
    if (handle == nullptr) {
        LOGD("Couldn't get __system_property_read_callback handle :(");
    } else {
        LOGD("Hooked __system_property_read_callback at %p", handle);
    }
}

But when it runs the app crash, I tried to change __system_property_read_callback to __system_property_get and it works! But doesn't log any prop :(

Is it maybe the problem the custom "handle_system_property" function?

Using Shadowhook I can hook both with no problems.

hook so库的open函数在访问/apex/com.android.runtime/lib64/bionic/libc.so出现崩溃

bytehook Version

1.0.4

Android OS Version

13

Android ABIs

arm64-v8a

Device Manufacturers and Models

Google Pixel 5(Android 13)

Describe the Bug

问题描述:

你好!
我新建了一个空的Unity工程(版本: 2018.4.36f1),导出了Android工程,导出的工程中有三个so,我需要hook libunity.so的所有open函数从而修改文件路径。我发现在Google Pixel 5手机上,我hook以后会出现崩溃,如果我不hook就不会崩溃,其他手机(包括小米8、小米max2、HUAWEI nova7、HUAWEI Mate 10等)没有出现这个问题。

代码片段:

因为open函数有多个,我在代理函数中用可变参数来调用,不知道是否正确。

image

崩溃堆栈:

image

附件是详细的日志和我的工程,解压AndroidUnity2018EmptyFor50.zip导入Android studio可以复现问题。
crash.log

AndroidUnity2018EmptyFor50.zip

怎么使用so提供的非公开函数?

目前看提供的API里面是需要有调用方触发,然后hook掉函数调用(比如hook malloc打印堆栈)。是否能够调用非公开的函数,比如需要实现调用libart.so里面的函数(比如art::Thread::DumpJavaStack),如何通过符号查找到函数并且调用,使用库提供的功能?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.