Dobby 框架(https://github.com/jmpews/Dobby)是一个全平台的 inline Hook框架,这里记录一下此框架如何在Android 平台上使用
1. 下载与安装
参考项目介绍,直接 clone 即可
git clone https://github.com/jmpews/Dobby.git --depth=1
2. 代码与配置文件
由于项目使用的 cmake,而不是我们熟悉的 NDK 配置文件Android.mk,想要直接编译出可执行文件,还是要学习一下 CmakeList.txt 的语法规则。
- 首先给出测试代码:
#include <stdio.h>
#include <dlfcn.h>
// 直接引用上层目录的头文件即可使用 Hook 库
#include "../include/dobby.h"
void* oldfunc;
int myputs(char* str){
printf("hook :%s\n",str);
int i=1;
for(;*(str+i)!=0;i++){}
return i;
}
int main(int argc, char *argv[])
{
puts("puts1\n");
DobbyHook((void*)&puts,(void*)myputs,(void **)&oldfunc);
puts("puts2\n");
return 0;
}
- CMakeLists.txt 配置文件,官方的demo是Mac平台,并且未说明怎么编译成 Android 平台,需要进行一定的修改,连猜带查的,终于把正确的配置文件搞定了,具体需要注意的地方可以看看注释
cmake_minimum_required(VERSION 3.5)
project(DobbyExampleAndroid)
set(DOBBY_SOURCE_DIR ..)
# 指定静态链接,否则默认动态链接
set(GENERATE_SHARED OFF)
add_subdirectory(${DOBBY_SOURCE_DIR} dobby.out)
include_directories(${DOBBY_SOURCE_DIR}/example_android)
add_executable(DobbyExampleAndroid
./main.c
)
# 一定要放到 add_executable 后面,否则会出错
target_link_libraries(${PROJECT_NAME}
dobby
)
- 目录如下,有以下2个文件就够了
tree example_android
example_android
├── CMakeLists.txt
└── main.c
3. 编译运行
- 当前目录下,通过 cmake 命令生成 MakeFile 文件
DCMAKE_TOOLCHAIN_FILE 里的NDK路径需要自行替换
DANDROID_ABI cpu类型,我选了64位
DANDROID_NATIVE_API_LEVEL API级别,不多说
cmake . \
-DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake \
-DCMAKE_BUILD_TYPE=Release \
-DANDROID_ABI="arm64-v8a" \
-DANDROID_STL=c++_static \
-DANDROID_NATIVE_API_LEVEL=android-21 \
-DSHARED=ON
-
make 命令编译,最后可以看到进行静态链接并生成可执行文件,就算成了
-
测试运行一下
参考文章:
部分命令与代码参考此文章,并做了一定修改:
https://blog.csdn.net/weixin_34044273/article/details/93088760
[更新] 4. 在 Android Studio 中的配置:
-
把整个 Dobby 项目放在 jni 目录下,我的测试目录如下:
代码中引用 Dobby 库,如下:
#include "HookMain.h"
#include "Dobby/include/dobby.h"
extern "C" {
void HookMain() __attribute__((constructor));
JNIEXPORT void JNICALL
Java_com_your_jni_function_name(JNIEnv *env, jclass clazz) {
__android_log_print(ANDROID_LOG_DEBUG, "Tag", "Print");
}
void (*old_print)(JNIEnv *env, jclass clazz);
JNIEXPORT void JNICALL new_print(JNIEnv *env, jclass clazz) {
__android_log_print(ANDROID_LOG_DEBUG, "Tag", "Hooked");
old_print(env, clazz);
}
void HookMain() {
// Write hook functions here
DobbyHook((void *)&Java_com_your_jni_function_name, (void *)new_print, (void **)&old_print);
}
}
- CmakeLists.txt 文件如下,添加Doobby库即可
cmake_minimum_required(VERSION 3.5)
# 这里指定静态链接,生成一个so;默认为 ON,生成两个so
set(GENERATE_SHARED OFF)
# 指定 dobby 库目录
set(DOBBY_SOURCE_DIR Dobby)
add_subdirectory(${DOBBY_SOURCE_DIR} dobby.out)
add_library( # Sets the name of the library.
hook-main
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
HookMain.cpp)
find_library( # Sets the name of the path variable.
log-lib
log)
target_link_libraries( # Specifies the target library.
hook-main
# 添加 dobby 库
dobby
# Links the target library to the log library
# included in the NDK.
${log-lib})
-
运行结果如下
[更新]
目前最新 20201224
版设置静态链接的方法:
修改 /Dobby/CMakeLists.txt 中的 DOBBY_GENERATE_SHARED
选项,将其设置为 OFF
,默认是动态链接:
......
# ===== Handle Option =====
option(DOBBY_GENERATE_SHARED "Build shared library" OFF)
......