首页
论坛
课程
招聘
[原创]Frida持久化方案(Xcube)之方案三——基于Magisk和gadget
2021-8-13 14:27 7677

[原创]Frida持久化方案(Xcube)之方案三——基于Magisk和gadget

2021-8-13 14:27
7677

回顾

之前分享了两个方案,各有各的问题。

  1. Frida持久化方案(Xcube)之方案一——基于Magisk和Riru能用但是不够灵活:脚本修改不能时时生效,必须重启目标app;日志只能输出到logcat,无法重定向到pc端;
  2. Frida持久化方案(Xcube)之方案二——基于xposed容易被检测xposed

新的思路

  • 注意到frida还有gadget这个小东西,有了把gadget直接通过magisk刷入/system/lib目录下的想法,这样app加载gadget.so就非常方便了,不仅如此,还没有之前两个方案存在的问题;

方案

编写一个magisk插件,集成gadget.so,在手机启动时copy到/system/lib目录下;在这个插件中集成riru,用于在目标app启动时加载gadget;

  • 复制gadget到/system/lib的关键代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
# customize.h
if [ "$ARCH" = "arm" ] || [ "$ARCH" = "arm64" ]; then
  ui_print "- Extracting arm libraries"
#  extract "$ZIPFILE" "lib/armeabi-v7a/libfrida-gadget-14.2.14.so" "$MODPATH/gadget/lib" true
#  extract "$ZIPFILE" "lib/armeabi-v7a/libfrida-gadget-14.2.14.config.so" "$MODPATH/gadget/lib" true
  extract "$ZIPFILE" "lib/armeabi-v7a/libfrida-gadget.so" "$MODPATH/gadget/lib" true
  if [ "$IS64BIT" = true ]; then
    ui_print "- Extracting arm64 libraries"
#    extract "$ZIPFILE" "lib/arm64-v8a/libfrida-gadget-14.2.14.so" "$MODPATH/gadget/lib64" true
#    extract "$ZIPFILE" "lib/arm64-v8a/libfrida-gadget-14.2.14.config.so" "$MODPATH/gadget/lib64" true
    extract "$ZIPFILE" "lib/arm64-v8a/libfrida-gadget.so" "$MODPATH/gadget/lib64" true
  fi
