【公众号回复 “1024”,免费领取程序员赚钱实操经验】
大家好,我是章鱼猫。
今天推荐的这个项目是「ByteHook」,是一个针对 Android App 的 PLT hook 框架。
字节跳动的大多数 Android App 在线上使用了 ByteHook 作为 PLT hook 方案。
随着 Android App 开发的技术栈不断向 Native 层扩展,Native hook 已经被用于越来越多的技术场景中。Android Native hook 的实现方式有很多种,其中使用最广泛,并且通用性最强的是 inline hook 和 PLT hook。
在真实的线上环境中,经常是 PLT hook 和 inline hook 并存的,这样它们可以各自扬长避短,在不同的场景中发挥作用。
更完善的 Android PLT hook 方案
我们迫切需要一个新的更完善的 Android PLT hook 方案,它应该是什么样子的呢?它应该满足这些条件:
要有一套真正可靠的 native 崩溃兜底机制,来避免可控范围内的 native 崩溃。
可以随时 hook 和 unhook 单个、部分、全部的调用者 ELF。
当新的 ELF 被加载到内存后,它应该自动的被执行所有预定的 hook 操作。
多个使用方如果 hook 了同一个调用点,它们应该可以彼此独立的执行 unhook,相互不干扰。
为了适配 Android linker namespace,应该可以指定 hook 函数的被调用者 ELF。
能自动避免由于 hook 引起的意外的“递归调用”和“环形调用”。比如:open 的 proxy 函数中调用了 read,然后 read 的 proxy 函数中又调用了 open。如果这两个 proxy 存在于两个独立的 SDK 中,此时形成的环形调用将很难在 SDK 开发阶段被发现。如果在更多的 SDK 之间形成了一个更大的 proxy 函数调用环,情况将会失去控制。
proxy 函数中要能以正常的方式获取 backtrace(libunwind、libunwindstack、llvm libunwind、FP unwind 等)。有大量的业务场景是需要 hook 后在 proxy 函数中抓取和保存 backtrace,然后在特定的时机 dump 和聚合这些 backtrace,符号化后再将数据投递到服务端,从而监控和发现业务问题。
hook 管理机制本身带来的额外性能损耗要足够低。
带着上面的这些目标设计和开发了 ByteHook。
ByteHook 特征:
对同一个函数的多个 hook 和 unhook 互相不冲突。
可以 hook 进程中单个、部分或全部的动态库。
自动 hook 新加载的动态库。
自动避免代理函数之间的递归调用和环形调用。
代理函数中支持回溯调用栈。
支持 Android 4.1 - 12 (API level 16 - 31)。
支持 armeabi-v7a, arm64-v8a, x86 和 x86_64。
使用 MIT 许可证授权。
开源项目地址:https://github.com/bytedance/bhook
开源项目组织:bytedance
推荐阅读
最近,章鱼猫建了一个「GitHub 精选交流群」,欢迎大家一起交流优秀开源项目,也可以宣传自己的开源项目,在 「GitHub 精选」公众号后台回复【加群】邀请你入群。
---特别推荐---
特别推荐:一个新的优质的专注分享各种浏览器插件、黑科技教程、各种你想不到的高效率软件及工具的公众号,「黑科技指北」,非常值得大家关注。点击下方公众号卡片,直接关注。