过掉XXAPP frida检测

admin 2025年1月17日18:49:45评论20 views字数 6479阅读21分35秒阅读模式
来到新公司以后,很忙。另外一个小伙伴在某大厂,也是特别忙。就很久没有更新了,下来抽空的时候多更新更新
过掉XXAPP frida检测
前提:存在frida检测,直接运用server打开应用,会闪退,hluda也不行。

1.先去Hook dlopen

过掉XXAPP frida检测
functionhook_dlopen() {Interceptor.attach(Module.findExportByName(null"android_dlopen_ext"),        {onEnterfunction (args) {var pathptr = args[0];if (pathptr !== undefined && pathptr != null) {var path = ptr(pathptr).readCString();console.log("load " + path);                }            }        }    );}hook_dlopen()

查看到是libmsaoaidsec.so进行到了最后一步,猜测是这个so进行了ptrace检测进程

第二步:

验证下是在jni_onload之前还是之后

如果调用了该函数就输出一行日志

如果没有日志输出,那么就说明检测点在.init_xxx函数中。.init_xxx对应的是下面补充的的init()

注入的时机可以选择dlopen加载libmsaoaidsec.so完成之后

functionhook_dlopen(soName = '') {Interceptor.attach(Module.findExportByName(null"android_dlopen_ext"),        {onEnterfunction (args) {var pathptr = args[0];if (pathptr !== undefined && pathptr != null) {var path = ptr(pathptr).readCString();if (path.indexOf(soName) >= 0) {this.is_can_hook = true;                    }                }            },onLeavefunction (retval) {if (this.is_can_hook) {hook_JNI_OnLoad()                }            }        }    );}functionhook_JNI_OnLoad(){letmodule = Process.findModuleByName("libmsaoaidsec.so")Interceptor.attach(module.base.add(0xC6DC + 1), {onEnter(args){console.log("call JNI_OnLoad")        }    })}setImmediate(hook_dlopen, "libmsaoaidsec.so")
过掉XXAPP frida检测

没有任何输出,说明是在jni_onload

尝试 hook pthread 方法,pthread 用于线程的创建、同步、管理和终止

过掉XXAPP frida检测

如何过掉frida检测?

想法:直接nop掉pthread_create或者替换检测函数

上面看到三个地址

0x1c544,0x1b8d4,0x26e5c

过掉XXAPP frida检测

直接去hook这个 18BD4,按住X进行多个循环引用

过掉XXAPP frida检测
过掉XXAPP frida检测

再次按住X进行引用

过掉XXAPP frida检测
过掉XXAPP frida检测

追踪到了init_proc这个地方

另外这个 hook 时机要早,因为这个函数的调用是通过 init_proc 调用的。通过调用比init_proc更早的来进行调用。

我们可以通过 hook call_constructors 这个, call_constructors 主要作用是执行那些需要在程序开始运行之前完成初始化的代码,hook 代码如下

var dlopen = Module.findExportByName(null"dlopen");var android_dlopen_ext = Module.findExportByName(null"android_dlopen_ext");Interceptor.attach(dlopen, {onEnterfunction (args) {var path_ptr = args[0];var path = ptr(path_ptr).readCString();console.log("[dlopen -> enter", path);    },onLeavefunction (retval) {console.log("dlopen -> leave")    }});Interceptor.attach(android_dlopen_ext, {onEnterfunction (args) {var path_ptr = args[0];var path = ptr(path_ptr).readCString();console.log("[android_dlopen_ext -> enter", path);if (args[0].readCString() != null && args[0].readCString().indexOf("libmsaoaidsec.so") >= 0) {hook_call_constructors()        }    },onLeavefunction (retval) {console.log("android_dlopen_ext -> leave")    }});functionhook_call_constructors() {var linker64_base_addr = Module.getBaseAddress("linker64")var call_constructors_func_off =0xa128cvar call_constructors_func_addr = linker64_base_addr.add(call_constructors_func_off)var listener = Interceptor.attach(call_constructors_func_addr, {onEnterfunction (args) {console.log("call_constructors -> enter")varmodule = Process.findModuleByName("libmsaoaidsec.so")if (module != null) {Interceptor.replace(module.base.add(0x1B924), newNativeCallback(function () {console.log("替换成功")                    }, "void", []))                    listener.detach()                  }            },        })    }

问题:

为什么要先hook dlopen再去Hook call_constructors?

时机不对,call_constructors 是一个初始化函数,通常在库加载完成后会被调用。  如果直接Hook可能导致so没有被加载。所以如果是要Hook call_constructors之前要Hook dlopen。 在 Android 上,android_dlopen_ext 有时会用来加载一些特定的系统库。通过 hook android_dlopen_ext,可以在更高层次上监控到一些特定库(如 libmsaoaidsec.so)的加载 。下图有补充加载so的流程,具体代码,就不跟了,之前也跟踪过。

