原本是想等分析完再一起发的,但是想了想检测部分还是单独发出来吧,这个APP的检测难度对我来说是相当大的(之前没有具体的分析过检测),记录一下
首先正常附加frida,启动,退出,一气呵成

hook 一下dlopen,打印一下加载的so,然后可以发现了一个很熟悉的so(上次研究到一半的某游戏盒也是这个),libmsaoaidsec.so

一开始以为很简单,毕竟已经有很多前辈研究过了,使用前辈的笔记代码过掉他就行了,【地址:https://bbs.kanxue.com/thread-285811.htm】,没想到,还是我太天真了,直接就运行报错,地址找不到?

咱们hook一下 create 进行打印看看调用的线程,这次线程出来了
address libmsaoaidsec.so 0x127f1
address libmsaoaidsec.so 0x11e1d
address libmsaoaidsec.so 0x19c09
咦,没想到这个so的地址居然变更了,没关系,咱们手动替换一下,运行,,但是五秒不到,还是直接闪退


打开IDA分析一下,首先进去就感觉不对劲,地址居然是0x127F0,和打印出来的线程对不上,查了一下(另外两个也是一样)


看来貌似是我hook错了,全部减一位,然后

一样报错,看来直接替换掉线程是有问题的了,那接下来我的思路就分为了两个
一:找找修改的frida或者模块以及其他的办法来绕过检测
二:直接硬刚,深入分析检查点进行处理
我首先选择的是绕过检测,毕竟之前都没有研究过,没有底,所以打算去网上找找看有没有什么过检测的办法
首先在b站找到了一个大佬发布的模块,看视频测试效果测试挺不错的,是能绕过大部分的frida检测,【地址:208K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6K6N6h3y4K6j5h3&6V1i4K6u0r3M7%4g2U0M7$3q4F1k6q4!0q4x3#2)9^5x3q4)9&6x3g2!0q4x3#2)9^5x3q4)9^5x3R3`.`.
我个人按照步骤折腾了好久,两部手机都没有实现效果,不晓得啥原因,差点还折腾坏了一部手机,让我朋友测试是正常的(有点不稳定),但是也是能够绕过的,各位有兴趣的可以试试。
PS:这个模块是作者发布在b站的,我感觉不错就放在这里了,如果对作者造成影响或者有什么不妥的话,请联系我进行删除

