当前位置: 首页 > 软件库 > 手机/移动开发 > >

x-hook

针对 Android 平台 ELF 的 PLT hook 库
授权协议 MIT
开发语言 C/C++
所属分类 手机/移动开发
软件类型 开源软件
地区 国产
投 递 者 许博
操作系统 Android
开源组织
适用人群 未知
 软件概览

爱奇艺开源的一个针对 Android 平台 ELF (可执行文件和动态库) 的 PLT (Procedure Linkage Table) hook 库。

xhook 一直在稳定性和兼容性方面做着持续的优化。

              oooo                            oooo        
              `888                            `888        
  oooo    ooo  888 .oo.    .ooooo.   .ooooo.   888  oooo  
   `88b..8P'   888P"Y88b  d88' `88b d88' `88b  888 .8P'   
     Y888'     888   888  888   888 888   888  888888.    
   .o8"'88b    888   888  888   888 888   888  888 `88b.  
  o88'   888o o888o o888o `Y8bod8P' `Y8bod8P' o888o o888o

特征

  • 支持 Android 4.0 (含) 以上版本 (API level >= 14)。

  • 支持 armeabi, armeabi-v7a 和 arm64-v8a。

  • 支持 ELF HASH 和 GNU HASH 索引的符号。

  • 支持 SLEB128 编码的重定位信息。

  • 需要 ROOT 权限。

  • 不依赖于任何的第三方动态库。

  • 纯 C 的代码。比较小的库体积。

编译

你需要 google NDK 来编译 xhook。

最新版本的 xhook 在开发和调试中使用的 NDK 版本是 r16b

  • 编译动态库 (libxhook.so 和其他的用于测试的动态库)

./build_libs.sh
  • 把动态库安装到 Demo 工程的 libs 目录中

./install_libs.sh
  • 清除动态库

./clean_libs.sh

Demo

cd ./xhookwrapper/
./gradlew assembleDebug
adb install ./app/build/outputs/apk/debug/app-debug.apk

API

外部 API 头文件: libxhook/jni/xhook.h

1. 注册 hook 信息

int xhook_register(const char  *pathname_regex_str,  
                   const char  *symbol,  
                   void        *new_func,  
                   void       **old_func);

在当前进程的内存空间中,在每一个符合正则表达式 pathname_regex_str 的已加载ELF中,每一个调用 symbol 的 PLT 入口点的地址值都将给替换成 new_func。之前的 PLT 入口点的地址值将被保存在 old_func 中。

new_func 必须具有和原函数同样的函数声明。

成功返回 0,失败返回 非0。

pathname_regex_str 只支持 POSIX BRE 定义的正则表达式语法。

2. 执行 hook

int xhook_refresh(int async);

根据前面注册的 hook 信息,执行真正的 hook 操作。

给 async 参数传 1 表示执行异步的 hook 操作,传 0 表示执行同步的 hook 操作。

成功返回 0,失败返回 非0。

xhook 在内部维护了一个全局的缓存,用于保存最后一次从 /proc/self/maps 读取到的 ELF 加载信息。每次一调用 xhook_refresh 函数,这个缓存都将被更新。xhook 使用这个缓存来判断哪些 ELF 是这次新被加载到内存中的。我们每次只需要针对这些新加载的 ELF 做 hook 就可以了。

3. 清除缓存

void xhook_clear();

清除 xhook 的缓存,重置所有的全局标示。

如果你确定你需要的所有 PLT 入口点都已经被替换了,你可以调用这个函数来释放和节省一些内存空间。

4. 启用/禁用 调试信息

void xhook_enable_debug(int flag);

给 flag 参数传 1 表示启用调试信息,传 0 表示禁用调试信息。 (默认为:禁用)

调试信息将被输出到 logcat,对应的 TAG 为:xhook

5. 启用/禁用 SFP (段错误保护)

void xhook_enable_sigsegv_protection(int flag);

给 flag 参数传 1 表示启用 SFP,传 0 表示禁用 SFP。 (默认为:启用)

xhook 并不是一个常规的业务层的动态库。在 xhook 中,我们不得不直接计算一些内存指针的值。在一些极端的情况和环境下,读或者写这些指针指向的内存会发生段错误。根据我们的测试,xhook 的行为将导致 APP 崩溃率增加 "一千万分之一" (0.0000001)。(具体崩溃率可能会增加多少,也和你想要 hook 的库和符号有关)。最终,我们不得不使用某些方法来防止这些无害的崩溃。我们叫它SFP (段错误保护),它是由这些调用和值组成的:sigaction(), SIGSEGV, siglongjmp() 和 sigsetjmp()

在 release 版本的 APP 中,你应该始终启用 SFP,这能防止你的 APP 因为 xhook 而崩溃。在 debug 版本的 APP 中,你应该始终禁用 SFP,这样你就不会丢失那些一般性的编码失误导致的段错误,这些段错误是应该被修复的。

应用举例

//监测内存泄露
xhook_register(".*\\.so$", "malloc",  my_malloc,  NULL);
xhook_register(".*\\.so$", "calloc",  my_calloc,  NULL);
xhook_register(".*\\.so$", "realloc", my_realloc, NULL);
xhook_register(".*\\.so$", "free",    my_free,    NULL);

//监控 sockets 生命周期
xhook_register(".*\\.so$", "getaddrinfo", my_getaddrinfo, NULL);
xhook_register(".*\\.so$", "socket",      my_socket,      NULL);
xhook_register(".*\\.so$", "setsockopt"   my_setsockopt,  NULL);
xhook_register(".*\\.so$", "bind",        my_bind,        NULL);
xhook_register(".*\\.so$", "listen",      my_listen,      NULL);
xhook_register(".*\\.so$", "connect",     my_connect,     NULL);
xhook_register(".*\\.so$", "shutdown",    my_shutdown,    NULL);
xhook_register(".*\\.so$", "close",       my_close,       NULL);

//过滤出和保存部分安卓 log 到本地文件
xhook_register(".*\\.so$", "__android_log_write",  my_log_write,  NULL);
xhook_register(".*\\.so$", "__android_log_print",  my_log_print,  NULL);
xhook_register(".*\\.so$", "__android_log_vprint", my_log_vprint, NULL);
xhook_register(".*\\.so$", "__android_log_assert", my_log_assert, NULL);

//追踪某些调用
xhook_register("^/system/.*$", "mmap",   my_mmap,   NULL);
xhook_register("^/vendor/.*$", "munmap", my_munmap, NULL);

//防御某些注入攻击
xhook_register(".*com\\.hacker.*\\.so$", "malloc",  my_malloc_always_return_NULL, NULL);
xhook_register(".*/libhacker\\.so$",     "connect", my_connect_with_recorder,     NULL);

//修复某些系统 bug
xhook_register(".*some_vendor.*/libvictim\\.so$", "bad_func", my_nice_func, NULL);

//现在执行 hook!
xhook_refresh(1);

许可证

Copyright (c) 2018-present, 爱奇艺, Inc. All rights reserved.

xhook 中大多数的源码使用 MIT 许可证,另外的一些源码使用 BSD 样式的许可证。

详细信息请查看 LICENSE 文件。

 
  • 这一课,我们准备用 emqx-rabbitmq-hook 插件来替换掉 IotHub 之前使用的 Webhook 插件。 发布 emqx-rabbitmq-hook 插件 虽然在我的电脑上已经有了可运行的 emqx-rabbitmq-hook 插件,但是为了在别的系统和机器上使用这个插件,还是必须要先发布这个插件。 EMQ X 插件的代码需要用一个 git 仓库来存放,你可以 点击这里 找到 em

  • 手淘版的x-sgin的算法接口,终于实现了 手淘xsign的协议算法,最新带 x-mini-wua ***更新时间:2020-1-2 15:44:53,***大家都知道,有时候PC和WAP版的协议根本满足不了业务场景的需求,但是手淘可以满足,但是手淘最大的难度就是X-sign,可以说是万事俱备只欠X-sign,因为公司安排给我的任务就是解决这个,前前后后花了差不多一个月时间把X-sign的签名算法

  • 此项目是根据sylar框架实现,是从零开始重写sylar,也是对sylar丰富与完善 项目地址:https://gitee.com/lzhiqiang1999/server-framework 简介 项目介绍:实现了一个基于协程的服务器框架,支持多线程、多协程协同调度;支持以异步处理的方式提高服务器性能;封装了网络相关的模块,包括socket、http、servlet等,支持快速搭建HTTP服务器

  • android5.0以上,webview所在进程如果是android.uid.system,运行则会直接崩溃。 解决方法: 2个apk,由主apk做需要system权限的业务,拉起webview apk 通过hook方式解决,参考android.webkit.WebViewFactory源码,详细代码如下 public class WebViewUtils { private static fin

  • 什么是hook 本质是一个函数,把setup函数中使用的composition API进行了封装 类似于Vue2中的mixin 其优势,复用代码,让setup中的逻辑更清楚易懂 Demo hook函数文件:通常在src文件下新建一个hooks文件夹存放不同的hook函数,名称随便起,但是,一般来说,可能会使用use开头命名的文件 // src/hooks/usePageXY.js import {

  • 参考链接:https://www.cnblogs.com/hellcat/p/8512090.html 由于pytorch会自动舍弃图计算的中间结果,所以想要获取这些数值就需要使用hook函数。hook函数包括tensor的hook和nn.Module的hook,用法相似。hook函数在使用后应及时删除,以避免每次都运行钩子增加运行负载。hook函数主要用在获取某些中间结果的情景,如中间某一层的输

  • 当我们提交代码提示husky > pre-commit hook failed (add --no-verify to bypass)时,是由于pre-commit(客户端)它会在Git键入提交信息前运行做代码风格检查。如果代码不符合相应规则,则报错。导致无法提交,解决方案如下: 1.进入项目文件夹⁨/.git⁩/hooks⁩文件夹下 2.删除pre-commit文件

  • 为什么会有Hooks? 介绍Hooks之前,首先要给大家说一下React的组件创建方式,一种是类组件,一种是纯函数组件,并且React团队希望,组件不要变成复杂的容器,最好只是数据流的管道。开发者根据需要,组合管道即可。也就是说组件的最佳写法应该是函数,而不是类。。 但是我们知道,在以往开发中类组件和纯函数组件的区别是很大的,纯函数组件有着类组件不具备的多种特点,简单列举几条 纯函数组件没有状态

 相关资料
  • Microsoft Windows Apache的使用 此文阐述如何在Windows平台上安装、配置和运行Apache2.0 参见:在Microsoft Windows上使用Apache 编译Apache 此文会指出在Windows平台上编译Apache以前必须了解的许多要点。 参见:在Microsoft Windows平台上编译Apache 其他平台 Novell NetWare 此文阐述如何在

  • 从包管理安装 通过 Homebrew,OpenResty 提供了 OSX 上的 官方包。 你只需运行下面的命令: brew install openresty/brew/openresty 如果你之前是从 homebrew/nginx 安装的 OpenResty,请先执行: brew untap homebrew/nginx 如果一切顺利,OpenResty 应该已经安装好了。 接下来,我们就可以

  • 本文将介绍了如何设置 SDK 环境来部署 Cordova 应用到 Android 设备上,以及在你的开发流程中如何选择使用 Android 命令行工具。不管你是以平台为中心的工作流程还是跨平台(命令行界面)的工作流程都需要安装 Android SDK。 需求及支持 Cordova 开发 Android 需要 Android SDK,可以安装在 OS X, Linux 或 Windows 操作系统。

  • 本指南将向你展示怎样在OS X电脑上搭建SDK开发环境部署Cordova应用。更多详细的平台相关的信息如下: OS X 配置 OS X 插件 上面提到的命令行工具适用于Cordova 3.0之前的版本。当前的版本请查看创建你的第一个App来获取更多信息。 需求和支持 要构建OS X应用需要使用苹果提供的工具,这些工具只能运行在安装了OS X操作系统的基于Intel的Mac设备上。Xcode 6.0

  • 工具准备 Android Studio v3.0+, 下载参见:Google 中国开发者网站 cocos2d-x v3.17,下载后解压,下载参见:Cocos 官网页面 配置步骤: 完成 Android Studio 安装,进入欢迎界面,选择 Import project(Gradle, Eclipse ADT, etc.)。选择目录 cocos2d-x root/tests/cpp-tests/

  • 这个指南展示如何安装SDK环境以便可以部署Cordova App在Android设备上,以及如何选择使用以Android为中心命令行工具在你的开发工作流中。 不管你是使用以平台为中心的shell工具还是跨平台的Cordova命令行你都需要安装Android SDK。要比较两种开发路径,请参见概述。要获取CLI的详细介绍请参见Cordova CLI 参考. 要求和支持情况 Cordova支持Andr