patch某哩frida检测

文章仅限于个人学习使用

样本

YmlsYmlsaSAgNy4zOS4w

工具=>ida frida(未去任何特征) so文件arm64-v8a

1.数据加密

bb76b8dc6b4d1d6e1c7759eadbd2b917.png

看看是哪个so文件有检测

function hook_dlopen1(soName = 'libmsaoaidsec.so') {
    Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"),
        {
            onEnter: function (args) {
                var pathptr = args[0];
                if (pathptr !== undefined && pathptr != null) {
                    var path = ptr(pathptr).readCString();
                    console.log(path)
                }
            }
        }
    );
}
/data/app/~~BSX3pQx54amgGap_bJlDRg==/tv.danmaku.bili-gpokD3YitZKGKPiflQDaDQ==/oat/arm64/base.odex
libframework-connectivity-jni.so
libforcedarkimpl.so
/data/app/~~BSX3pQx54amgGap_bJlDRg==/tv.danmaku.bili-gpokD3YitZKGKPiflQDaDQ==/lib/arm64/libblkv.so
/data/app/~~BSX3pQx54amgGap_bJlDRg==/tv.danmaku.bili-gpokD3YitZKGKPiflQDaDQ==/lib/arm64/libbili_core.so
/data/app/~~BSX3pQx54amgGap_bJlDRg==/tv.danmaku.bili-gpokD3YitZKGKPiflQDaDQ==/lib/arm64/libmsaoaidsec.so
Process terminated

在加载完成libmsaoaidsec.so后闪退

2.检测点

按照检测思路,一般会用pthread_create起线程

https://github.com/darvincisec/DetectFrida
function hook_pthread_createx() {
    var libcModule = Process.findModuleByName('libc.so');
    if (libcModule) {
        var pthread_create = new NativeFunction(
            libcModule.findExportByName('pthread_create'),
            'int', ['pointer', 'pointer', 'pointer', 'pointer']
        );
        Interceptor.attach(pthread_create, {
            onEnter: function (args) {
                var libmsaoaidsecModule = Process.findModuleByName('libmsaoaidsec.so');
                if (libmsaoaidsecModule) {
                    // 在进入 pthread_create 之前
                    console.log("pthread_create called with arguments:");
                    console.log("attr:", args[0]);
                    console.log("attr:", (args[0] - libmsaoaidsecModule.base).toString(16));
                    console.log("start_routine:", args[1]);
                    console.log("arg:", args[2]);
                    console.log("function at=>0x"+(args[2] - libmsaoaidsecModule.base).toString(16));
                    console.log("pid:", args[3]);
                    console.log('----------------------------------------\n')
                }
            },
            onLeave: function (retval) {
                // 在离开 pthread_create 之后
                console.log("pthread_create returned:", retval);
                if (retval.toInt32() === 0) {
                    console.log("Thread created successfully!");
                } else {
                    console.log("Thread creation failed!");
                }
            }
        });
    }
}

9283d18e3cf4f6aad7a3ba90dd2854d9.png

结果是在0x1aee4和0x1a574

3.nop检测点

0x1aee4

5d326201394eba0f28ab7ffc7a81621a.png

590c33a88805de23dc372ec0ccfb5692.png

0x1a574

56ac2f73cbc09eefd9804817a7282726.png

192ec2994b1c640c5f7cb395d6209002.png

两个函数往上翻找都会有个getpid

cd2400eb9e86a72b81a7ea9e75f0991b.png

然后可以用两种方式去patch地址

3-1.ida patch

直接nop掉0x1A858和0x1B8B4,apply patch后push到手机即可

6cb020a45e4b5cb3b1b7a11a880a9efd.png

3-2 frida patch

frida patch后效果如下

7b2d98452b0ebcdb17ddc5e39f7f3684.png

function hook_RegisterNatives() {
    var symbols = Module.enumerateSymbolsSync("libart.so");
    var addrRegisterNatives = null;
    for (var i = 0; i < symbols.length; i++) {
        var symbol = symbols[i];
        if (symbol.name.indexOf("art") >= 0 &&
            symbol.name.indexOf("JNI") >= 0 &&
            symbol.name.indexOf("RegisterNatives") >= 0 &&
            symbol.name.indexOf("CheckJNI") < 0) {
            addrRegisterNatives = symbol.address;
            console.log("RegisterNatives is at ", symbol.address, symbol.name);
            if (addrRegisterNatives != null) {
                Interceptor.attach(addrRegisterNatives, {
                    onEnter: function (args) {
                        var env = args[0];
                        var java_class = args[1];
                        var class_name = Java.vm.tryGetEnv().getClassName(java_class);
                        console.log("\n[RegisterNatives] method_count:", args[3]);
                        var methods_ptr = ptr(args[2]);
                        var method_count = parseInt(args[3]);
                        for (var i = 0; i < method_count; i++) {
                            var name_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3));
                            var sig_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize));
                            var fnPtr_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize * 2));
​
                            var name = Memory.readCString(name_ptr);
                            var sig = Memory.readCString(sig_ptr);
                            var find_module = Process.findModuleByAddress(fnPtr_ptr);
                            console.log("[RegisterNatives] java_class:", class_name, "name:", name, "sig:", sig, "fnPtr:", fnPtr_ptr, "module_name:", find_module.name, "module_base:", find_module.base, "offset:", ptr(fnPtr_ptr).sub(find_module.base));
                            // }
                        }
                    }
                });
            }
        }
    }
