bytedance / bhook

:fire: ByteHook is an Android PLT hook library which supports armeabi-v7a, arm64-v8a, x86 and x86_64.
https://github.com/bytedance/bhook/tree/main/doc#readme
MIT License
2.05k stars 315 forks source link

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

Closed tyrionchen closed 2 years ago

tyrionchen commented 2 years ago

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

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

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 (dlZ9do_dlopenPKciPK17android_dlextinfoPKv+988) (BuildId: 14e4f7c3a987c01b47ee17cc5aa77135) 02-22 17:20:27.823 10324 10324 F DEBUG : #01 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 : #02 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 : #04 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 : #06 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 : #08 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 : #09 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::Handle, 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::Handle, 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);

caikelun commented 2 years ago

android从7.0开始对dlopen / android_dlopen_ext做了权限限制,你如果直接hook这两个函数,会导致如果hook到的调用试图打开的so是app没有权限的,那你在proxy函数中也就无法调用原函数了。可能有以下的几种方式能处理:

  1. 类似bytehook源码中 DL monitor 的处理方式,针对不同android版本分别处理。但是实现起来比较复杂。

  2. 如果只是监听dlopen行为,不修改参数和返回值,可以用 bytehook_add_dlopen_callbackhttps://github.com/bytedance/bhook/blob/main/doc/native_manual.zh-CN.md#hook-dlopen-%E5%92%8C-android_dlopen_ext

  3. inlinehook linker 内部的 do_dlopen,分版本分别hook:__dl__Z9do_dlopenPKciPK17android_dlextinfo, __dl__Z9do_dlopenPKciPK17android_dlextinfoPv, __dl__Z9do_dlopenPKciPK17android_dlextinfoPKv。线上稳定的inlinehook方案推荐用我们开源的 shadowhook:https://github.com/bytedance/android-inline-hook

具体到你的场景,我个人倾向于用第三种方式。

tyrionchen commented 2 years ago

android从7.0开始对dlopen / android_dlopen_ext做了权限限制,你如果直接hook这两个函数,会导致如果hook到的调用试图打开的so是app没有权限的,那你在proxy函数中也就无法调用原函数了。可能有以下的几种方式能处理:

  1. 类似bytehook源码中 DL monitor 的处理方式,针对不同android版本分别处理。但是实现起来比较复杂。
  2. 如果只是监听dlopen行为,不修改参数和返回值,可以用 bytehook_add_dlopen_callbackhttps://github.com/bytedance/bhook/blob/main/doc/native_manual.zh-CN.md#hook-dlopen-%E5%92%8C-android_dlopen_ext
  3. inlinehook linker 内部的 do_dlopen,分版本分别hook:__dl__Z9do_dlopenPKciPK17android_dlextinfo, __dl__Z9do_dlopenPKciPK17android_dlextinfoPv, __dl__Z9do_dlopenPKciPK17android_dlextinfoPKv。线上稳定的inlinehook方案推荐用我们开源的 shadowhook:https://github.com/bytedance/android-inline-hook

具体到你的场景,我个人倾向于用第三种方式。

感谢解答! 我看到Native API文档(https://github.com/bytedance/bhook/blob/main/doc/native_manual.zh-CN.md) 里有提到如果用自动模式,可以用BYTEHOOK_CALL_PREV调用原函数,请问下如果选择自动模式这个能否使用呢?

另外比较奇怪的一点,我在sample里面增加的hook android_dlopen_ext,这个似乎跑起来是正常的,但如果在android_dlopen_ext的代理函数中,在BYTEHOOK_CALL_PREV调用之前打印任何内容,就会出现崩溃。

image

HookC.zip