39.安卓逆向2-frida hook技术-过firda检测(四)(魔改Frida)

发布于:2025-07-31 ⋅ 阅读:(18) ⋅ 点赞:(0)

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!

内容参考于:图灵Python学院

工具下载:

链接:https://pan.baidu.com/s/1bb8NhJc9eTuLzQr39lF55Q?pwd=zy89

提取码:zy89

复制这段内容后打开百度网盘手机App,操作更方便哦

上一个内容:38.安卓逆向2-frida hook技术-过firda检测(三)(通过SO文件过检测原理)

魔改frida也要去找版本,之前用的firdaServer是14.2.18版本,但是魔改frida没有14.2.18这个版本,所以这里下载的是15.2.2版本,经过测试它是没问题的

然后电脑上的frida版本,如果安装过程中,出现问题,把错误信息给ai,ai会教你如何解决

Python用3.10版本(使用Conda安装):

conda create -n python310Frida1522 python=3.10

再执行

conda activate python310Frida1522

frida用15.2.2版本,先执行:

pip install frida==15.2.2 --index-url https://pypi.org/simple/

frida-tools用10.0.0版本,执行完上方的指令,再执行:

pip install frida-tools==10.0.0 -i https://pypi.tuna.tsinghua.edu.cn/simple/

安装完后使用 pip list指令验证:

魔改frida下载地址

https://github.com/hzzheyang/strongR-frida-android/releases?page=10

手机是arm64架构的下载下图红框的

下载完进行解压

解压完就能得到一个可执行文件,然后使用adb把它放到手机里

然后它改个名字,方便在手机里使用

然后使用adb push 上传到手机 adb push D:\f1522 /data/local/tmp

然后来到手机里看看上传成功没有,如下图上传成功

然后直接运行如下图,它会出错,需要给它一个权限

给f1522所有权限 chmod 777 ./f1522,如下图就可以运行了

然后运行过非魔改frida的还需要删除点东西,否则还是有frida特征,如下图红框,frida-server-14.2.18-android-arm64是fridaServer的运行文件,然后 re.frida.server 是fridaServer运行后创建的文件,需要把它们进行删除

删除指令

rm frida-server-14.2.18-android-arm64

rm -r re.frida.server/

删除完运行魔改Frida,魔改frida的端口没有改,如下图可以看到Maps记录检查就过了,之前是过不了的

魔改frida运行后,如下图,原本re.frida.server文件夹就变成了下图红框的内容

然后它的so文件也一样,这样就找不到frida的特征了

然后运行之前的打印模块的frida脚本

function 导出模块(){
    var module = Process.enumerateModules();
    for(var i = 0; i < module.length; i++){
        console.log(module[i].name);// 模块名
    }
}
// setImmediate异步执行代码
setImmediate(导出模块);

如下图它肯定是frdiaServer64了

搭配上一个内容中的脚本使用

function mapsRedirect() {
    // 定义伪造的maps文件路径
    var FakeMaps = "/data/data/com.yimian.envcheck/maps";
    // 获取libc.so库中'open'函数的地址
    const openPtr = Module.getExportByName('libc.so', 'open');
    // 根据地址创建一个新的NativeFunction对象,表示原生的'open'函数
    const open = new NativeFunction(openPtr, 'int', ['pointer', 'int']);
    // 查找并获取libc.so库中'read'函数的地址
    var readPtr = Module.findExportByName("libc.so", "read");
    // 创建新的NativeFunction对象表示原生的'read'函数
    var read = new NativeFunction(readPtr, 'int', ['int', 'pointer', "int"]);
    // 分配512字节的内存空间,用于临时存储从maps文件读取的内容
    var MapsBuffer = Memory.alloc(512);
    // 创建一个伪造的maps文件,用于写入修改后的内容,模式为"w"(写入)
    var MapsFile = new File(FakeMaps, "w");
    // 使用Interceptor替换原有的'open'函数,注入自定义逻辑
    Interceptor.replace(openPtr, new NativeCallback(function(pathname, flag) {
        // 调用原始的'open'函数,并获取文件描述符(FD)
        var FD = open(pathname, flag);
        // 读取并打印尝试打开的文件路径
        var ch = pathname.readCString();
        if (ch.indexOf("/proc/") >= 0 && ch.indexOf("maps") >= 0) {
            console.log("open : ", pathname.readCString());
            // 循环读取maps内容,并写入伪造的maps文件中,同时进行字符串替换以隐藏特定信息
            while (parseInt(read(FD, MapsBuffer, 512)) !== 0) {
                var MBuffer = MapsBuffer.readCString();
                MBuffer = MBuffer.replaceAll("/data/local/tmp/re.frida.server/frida-agent-64.so", "FakingMaps");
                MBuffer = MBuffer.replaceAll("re.frida.server", "FakingMaps");
                MBuffer = MBuffer.replaceAll("frida-agent-64.so", "FakingMaps");
                MBuffer = MBuffer.replaceAll("frida-agent-32.so", "FakingMaps");
                MBuffer = MBuffer.replaceAll("frida", "FakingMaps");
                MBuffer = MBuffer.replaceAll("/data/local/tmp", "/data");
                // 将修改后的内容写入伪造的maps文件
                MapsFile.write(MBuffer);
            }
            // 为返回伪造maps文件的打开操作,分配UTF8编码的文件名字符串
            var filename = Memory.allocUtf8String(FakeMaps);
            // 返回打开伪造maps文件的文件描述符
            return open(filename, flag);
        }
        // 如果不是目标maps文件,则直接返回原open调用的结果
        return FD;
    }, 'int', ['pointer', 'int']));
}
 
function replace_str() {
    var pt_strstr = Module.findExportByName("libc.so", 'strstr');
    var pt_strcmp = Module.findExportByName("libc.so", 'strcmp');
    Interceptor.attach(pt_strstr, {
        onEnter: function (args) {
            var str1 = args[0].readCString();
            var str2 = args[1].readCString();
            if (str2.indexOf("SigBlk") !== -1 ||
                str2.indexOf("tmp") !== -1 ||
                str2.indexOf("frida") !== -1 ||
                str2.indexOf("gum-js-loop") !== -1 ||
                str2.indexOf("gmain") !== -1 ||
                str2.indexOf("gdbus") !== -1 ||
                str2.indexOf("pool-frida") !== -1||
                str2.indexOf("linjector") !== -1) {
                // console.log("strcmp-->", str1, str2);
                this.hook = true;
            }
        }, onLeave: function (retval) {
            if (this.hook) {
                retval.replace(0x0);
            }
        }
    });
 
    Interceptor.attach(pt_strcmp, {
        onEnter: function (args) {
            var str1 = args[0].readCString();
            var str2 = args[1].readCString();
            if (str2.indexOf("tmp") !== -1 ||
                str2.indexOf("frida") !== -1 ||
                str2.indexOf("gum-js-loop") !== -1 ||
                str2.indexOf("gmain") !== -1 ||
                str2.indexOf("gdbus") !== -1 ||
                str2.indexOf("pool-frida") !== -1||
                str2.indexOf("linjector") !== -1) {
                // console.log("strcmp-->", str1, str2);
                this.hook = true;
            }
        }, onLeave: function (retval) {
            if (this.hook) {
                retval.replace(0x0);
            }
        }
    })
 
}
function m(){
    mapsRedirect()
    replace_str()
}
setImmediate(m)

注入之后,还是会有被检测的点

下一节将使用技术手段对抗检测,不使用魔改frida


img


网站公告

今日签到

点亮在社区的每一天
去签到