​
}
function print_arg(addr) {
    try {
        var module = Process.findRangeByAddress(addr);
        if (module != null) return "\n" + hexdump(addr) + "\n";
        return ptr(addr) + "\n";
    } catch (e) {
        return addr + "\n";
    }
}
​
​
function hook_native_addr() {
    var funcPtr = Module.findBaseAddress("libbili.so").add(0x8d14);
    var paramsNum = 0x3;
    var module = Process.findModuleByAddress(funcPtr);
    try {
        Interceptor.attach(funcPtr, {
            onEnter: function (args) {
                this.logs = "";
                this.params = [];
                // @ts-ignore
                this.logs = this.logs.concat("So: " + module.name + "  Method: sub_8D14 offset: " + ptr(funcPtr).sub(module.base) + "\n");
                for (let i = 0; i < paramsNum; i++) {
                    this.params.push(args[i]);
                    this.logs = this.logs.concat("this.args" + i + " onEnter: " + print_arg(args[i]));
                }
            }, onLeave: function (retval) {
                this.logs = this.logs.concat("retval onLeave: " + print_arg(retval) + "\n");
                console.log(this.logs);
            }
        });
    } catch (e) {
        console.log(e);
    }
}
function hook_dlopen1(soName = 'libmsaoaidsec.so') {
    // hook_RegisterNatives()
    Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"),
        {
            onEnter: function (args) {
                var pathptr = args[0];
                if (pathptr !== undefined && pathptr != null) {
                    var path = ptr(pathptr).readCString();
                    if (path.indexOf(soName) >= 0) {
                        // hook_pthread_createx()
                        hook_libc_getpid()
                    }
                }
            }
        }
    );
}
​
function enumerateLoadedModules() {
    // 使用 Process.enumerateModules() 方法来获取当前加载的所有模块(包括共享库)
    var modules = Process.enumerateModules();
​
    // 遍历所有模块并打印它们的信息
    for (var i = 0; i < modules.length; i++) {
        var module = modules[i];
        console.log('Module Name:', module.name);
        console.log('Base Address:', module.base);
        console.log('Size:', module.size);
    }
}
​
function hook_pthread_createx() {
    var libcModule = Process.findModuleByName('libc.so');
    if (libcModule) {
        var pthread_create = new NativeFunction(
            libcModule.findExportByName('pthread_create'),
            'int', ['pointer', 'pointer', 'pointer', 'pointer']
        );
        Interceptor.attach(pthread_create, {
            onEnter: function (args) {
                var libmsaoaidsecModule = Process.findModuleByName('libmsaoaidsec.so');
                if (libmsaoaidsecModule) {
                    // 在进入 pthread_create 之前
                    console.log("pthread_create called with arguments:");
                    console.log("attr:", args[0]);
                    console.log("attr:", (args[0] - libmsaoaidsecModule.base).toString(16));
                    console.log("start_routine:", args[1]);
                    console.log("arg:", args[2]);
                    console.log("function at=>0x"+(args[2] - libmsaoaidsecModule.base).toString(16));
                    console.log("pid:", args[3]);
                    console.log('----------------------------------------\n')
                }
            },
            onLeave: function (retval) {
                // 在离开 pthread_create 之后
                console.log("pthread_create returned:", retval);
                if (retval.toInt32() === 0) {
                    console.log("Thread created successfully!");
                } else {
                    console.log("Thread creation failed!");
                }
            }
        });
    }
}
function nop(targetModule, addr) {
    // 定义要 NOP 的函数地址和指令长度
    var targetFunctionAddress = targetModule.base.add(addr); // 0x1A858 是函数的偏移地址
    var instructionLength = 4; // 假设函数中的指令长度为 4 字节
​
    // 在目标函数地址写入 NOP 指令
    Memory.protect(targetFunctionAddress, instructionLength, 'rwx');
    for (var i = 0; i < instructionLength; i++) {
        Memory.writeU8(targetFunctionAddress.add(i), 0x90); // 0x90 是 NOP 指令
    }
    console.log('NOPed function at address 0x', (addr).toString(16));
}
function hook_libc_getpid() {
    // 寻找并 hook 目标库
    var f = false
    var libcModule = Process.findModuleByName('libc.so');
    if (libcModule) {
        var getpid = libcModule.findExportByName('getpid');
        Interceptor.attach(getpid, {
            onEnter: function (args) {
                var targetModule = Process.getModuleByName('libmsaoaidsec.so');
                if (targetModule && !f) {
                    nop(targetModule, 0x1A858)
                    nop(targetModule, 0x1B8B4)
                    f = true
                }
            },
            onLeave: function (retval) {
            }
        });
    }
}
​
​
setImmediate(hook_dlopen1, "libmsaoaidsec.so")

提示

ARMv7-A ARMv7-R:大多数指令仍然是4个字节长,但ARMv7-A引入了Thumb-2指令集,其中包括16位和32位指令。Thumb-2指令集的指令可以是2或4个字节长。
ARMv8-A:ARMv8-A引入了64位的A64指令集,其中指令通常是4个字节长。此外,ARMv8-A还支持A32和T32指令集,其中A32指令通常是4个字节长,而T32指令可以是2或4个字节长。

参考

https://bbs.kanxue.com/thread-277034.htm

 

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值