正在折腾上面的sucsand的时候我朋友给我发来了一个大佬魔改过的frida
frida16.2.1 编译patch全过程
【地址:cf7K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6@1j5h3W2K6N6h3W2A6i4K6u0r3M7Y4g2K6k6r3q4Q4x3V1k6Q4x3@1k6@1j5h3u0Q4x3@1c8J5k6h3q4V1L8h3g2Q4x3X3c8G2N6W2)9J5k6r3k6A6L8r3g2Q4c8e0y4Q4z5o6m8Q4z5e0p5`.
简直就是雪中送炭,测试 hook 上之后能够正常运行,成功绕过,但是一运行Java.perform()的代码就闪退,应该是有其他的检测点存在,不完美

frida都hook上了,但是java层还是没办法输出,有点不甘心,那么再深入,直接修改系统代码打印输出调用函数以及参数呢?
说干就干,折腾半天后(这块具体过程就不发了,有兴趣的可以自己网上找找相关的资料)我们直接看看结果,调用的函数以及传递的账密参数都能打印出来,但是不是每个人都能用这个办法的,还有没有其他的方案呢?有的,那就是


只要定位到检查点然后过掉不就行了,先打开IDA,分析分析那三个线程干了什么
0x127f1:首先对字符串进行了一系列的解密,然后进入循环重复执行,下面的这些函数估计就是主力

0x11e1d:这个也是直接进入循环检测的线程,貌似是检测Native层的反调试检测

0x19c09:这个貌似是一个验证什么东西的

那我们先把重点先放在前面两个线程身上,首先第一个线程
sub_122BC():检测系统进程

sub_123F0():检测当前进程的文件

sub_124C0:内存映射区域检测

sub_195B8:动态解密并执行shellcode来进行反调试检测

可以看到直接一个检测比一个检测牛逼,当时第一反应是能不能nop掉这些,直接不运行呢,尝试了半天,还是打开APP就卡死,实在没办法(不晓得是我的代码有问题还是有其他检测),那再换一种思路,你这不是每隔几秒钟才循环检测一次吗?我把你的检测时间调大不就行了。
然后又折腾了半天,终于可以了,启动,触发检测,都正常,虽然有点小瑕疵,比如说退出附加控制台可能会卡住什么的,但是起码把检测过了

直接分析之后逻辑基本上都能看得懂,并不是很难,重点是代码部分,我最初的想法是直接nop掉那几个具体的检测函数点,但是一直都有问题,或者说,根本没办法进行nop(不晓得我的代码是不是有问题),然后又尝试nop掉sleep的,一样不行,后面只能转变思路调大检测线程的时间
参考
libmsaoaidsec.so反调试及算法逆向案例(爱库存)
libmsaoaidsec.so 过检测
/**
* 不修改指令的延迟方案 - Hook sleep函数
*/
function hookSleepDelay() {
let hasHooked = false;
let moduleBase = null;
// 监控目标库加载
Interceptor.attach(Module.findExportByName("libc.so", "__system_property_get"), {
onEnter: function (args) {
if (hasHooked) return;
const module = Process.findModuleByName("libmsaoaidsec.so");
if (!module) return;
const propName = args[0].readCString();
if (propName && propName.includes("ro.build.version.sdk")) {
moduleBase = module.base;
console.log(`目标库基址: ${moduleBase}`);
// Hook sleep函数实现延迟
hookSleepFunction();
hasHooked = true;
}
}
});
// Hook sleep函数,针对反调试调用进行延长
function hookSleepFunction() {
console.log("进行 sleep 函数Hook...");
const sleepPtr = Module.findExportByName("libc.so", "sleep");
Interceptor.replace(sleepPtr, new NativeCallback(function(seconds) {
// 检查调用来源
const backtrace = Thread.backtrace(this.context, Backtracer.ACCURATE);
// 检查是否来自目标模块的反调试检测
let isFromAntiDebug = false;
for (let addr of backtrace) {
if (moduleBase && addr.compare(moduleBase) >= 0 &&
addr.compare(moduleBase.add(0x100000)) < 0) {
isFromAntiDebug = true;
break;
}
}
if (isFromAntiDebug && seconds === 4) {
const extendedTime = 3600; // 1小时
console.log(`sleep 检测: ${seconds}秒 -> ${extendedTime}秒 (1小时)`);
// 调用原始sleep但用延长时间
const originalSleep = new NativeFunction(sleepPtr, 'uint', ['uint']);
return originalSleep(extendedTime);
}
// 其他正常sleep调用
const originalSleep = new NativeFunction(sleepPtr, 'uint', ['uint']);
return originalSleep(seconds);
}, 'uint', ['uint']));
console.log("Sleep Hook完成!检测延迟到1小时");
// 测试
setTimeout(() => {
Java.perform(() => {
console.log("测试 Java.perform 是否正常运行!请等待五秒钟");
});
}, 1000);
}
}
hookSleepDelay();
/**
* 不修改指令的延迟方案 - Hook sleep函数
*/
function hookSleepDelay() {
let hasHooked = false;
let moduleBase = null;
// 监控目标库加载
Interceptor.attach(Module.findExportByName("libc.so", "__system_property_get"), {
onEnter: function (args) {
if (hasHooked) return;
const module = Process.findModuleByName("libmsaoaidsec.so");
if (!module) return;
const propName = args[0].readCString();
if (propName && propName.includes("ro.build.version.sdk")) {
moduleBase = module.base;
console.log(`目标库基址: ${moduleBase}`);
// Hook sleep函数实现延迟
hookSleepFunction();
hasHooked = true;
}
}
});
// Hook sleep函数,针对反调试调用进行延长
function hookSleepFunction() {
console.log("进行 sleep 函数Hook...");
const sleepPtr = Module.findExportByName("libc.so", "sleep");
传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!