编译环境: ubuntu 16.04.7 + nexus 6P
1. 首先编译aosp,并能成功刷机。
2. 配置frida-gadget到编译成功的源码路径下
去github下载两个版本的frida-gadget.so
下载完成后解压,并改名。注意文件名必须以lib开头。
mv frida-gadget-15.1.16-android-arm.so libfg15116arm.so
mv frida-gadget-15.1.16-android-arm64.so libfg15116arm64.so
然后分别push到编译好的aosp对应目录
mv libfg15116arm.so out/target/product/angler/system/lib/
mv libfg15116arm64.so out/target/product/angler/system/lib64/
接下来创建frida gadget库的配置文件。配置文件名前半部分需要和gadget库的文件名相同
touch out/target/product/angler/system/lib/libfg15116arm.config.so
touch out/target/product/angler/system/lib/libfg15116arm64.config.so
分别在其中写入如下内容
{
"interaction": {
"type": "script",
"path": "/data/local/tmp/hook.js"
}
}
3. 修改源代码,在fork子进程的时候注入frida-gadget
找到源代码frameworks/base/core/jni/com_android_internal_os_Zygote.cpp 可以看到在这里fork的子进程。 在 pid==0的判断条件下,末尾增加以下代码
/*
* 在虚拟机,系统框架初始化完成之后,加载frida框架
* 需要增加头文件的引用 #include <dlfcn.h>
*/
#if defined(__aarch64__) || defined(__arm__)
{
#if defined(__aarch64__)
#define FRIDA_LIB "/system/lib64/libfg15116arm64.so"
#else
#define FRIDA_LIB "/system/lib/libfg15116arm.so"
#endif
const char *name = env->GetStringUTFChars(java_se_name, 0);
void* frida = dlopen(FRIDA_LIB, RTLD_NOW);
if(NULL == frida) {
ALOGE("(%s) load frida-gadget(%s) failed, err= %d\n", name, FRIDA_LIB, errno);
} else {
ALOGI("(%s) load frida-gadget(%s) success\n", name, FRIDA_LIB);
}
env->ReleaseStringUTFChars(java_se_name, name);
}
#endif
4. 编译并重新生成系统镜像
cd frameworks/base
mmm
make snod
5. 刷机后效果
6. 测试效果,load上一篇文章中的so
编写hook脚本
function copyFileByLibc(i_file, o_file){
const addr_fopen = Module.findExportByName('libc.so', 'fopen');
const addr_fread = Module.findExportByName('libc.so', 'fread');
const addr_fclose = Module.findExportByName('libc.so', 'fclose');
const addr_fwrite = Module.findExportByName('libc.so', 'fwrite');
const fopen = new NativeFunction(addr_fopen, 'pointer', ['pointer', 'pointer']);
const fclose = new NativeFunction(addr_fclose, 'int', ['pointer']);
const fread = new NativeFunction(addr_fread, 'int', ['pointer', 'int', 'int', 'pointer']);
const fwrite = new NativeFunction(addr_fwrite, 'int', ['pointer', 'int', 'int', 'pointer']);
const in_filename = Memory.allocUtf8String(i_file);
const in_mode = Memory.allocUtf8String("rb");
const in_file = fopen(in_filename, in_mode);
const out_filename = Memory.allocUtf8String(o_file);
const out_mode = Memory.allocUtf8String("wb");
const out_file = fopen(out_filename, out_mode);
const read_size = 1024
const buffer = Memory.alloc(read_size);
while (true){
const len = fread(buffer, 1, read_size, in_file);
if(len === 0){
break
}
fwrite(buffer, 1, len, out_file);
}
fclose(in_file);
fclose(out_file);
}
function main(){
if(Java.available){
Java.perform(function (){
var System = Java.use("java.lang.System");
var clz = Java.use("com.h0p1.xposeddemo.MainActivity");
clz.testOne.implementation = function (){
var currentApplication = Java.use('android.app.ActivityThread').currentApplication();
var context = currentApplication.getApplicationContext();
var libs = context.getDir("tt", 0x0000);
var target_so = libs.getAbsolutePath() + "/libhookso.so";
copyFileByLibc("/data/local/tmp/libhookso.so", target_so);
System.load(target_so);
}
})
}
}
setTimeout(main, 500)
把脚本推到手机上
adb push code.js /data/local/tmp/hook.js
重新打开app,效果如下:
参考文章:
1.ubuntu 20.04系统AOSP(Android 11)集成Frida
|