fi
1
2
3
# post-fs-data.sh
cp -f $MODDIR/gadget/lib/* $MODDIR/system/lib/
cp -f $MODDIR/gadget/lib64/* $MODDIR/system/lib64/
  • 目标进程拉起gadget.so的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
void loadGadget(JNIEnv *env){
    LOGD("Load frida-gadget");
    jclass system = env->FindClass("java/lang/System");
    jmethodID loadLibrary = env->GetStaticMethodID(system,"loadLibrary","(Ljava/lang/String;)V");
    jstring libraryName = env->NewStringUTF("frida-gadget");
    env ->CallStaticVoidMethod(system,loadLibrary,libraryName);
    env->DeleteLocalRef(system);
    env->DeleteLocalRef(libraryName);
}
 
void loadGadget2(JNIEnv *env){
    LOGD("Load frida-gadget2");
 
    #if defined(__arm__)
    #define FRIDA_LIB "/system/lib/libfrida-gadget-15.0.2.so"
    #elif defined(__aarch64__)
    #define FRIDA_LIB "/system/lib64/libfrida-gadget.so"
    #endif
    void* frida = dlopen(FRIDA_LIB, RTLD_NOW);
    const char *name = env->GetStringUTFChars(*_niceName, 0);
    if(NULL == frida) {
        LOGE("(%s) load frida-gadget(%s) failed\n", name, FRIDA_LIB);
    } else {
        LOGD("(%s) load frida-gadget(%s) success\n", name, FRIDA_LIB);
    }
    env->ReleaseStringUTFChars(*_niceName, name);
}
 
static void forkAndSpecializePost(JNIEnv *env, jclass clazz, jint res) {
    if (res == 0) {
        // In app process
        if (targetPackage(env)) {
            loadGadget(env);
        }
    } else {
        // In zygote process
    }
}

实测两种加载gadget.so的方法均可以

新方案需要解决的问题

  • 根据gadget的官方文档,gadget需要一个gadget.so.config的配置文件,它需要在gadget.so的相同目录下。很明显如果我们把gadget.so放到/system/lib下,那么它就不能随时修改了。所以这里我们就要修改frida源码将配置文件修改到其他位置。
  • 不仅要把gadget.so放到/system/lib下,还需要在app启动时加载它。gadget.so在被加载的时候会启动服务并开启一个端口监听,所有app都加载它显然会引起冲突;
  • 实测15.0.8的版本,gadget有bug,连不上;

问题逐个解决

  • 修改frida源码,指定配置文件目录为/data/local/tmp/gadget.config,编译一个新的gadget.so出来;
  • 使用adb命令设置目标app。setprop frida.target packagename;这样此目标app在启动的时候判断一下frida.target属性,是目标APP的情况下拉起gadget;
  • 只要把pc端的frida推到14.2.18即可,gadget可以用最新版代码编译;

插件下载链接

链接: https://pan.baidu.com/s/1y99yyVZqQqi01Uo7eFEQBQ 密码: ht6r
--来自百度网盘超级会员V5的分享

安装使用

  1. 在migisk中安装riru_25.x版本,然后安装网盘中的插件
  2. 下载附件中的gadget.json执行adb push gadget.json /data/local/tmp
  3. 执行adb shell su -c "setprop frida.target packagename"
  4. 启动目标app
  5. 执行frida -H phoneIP:27004 -l ./myscript.js Gadget,其中phoneIP是手机ip,端口27004在gadget.json指定,可修改;myscript.js是自定义的js脚本,Gadget固定值;frida使用14.2.14版本,实测15.0.8之前的都不能用,不知道frida后面有没有修复;

其他

  • 目前listen模式中,on_load仅支持resume,wait模式还有些问题,我自己判断是由于riru加载gadget.so的时机过于的早了;也就是暂时无法提供类似-f那样的功能,只能用script模式暂代,后面再想办法;
  • 14.2.14中script-directory和script模式应该都可以使用,我测过script模式,script-directory没有测试;这两种模式我一般用在应用刚启动的时候的一些hook。
  • 官方文档里还有一种connect模式,但是编译14.2.14的时候没发现它的代码,所以这个版本应当是后加的现在不支持;

[培训] 优秀毕业生寄语:恭喜id咸鱼炒白菜拿到远超3W月薪的offer,《安卓高级研修班》火热招生!!!

最后于 2021-8-16 10:50 被svengong编辑 ,原因: 没写完
收藏
点赞0
打赏
分享
最新回复 (18)
雪    币: 8381
活跃值: 活跃值 (1250)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tDasm 活跃值 2021-8-13 14:45
2
0
修改gadget.so文件,指定gadget.so.config路径
雪    币: 8381
活跃值: 活跃值 (1250)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tDasm 活跃值 2021-8-13 15:48
3
0
楼主测试一下,你这个方案能过梆梆加固企业版?
雪    币: 213
活跃值: 活跃值 (691)
能力值: ( LV3,RANK:27 )
在线值:
发帖
回帖
粉丝
svengong 活跃值 2021-8-13 16:09
4
0
tDasm 楼主测试一下,你这个方案能过梆梆加固企业版?
纯属爱好,没有专门测他家
雪    币: 611
活跃值: 活跃值 (575)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
mb_foyotena 活跃值 2021-8-13 19:13
5
0
tDasm 楼主测试一下,你这个方案能过梆梆加固企业版?
发样本
雪    币: 493
活跃值: 活跃值 (511)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
奋斗der小鸟 活跃值 2021-8-16 09:49
6
0
1、如果不在riru模块中对进程名进行修复的话,script-directory 模式中的配置文件是无法生效的,也就是文档中的 twitter.config 。
2、en......我记得好像14.2.14 有bug,好像函数参数为字符串数组的时候,构建存在bug
3、有些Android 10 以上的系统还要处理 specializeAppProcessPre 这个函数
雪    币: 213
活跃值: 活跃值 (691)
能力值: ( LV3,RANK:27 )
在线值:
发帖
回帖
粉丝
svengong 活跃值 2021-8-16 10:47
7
0
奋斗der小鸟 1、如果不在riru模块中对进程名进行修复的话,script-directory 模式中的配置文件是无法生效的,也就是文档中的 twitter.config 。 2、en......我记得好像14. ...
1.我去看一下,
2.我记错了,后来看代码,编译的是14.2.18;gadget‘我用15+版本编译也是能用的,只是pc端用15+连不上,包括最新的
3.我手头没有需要处理specializeAppProcessPre这个函数的手机,毕竟我只有一部小米10pro
雪    币: 213
活跃值: 活跃值 (691)
能力值: ( LV3,RANK:27 )
在线值:
发帖
回帖
粉丝
svengong 活跃值 2021-8-16 14:41
8
0
奋斗der小鸟 1、如果不在riru模块中对进程名进行修复的话,script-directory 模式中的配置文件是无法生效的,也就是文档中的 twitter.config 。 2、en......我记得好像14. ...

看了一下源码,这里涉及进程名字的就是current_process_matches吧;frida在使用的时候进程名的确被写死为Gadget了,所以有点搞不清你说的为什么要修复进程名,能解释一下么

雪    币: 192
活跃值: 活跃值 (61)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
batstying 活跃值 2021-8-16 21:03
9
0

我之前是这么做的,编写一个riru插件:

#include <jni.h>
#include <sys/types.h>
#include <riru.h>
#include <malloc.h>
#include <cstring>
#include <config.h>

#include <unistd.h>
#include <pthread.h>
#include <android/log.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <dlfcn.h>
//#include <stdio.h>
#define LOGTAG "test_fridahook"
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOGTAG , __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , LOGTAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO , LOGTAG, __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN , LOGTAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , LOGTAG, __VA_ARGS__)
#if defined(__arm__)
//#include "includes/armeabi-v7a/frida-gumjs.h"
#elif defined(__aarch64__)
//#include "includes/arm64-v8a/frida-gumjs.h"
#endif

int mysystem(char *cmdstring, char *buf, int len);

static int enable_hack;
static jstring *_appDataDir;

static char package_name[256];
const char *sopath = "/data/local/tmp/libfg1502.so";

// 仅在测试app生效
int rirutest(JNIEnv *env, jstring appDataDir) {

    if (!appDataDir) {
        LOGD("forkAndSpecializePre appDataDir null");
        return 0;
    }
    const char *app_data_dir = env->GetStringUTFChars(appDataDir, NULL);
    int user = 0;

    if (sscanf(app_data_dir, "/data/%*[^/]/%d/%s", &user, package_name) != 2) {
        if (sscanf(app_data_dir, "/data/%*[^/]/%s", package_name) != 1) {
            package_name[0] = '\0';
            LOGW("can't parse %s", app_data_dir);
            env->ReleaseStringUTFChars(appDataDir, app_data_dir);
            return 0;
        }
    }
    env->ReleaseStringUTFChars(appDataDir, app_data_dir);
//    LOGD("package [ %s ] starting...", package_name);

    char cmd_string[1024];
    const char *filepath = "/data/local/tmp/pkg.conf";
    sprintf(cmd_string, "cat %s", filepath);
    int bufsize = 1024 * 10;
    char buf[bufsize];
    mysystem(cmd_string, buf, bufsize);

    int ret = 0;
    char *item = NULL;
    char *delims = "\r\n";
    item = strtok(buf, delims);

    while (item != NULL) {
//        LOGD("package item: %s", item);
        if (strcmp(item, package_name) == 0) {
            ret = 1;
            LOGD("package item: %s", item);
            break;
        } else {
            ret = 0;
        }
        item = strtok(NULL, delims);
    }
    return ret;
}

// 用readjs方法中的方式比较简单,但是由于尝试在zygote进程中读取文件,才试到这里的方法
// 这个方法作为一个通用方法就不改回去了
int mysystem(char *cmdstring, char *buf, int len) {
    int fd[2];
    pid_t pid;
    int n, count;
    memset(buf, 0, len);
    if (pipe(fd) < 0)
        return -1;
    if ((pid = fork()) < 0){
        LOGE("fork faild");
        return -1;
    }
    else if (pid > 0) {
        close(fd[1]);
        count = 0;
        while ((n = read(fd[0], buf + count, len)) > 0 && count > len)
            count += n;
        close(fd[0]);
        if (waitpid(pid, NULL, 0) > 0)
            return -1;
    } else {
        close(fd[0]);
        if (fd[1] != STDOUT_FILENO) {
            if (dup2(fd[1], STDOUT_FILENO) != STDOUT_FILENO) {
                return -1;
            }
            close(fd[1]);
        }
        if (execl("/system/bin/sh", "sh", "-c", cmdstring, (char *) 0) == -1){
            LOGE("execl (%s) faild", cmdstring);
            return -1;
        }

    }
    return 0;
}


static void forkAndSpecializePre(
        JNIEnv *env, jclass clazz, jint *uid, jint *gid, jintArray *gids, jint *runtimeFlags,
        jobjectArray *rlimits, jint *mountExternal, jstring *seInfo, jstring *niceName,
        jintArray *fdsToClose, jintArray *fdsToIgnore, jboolean *is_child_zygote,
        jstring *instructionSet, jstring *appDataDir, jboolean *isTopApp, jobjectArray *pkgDataInfoList,
        jobjectArray *whitelistedDataInfoList, jboolean *bindMountAppDataDirs, jboolean *bindMountAppStorageDirs) {
    // Called "before" com_android_internal_os_Zygote_nativeForkAndSpecialize in frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
    // Parameters are pointers, you can change the value of them if you want
    // Some parameters are not exist is older Android versions, in this case, they are null or 0
    _appDataDir = appDataDir;
}

static void forkAndSpecializePost(JNIEnv *env, jclass clazz, jint res) {
    // Called "after" com_android_internal_os_Zygote_nativeForkAndSpecialize in frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
    // "res" is the return value of com_android_internal_os_Zygote_nativeForkAndSpecialize

    if (res == 0) {
        // In app process
        enable_hack = rirutest(env, *_appDataDir);
        if (enable_hack) {
            char cmd_string[1024];
            const char *filepath = "/data/local/tmp/";
            sprintf(cmd_string, "%s%s/libtest.so", filepath, package_name);

            LOGE("Start Load Library");
            void* handle = dlopen( cmd_string, RTLD_LAZY );

            if( handle != 0) {
                LOGE("Load %s success!", cmd_string);
            }
            else {
                LOGE("Load %s failed! dlopen failed: %s\n", cmd_string, dlerror());
            }

        }
        // When unload allowed is true, the module will be unloaded (dlclose) by Riru
        // If this modules has hooks installed, DONOT set it to true, or there will be SIGSEGV
        // This value will be automatically reset to false before the "pre" function is called
        riru_set_unload_allowed(true);
    } else {
        // In zygote process
    }
}

static void specializeAppProcessPre(
        JNIEnv *env, jclass clazz, jint *uid, jint *gid, jintArray *gids, jint *runtimeFlags,
        jobjectArray *rlimits, jint *mountExternal, jstring *seInfo, jstring *niceName,
        jboolean *startChildZygote, jstring *instructionSet, jstring *appDataDir,
        jboolean *isTopApp, jobjectArray *pkgDataInfoList, jobjectArray *whitelistedDataInfoList,
        jboolean *bindMountAppDataDirs, jboolean *bindMountAppStorageDirs) {
    // Called "before" com_android_internal_os_Zygote_nativeSpecializeAppProcess in frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
    // Parameters are pointers, you can change the value of them if you want
    // Some parameters are not exist is older Android versions, in this case, they are null or 0
}

static void specializeAppProcessPost(
        JNIEnv *env, jclass clazz) {
    // Called "after" com_android_internal_os_Zygote_nativeSpecializeAppProcess in frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

    // When unload allowed is true, the module will be unloaded (dlclose) by Riru
    // If this modules has hooks installed, DONOT set it to true, or there will be SIGSEGV
    // This value will be automatically reset to false before the "pre" function is called
    riru_set_unload_allowed(true);
}

static void forkSystemServerPre(
        JNIEnv *env, jclass clazz, uid_t *uid, gid_t *gid, jintArray *gids, jint *runtimeFlags,
        jobjectArray *rlimits, jlong *permittedCapabilities, jlong *effectiveCapabilities) {
    // Called "before" com_android_internal_os_Zygote_forkSystemServer in frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
    // Parameters are pointers, you can change the value of them if you want
    // Some parameters are not exist is older Android versions, in this case, they are null or 0
}

static void forkSystemServerPost(JNIEnv *env, jclass clazz, jint res) {
    // Called "after" com_android_internal_os_Zygote_forkSystemServer in frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

    if (res == 0) {
        // In system server process
    } else {
        // In zygote process
    }
}

static void onModuleLoaded() {
    // Called when this library is loaded and "hidden" by Riru (see Riru's hide.cpp)

    // If you want to use threads, start them here rather than the constructors
    // __attribute__((constructor)) or constructors of static variables,
    // or the "hide" will cause SIGSEGV
}

extern "C" {

int riru_api_version;
const char *riru_magisk_module_path = nullptr;
int *riru_allow_unload = nullptr;

static auto module = RiruVersionedModuleInfo{
        .moduleApiVersion = riru::moduleApiVersion,
        .moduleInfo= RiruModuleInfo{
                .supportHide = true,
                .version = riru::moduleVersionCode,
                .versionName = riru::moduleVersionName,
                .onModuleLoaded = onModuleLoaded,
                .forkAndSpecializePre = forkAndSpecializePre,
                .forkAndSpecializePost = forkAndSpecializePost,
                .forkSystemServerPre = forkSystemServerPre,
                .forkSystemServerPost = forkSystemServerPost,
                .specializeAppProcessPre = specializeAppProcessPre,
                .specializeAppProcessPost = specializeAppProcessPost
        }
};

RiruVersionedModuleInfo *init(Riru *riru) {
    auto core_max_api_version = riru->riruApiVersion;
    riru_api_version = core_max_api_version <= riru::moduleApiVersion ? core_max_api_version : riru::moduleApiVersion;
    module.moduleApiVersion = riru_api_version;

    riru_magisk_module_path = strdup(riru->magiskModulePath);
    if (riru_api_version >= 25) {
        riru_allow_unload = riru->allowUnload;
    }
    return &module;
}
}


看gadget源码,加载conf的规则:

https://github.com/frida/frida-core/blob/0120cf59bc6f623bb842c93bc8870ce2a704453c/lib/gadget/gadget.vala

	private string derive_config_path_from_file_path (string path) {
		var dirname = Path.get_dirname (path);
		var filename = Path.get_basename (path);

		string stem;
		var ext_index = filename.last_index_of_char ('.');
		if (ext_index != -1)
			stem = filename[0:ext_index];
		else
			stem = filename;

		return Path.build_filename (dirname, stem + ".config");
	}

private Config load_config (Location location) throws Error {
		unowned string? gadget_path = location.path;
		if (gadget_path == null)
			return new Config ();

		var config_path = derive_config_path_from_file_path (gadget_path);

#if IOS
		if (!FileUtils.test (config_path, FileTest.EXISTS)) {
			var config_dir = Path.get_dirname (config_path);
			if (Path.get_basename (config_dir) == "Frameworks") {
				var app_dir = Path.get_dirname (config_dir);
				config_path = Path.build_filename (app_dir, Path.get_basename (config_path));
			}
		}
#endif

#if ANDROID
		if (!FileUtils.test (config_path, FileTest.EXISTS)) {
			var ext_index = config_path.last_index_of_char ('.');
			if (ext_index != -1) {
				config_path = config_path[0:ext_index] + ".config.so";
			} else {
				config_path = config_path + ".config.so";
			}
		}
#endif

简单的说,如果能找到当前so所在的路径下的xxx.config。如果找不到,又是安卓环境下,那么就就在/data/app/xxxx.xxx.xxx-xxxx(对应包名)/lib目录下,加载xxx.config.so(需要提前将config.so文件放到apk下,这就需要重打包了)。

所以可以直接将frida-gadget重命名为libtest.so 丢到目录(/data/local/tmp/xxxx.xxx.xxx-xxxx/),也就是需要注入的目标的包下,然后同级目录下放入:libtest.config,这个config名字必须与修改frida-gadget重命名libtest相同。

config中就可以指定加载的js了:

{
  "interaction": {
    "type": "script",
    "path": "/data/local/tmp/test.js"
  }
}


frida-gadget支持4种模式,默认是监听127.0.0.1:27012,会卡死app,所以这里采用的是script模式,指定加载的脚本路径。

也可以:

{
  "interaction": {
    "type": "listen",
    "address": "127.0.0.1",
    "port": 27042,
    "on_load": "wait"
  }
}

然后objection可以连接了:

objection -h 192.168.0.x -p 27042 explore

到这里就可以指定app加载frida-gadget,然后执行你的脚本,无需重打包。


综上,使用方法是:

1. 安装上面编译好的riru插件。

2. 在/data/local/tmp目录下,新建文件pkg.conf 一行写一个需要hook的apk包名。

3. 将frida-gadget下载下来重命名为libtest.so,对应的config为libtest.conf,丢到/data/local/tmp/xxxx.xxx.xxx-xxxx/。

4. 在配置文件中写入需要注入的js路径即可。


这样麻烦的一点就是每一个app都要到对应的包目录下放一个gadget...

最后于 2021-8-16 21:08 被batstying编辑 ,原因:
雪    币: 493
活跃值: 活跃值 (511)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
奋斗der小鸟 活跃值 2021-8-16 21:49
10
0
svengong 看了一下源码,这里涉及进程名字的就是current_process_matches吧;frida在使用的时候进程名的确被写死为Gadget了,所以有点搞不清你说的为什么要修复进程名,能解释一下么
是的,问题主要出在 script-directory 这种模式,这种模式有个配置文件,能够配置当前js脚本针对哪个进程生效。如果在 forkAndSpecializePost 里面加载 libgadget.so的话,libgadget.so 初始化的时候是读取不到当前app的进程名的
雪    币: 213
活跃值: 活跃值 (691)
能力值: ( LV3,RANK:27 )
在线值:
发帖
回帖
粉丝
svengong 活跃值 2021-8-17 12:15
11
0
batstying 我之前是这么做的,编写一个riru插件:#include&nbsp;&lt;jni.h&gt; #include&nbsp;&lt;sys/types.h&a ...
/data/app目录是可以的,只不过操作繁琐,所以我一开始就想着避免这种情况,才修改的gadget源码编译;你后面写的是/data/local/tmp目录,这个目录下的so是无法dlopen的,有权限限制;
雪    币: 213
活跃值: 活跃值 (691)
能力值: ( LV3,RANK:27 )
在线值:
发帖
回帖
粉丝
svengong 活跃值 2021-8-17 12:15
12
0
你这个代码我挺眼熟的
雪    币: 192
活跃值: 活跃值 (61)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
batstying 活跃值 2021-8-17 13:51
13
0
svengong 你这个代码我挺眼熟的[em_87]
是的,就是那你们的代码一顿copy的,啊哈哈
雪    币: 213
活跃值: 活跃值 (691)
能力值: ( LV3,RANK:27 )
在线值:
发帖
回帖
粉丝
svengong 活跃值 2021-8-17 14:52
14
0
奋斗der小鸟 是的,问题主要出在 script-directory 这种模式,这种模式有个配置文件,能够配置当前js脚本针对哪个进程生效。如果在 forkAndSpecializePost 里面加载 libgadg ...
用prctl修复可以么,我看修改进程名需要修改argv[0],但是riru里貌似无法获取这个地址
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_cykizhpu 活跃值 2021-8-24 16:20
15
0
附件 gadget.json在哪呀
雪    币: 493
活跃值: 活跃值 (511)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
奋斗der小鸟 活跃值 2021-9-1 10:45
16
0
svengong 用prctl修复可以么,我看修改进程名需要修改argv[0],但是riru里貌似无法获取这个地址
我的处理比较low,我直接进行了预先设置,这样 libgadget在加载xxx.js 的时候就能获取到当前进程名了  Process.setArgV0(parsedArgs.niceName);
雪    币: 2425
活跃值: 活跃值 (435)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
VNRKDOEA 活跃值 6天前
17
0
gadget.json 在哪
雪    币: 184
活跃值: 活跃值 (106)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
图样突森剖 活跃值 6天前
18
0
奋斗der小鸟 1、如果不在riru模块中对进程名进行修复的话,script-directory 模式中的配置文件是无法生效的,也就是文档中的 twitter.config 。 2、en......我记得好像14. ...
带佬,script-directory 配置文件同求。。我的问题是 js hook执行不了,配置文件也不生效

我把libfrida-gadget.so,libfrida-gadget64.so放到 /system/lib 和/system/lib64下,同时 这两个目录加上libfrida-gadget.config.so,libfrida-gadget64.so。 
这里app启动后,可以在内存空间中加载 so,同时配置文件也读取成功了。
配置文件格式如下:
{
  "interaction": {
    "type": "script-directory",
    "path": "/data/local/tmp",
    "on_change": "rescan"
  }
}
目的是去/data/local/tmp 目录下找js 以及 对于js脚本的配置文件。
我的 sslpining.js,以及sslpining.config。
sslpining.config如下
{
  "filter": {
    "executables": ["com.xxx.android"]
  }
}
奈何。。hook没生效。 就是不写sslpining.config 这个文件,也hook不了。。
雪    币: 493
活跃值: 活跃值 (511)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
奋斗der小鸟 活跃值 4天前
19
1
图样突森剖 带佬,script-directory 配置文件同求。。我的问题是 js hook执行不了,配置文件也不生效 我把libfrida-gadget.so,libfrida-gadget64.so放 ...
我自己写了个小工具,你可以看看是否自己修改一下,https://github.com/qiang/Riru-ModuleFridaGadget  目前这个工具仅仅在一加手机上部署过一定量
游客
登录 | 注册 方可回帖
返回