上面这个方法是从Linker64里面寻找符号,将符号给替换掉

通过上述代码,发现豆瓣绕不过去,换下一个。

第二种方法:

首先在.init_proc函数中找一个调用了外部函数的位置,时机越早越好。尝试去利用Hook。原因:

选择了_system_property_get函数,接下来使用frida hook dlopen函数

  • 当加载libmsaoaidsec.so
  • 在回调方法中hook _system_property_get函数,以"ro.build.version.sdk"字符串作为过滤器。
  • 如果_system_property_get函数被调用了
  • 那么这个时候也就是.init_proc函数刚刚调用的时候,比jni_onload加载进去的要早
  • 如果_system_property_get函数被调用了,那么这个时候也就是.init_proc函数刚刚调用的时候,在这个时机点可以注入我想要的代码,具体实现如上。

从init_proc里面寻找ro.build.version.sdk

过掉XXAPP frida检测

sub_123F0找到了

过掉XXAPP frida检测

尝试去利用

functionlocate_init() {    let r = null    Interceptor.attach(Module.findExportByName(null"__system_property_get"),        {onEnter: function(args) {var name = args[0];if(name !== undefined && name != null) {                    name = ptr(name).readCString();                    //console.log(name)if(name.indexOf("ro.build.version.sdk") >= 0) {var  r = Process.findModuleByName("libmsaoaidsec.so")nop_64(r.base.add("0x1c544"))nop_64(r.base.add("0x1b8d4"))nop_64(r.base.add("0x26e5c"))                    }                }            }        }    );}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.search("libmsaoaidsec.so") != -1){                this.hook = truelocate_init()            }        }    }});functionnop_64(addr{    Memory.protect(addr, 4 , 'rwx');var w = new Arm64Writer(addr);    w.putRet();    w.flush();    w.dispose();}

刚才这个尝试直接使用了 Module.findExportByName 来定位到需要 hook 的函数  

补充:

Module.findExportByName 是 Frida 提供的一个非常强大的 API,它可以直接从已加载的模块中查找导出符号,并返回该符号对应的地址。不需要显式地从 linker64 或者其他模块开始查找符号。

直接hook这个,发现能绕过去

补充:

hook so的加载流程

过掉XXAPP frida检测

在Hook so的时候,首先要知道so的加载流程

如果是hook jni_onload之前,就可以利用是init_proc还有call_constructors

换另外一种方法:

https://www.52pojie.cn/thread-1998228-1-1.html

如果是Hook jni_onload(梆梆)做校验,那就只能在这个地方搞了

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

可以大概看看这篇文章,也是hook东西的

参考文章:

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

https://www.52pojie.cn/thread-1998228-1-1.html

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

反思:

这个是在检测so的地方做文章,那么直接把 pthread_create 每次都替换掉不就行了

进行尝试

functionhook_pthread() {var pthread_create_addr = Module.findExportByName(null'pthread_create');console.log("pthread_create_addr,", pthread_create_addr);var pthread_create = newNativeFunction(pthread_create_addr, "int", ["pointer""pointer""pointer""pointer"]);Interceptor.replace(pthread_create_addr, newNativeCallback(function (parg0, parg1, parg2, parg3) {var so_name = Process.findModuleByAddress(parg2).name;var so_path = Process.findModuleByAddress(parg2).path;var so_base = Module.getBaseAddress(so_name);var offset = parg2 - so_base;console.log("so_name", so_name, "offset", offset, "path", so_path, "parg2", parg2);varPC = 0;if ((so_name.indexOf("libexec.so") > -1) || (so_name.indexOf("xxxx") > -1)) {console.log("find thread func offset", so_name, offset);if ((1 === offset)) {console.log("anti bypass");      } elseif (1 === offset) {console.log("anti bypass");      } elseif (1 === offset) {console.log("anti bypass");      } elseif (1 === offset) {console.log("anti bypass");      } elseif (1 === offset) {console.log("anti bypass");      } elseif (1 === offset) {console.log("anti bypass");      } elseif (1 === offset) {console.log("anti bypass");      } else {PC = pthread_create(parg0, parg1, parg2, parg3);console.log("ordinary sequence"PC)      }    } else {PC = pthread_create(parg0, parg1, parg2, parg3);// console.log("ordinary sequence", PC)    }    return PC;  }, "int", ["pointer", "pointer", "pointer", "pointer"]))}hook_pthread();
过掉XXAPP frida检测

没成功,后续再进行研究

原文始发于微信公众号(呼啦啦安全):过掉XXAPP frida检测

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年1月17日18:49:45
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   过掉XXAPP frida检测http://cn-sec.com/archives/3640618.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息