主要用于在云机中为指定应用注入自己的代码,对java层或native进行修改。
自动注入dex
自动注入so
内置java层Hook框架LspLant
内置native层Hook框架Dobby
使用Android Studio打开该项目。编译后得到模块app-debug.apk
将该文件上传自云机中,例如/sdcard/Download/app-debug.apk路径下
通过下面的命令可进行安装和查看
//首先连接到云机
adb connect xx.xx.xx.xx
//进入云机终端
adb shell
//然后安装模块
dplus install patch:/sdcard/Download/app-debug.apk
//成功安装后可以查看模块
dplus dump
//可以通过模块name卸载删除模块
dplus uninstall dplus_demo
模块源码结构如下图
config.json文件用于配置模块
native-lib.cpp中实现dobby的hook例子
Entry.java是java层hook的入口
该文件主要用于描述模块,并且引导注入的,样例数据如下
{
"name": "dplus_demo", //模块名称,卸载时使用
"package":"com.example.dplus_demo", //模块的包名
"desc": "module", //模块的描述
"type": "user", //模块的类型,主要为system和user。
"libs": "libdplus_demo.so", //要注入的so,可以不配置或者通过';'配置多条
"pattern": [
"com.android.settings" //需要生效的包名
]
}
下面演示了如何简单的对openat函数进行hook输出
int (*source_openat)(int fd, const char *path, int oflag, int mode) = nullptr;
int MyOpenAt(int fd, const char *pathname, int flags, int mode) {
LOGI("MyOpenAt pathname %s",pathname);
return source_openat(fd, pathname, flags, mode);
}
void HookOpenAt() {
//查找函数地址
void *__openat =
DobbySymbolResolver("libc.so", "__openat");
if (__openat == nullptr) {
LOGI("__openat null ");
return;
}
LOGI("拿到 __openat 地址 ");
//通过dobby替换原函数
if (DobbyHook((void *) __openat,
(void *) MyOpenAt,
(void **) &source_openat) == 0) {
LOGI("DobbyHook __openat sucess");
}
}
jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
LOGI("Test JNI_OnLoad 开始加载");
HookOpenAt();
return JNI_VERSION_1_6;
}
init函数是作为应用启动完后的一个入口点,在这里执行相关逻辑即可。LspLant相关的代码进行了简单的修改,所以部分类和函数不是原名称。
public class Entry {
public String TAG="demo_Entry";
public void init(Application app){
DPLog.i(TAG,"enter init");
LSPHelpers.findAndHookMethod("java.util.HashMap", app.getClassLoader(), "put",Object.class,Object.class, new LSP_MethodH() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.i(TAG,"enter HashMap.put key:"+param.args[0]+",value:"+param.args[1]);
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Log.i(TAG,"leave HashMap.put");
}
});
}
}
该模块对应用Setting进行测试,关掉Setting应用重新打开时相关日志如下图