frida常用检测点及其原理

文章转载于:https://bbs.kanxue.com/thread-278145.htm

frida常见反调试

查看哪个so在检测frida

function hook_dlopen() {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("load " + path);}}});
}

so的加载流程,那么就会知道linker会先对so进行加载与链接,然后调用so的.init_proc函数,接着调用.init_array中的函数,最后才是JNI_OnLoad函数,所以我需要先确定检测点大概在哪个函数中。

管他检测啥、直接一把梭

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("REJECT") !== -1 ||str2.indexOf("tmp") !== -1 ||str2.indexOf("frida") !== -1 ||str2.indexOf("gum-js-loop") !== -1 ||str2.indexOf("gmain") !== -1 ||str2.indexOf("linjector") !== -1) {console.log("strstr-->", str1, str2);this.hook = true;}}, onLeave: function (retval) {if (this.hook) {retval.replace(0);}}});Interceptor.attach(pt_strcmp, {onEnter: function (args) {var str1 = args[0].readCString();var str2 = args[1].readCString();if (str2.indexOf("REJECT") !== -1 ||str2.indexOf("tmp") !== -1 ||str2.indexOf("frida") !== -1 ||str2.indexOf("gum-js-loop") !== -1 ||str2.indexOf("gmain") !== -1 ||str2.indexOf("linjector") !== -1) {//console.log("strcmp-->", str1, str2);this.hook = true;}}, onLeave: function (retval) {if (this.hook) {retval.replace(0);}}})}replace_str();

测试xhs 、bilibili都可以过

1、检测文件名(改名)、端口名27042(改端口)、双进程保护(spawn启动)

2、检测D-Bus

  • 检测的原因是因为安卓系统中,D-Bus通信并不常见,而且不同于在传统Linux系统中广泛使用,安卓系统使用Binder机制来实现进程间通信(IPC),而不是使用D-Bus
  • D-Bus是一种进程间通信(IPC)和远程过程调用(RPC)机制,最初是为Linux开发的,目的是用一个统一的协议替代现有的和竞争的IPC解决方案。

遍历连接手机所有端口发送D-bus消息,如果返回"REJECT"这个特征则认为存在frida-server

内存中存在frida rpc字符串,认为有frida-server


/** Mini-portscan to detect frida-server on any local port.*/
for(i = 0 ; i <= 65535 ; i++) {sock = socket(AF_INET , SOCK_STREAM , 0);sa.sin_port = htons(i);if (connect(sock , (struct sockaddr*)&sa , sizeof sa) != -1) {__android_log_print(ANDROID_LOG_VERBOSE, APPNAME,  "FRIDA DETECTION [1]: Open Port: %d", i);memset(res, 0 , 7);// send a D-Bus AUTH message. Expected answer is “REJECT"send(sock, "\x00", 1, NULL);send(sock, "AUTH\r\n", 6, NULL);usleep(100);if (ret = recv(sock, res, 6, MSG_DONTWAIT) != -1) {if (strcmp(res, "REJECT") == 0) {/* Frida server detected. Do something… */}}}close(sock);
}
  • 检测D-Bus可以通过hook系统库函数,比如strstrstrcmp等等
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("REJECT") !== -1) {//console.log("strcmp-->", str1, str2);this.hook = true;}}, onLeave: function (retval) {if (this.hook) {retval.replace(0);}}});Interceptor.attach(pt_strcmp, {onEnter: function (args) {var str1 = args[0].readCString();var str2 = args[1].readCString();if (str2.indexOf("REJECT") !== -1) {//console.log("strcmp-->", str1, str2);this.hook = true;}}, onLeave: function (retval) {if (this.hook) {retval.replace(0);}}})}replace_str();

3、检测/proc/pid/maps依赖文件

  • maps文件中存储的是APP运行时加载的依赖
  • 当启动frida后,在maps文件中就会存在 frida-agent-64.sofrida-agent-32.so 文件。
char line[512];
FILE* fp;
fp = fopen("/proc/self/maps", "r");
if (fp) {while (fgets(line, 512, fp)) {if (strstr(line, "frida")) {/* Evil library is loaded. Do something… */}}fclose(fp);} else {/* Error opening /proc/self/maps. If this happens, something is off. */}
}
  • 绕过
function replace_str_maps() {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("REJECT") !== -1  || str2.indexOf("frida") !== -1) {this.hook = true;}}, onLeave: function (retval) {if (this.hook) {retval.replace(0);}}});Interceptor.attach(pt_strcmp, {onEnter: function (args) {var str1 = args[0].readCString();var str2 = args[1].readCString();if (str2.indexOf("REJECT") !== -1  || str2.indexOf("frida") !== -1) {this.hook = true;}}, onLeave: function (retval) {if (this.hook) {retval.replace(0);}}})}replace_str();

4、检测/proc/pid/tast下线程、fd目录下打开文件

  • /proc/pid/task 目录下,可以通过查看不同的线程子目录,来获取进程中每个线程的运行时信息。这些信息包括线程的状态、线程的寄存器内容、线程占用的CPU时间、线程的堆栈信息等。通过这些信息,可以实时观察和监控进程中每个线程的运行状态,帮助进行调试、性能优化和问题排查等工作。

  • /proc/pid/fd 目录的作用在于提供了一种方便的方式来查看进程的文件描述符信息,这对于调试和监控进程非常有用。通过查看文件描述符信息,可以了解进程打开了哪些文件、网络连接等,帮助开发者和系统管理员进行问题排查和分析工作。

  • 打开frida调试后这个task目录下会多出几个线程,检测点在查看这些多出来的线程是否和frida调试相关。

  • 在某些app中就会去读取 /proc/stask/线程ID/status 文件,如果是运行frida产生的,则进行反调试。例如:gmain/gdbus/gum-js-loop/pool-frida

1.gmain:Frida 使用 Glib 库,其中的主事件循环被称为 GMainLoop。在 Frida 中,gmain 表示
GMainLoop 的线程。
2.gdbus:GDBus 是 Glib 提供的一个用于 D-Bus 通信的库。在 Frida 中,gdbus
表示 GDBus 相关的线程。 gum-js-loop:Gum 是 Frida 的运行时引擎,用于执行注入的 JavaScript
代码。
3.gum-js-loop 表示 Gum 引擎执行 JavaScript 代码的线程。
4.pool-frida:Frida中的某些功能可能会使用线程池来处理任务,pool-frida 表示 Frida 中的线程池。
5. linjector 是一种用于 Android设备的开源工具,它允许用户在运行时向 Android 应用程序注入动态链接库(DLL)文件。通过注入 DLL文件,用户可以修改应用程序的行为、调试应用程序、监视函数调用等,这在逆向工程、安全研究和动态分析中是非常有用的。

  • 绕过
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("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(0);}}});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(0);}}})}replace_str();

5、frida-server启动

当frida-server启动时,在 /data/local/tmp/目录下会生成一个文件夹并且会生成一下带有frida的特征。

  • 重新编译去特征
  • hook

6、直接调用openat的syscall的检测在text节表中搜索frida-gadget.so / frida-agent.so字符串,避免了hook libc来anti-anti的方法

注入方式改为

  • 1、frida-inject
  • 2、ptrace注入 配置文件的形式注入
  • 3、编译rom注入

7、从inlinehook角度检测frida

  • https://bbs.kanxue.com/thread-269862.htm 未学习
  • https://zhuanlan.zhihu.com/p/557713016

8、hook_open函数可以查看是哪里检测了so文件

function hook_open(){var pth = Module.findExportByName(null,"open");Interceptor.attach(ptr(pth),{onEnter:function(args){this.filename = args[0];console.log("",this.filename.readCString())if (this.filename.readCString().indexOf(".so") != -1){args[0] = ptr(0)}},onLeave:function(retval){return retval;}})
}
setImmediate(hook_open)

替换一个正常的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/728384.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

死锁的四个必要条件怎么理解

简单介绍 死锁是指在多线程或多进程的环境中&#xff0c;两个或多个进程或线程相互等待对方所持有的资源而无法继续执行的情况。死锁发生时&#xff0c;各个进程或线程都无法继续执行&#xff0c;系统处于僵持状态。 死锁发生的四个必要条件是&#xff1a; 互斥条件&#xff0…

第五十二回 戴宗二取公孙胜 李逵独劈罗真人-飞桨AI框架安装和使用示例

吴用说只有公孙胜可以破法术&#xff0c;于是宋江请戴宗和李逵去蓟州。两人听说公孙胜的师傅罗真人在九宫县二仙山讲经&#xff0c;于是到了二仙山&#xff0c;并在山下找到了公孙胜的家。 两人请公孙胜去帮助打高唐州&#xff0c;公孙胜说听师傅的。罗真人说出家人不管闲事&a…

SpringMVC 中的常用注解和用法

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;JavaEE &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; 注解 1. MVC定义2. 注解2.1 RequestMappin…

leetcode:LCR 006. 两数之和 II - 输入有序数组(python3解法)

难度&#xff1a;简单 给定一个已按照 升序排列 的整数数组 numbers &#xff0c;请你从数组中找出两个数满足相加之和等于目标数 target 。 函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 0 开始计数 &#xff0c;所以答案数组应当满足 0 <…

牛客刷题|HJ24 合唱队,HJ25 数据分类处理 , HJ26 字符串排序

HJ24 合唱队 题目链接&#xff1a;合唱队_牛客题霸_牛客网 (nowcoder.com) 思路&#xff1a;对队列中每个元素分别找左边最长递增序列和右边最长递减序列&#xff08;都不一定是连续的&#xff09;&#xff0c;那么以当前元素为“山顶”可以保留的最大人数就是两者之和减一。…

el-dialog封装组件

父页面 <template><div><el-button type"primary" click"visible true">展示弹窗</el-button><!-- 弹窗组件 --><PlayVideo v-if"visible" :visible.syncvisible /></div> </template><sc…

C语言数组进阶-数组名的理解和计算

在之前我们关于数组的内容中&#xff0c;我们已经提出了关于数组名的理解 一般情况下&#xff0c;数组名是数组首元素的地址&#xff0c;但有两个例外&#xff1a; 1.sizeof(数组名)是计算整个数组的大小 2.&数组名是取出的整个数组的地址 sizeof不管后面是啥&#xff0c;只…

谷粒学院--在线教育实战项目【一】

谷粒学院--在线教育实战项目【一】 一、项目概述1.1.项目来源1.2.功能简介1.3.技术架构 二、Mybatis-Plus概述2.1.简介2.2.特性 三、Mybatis-Plus入门3.1.创建数据库3.2.创建 User 表3.3.初始化一个SpringBoot工程3.4.在Pom文件中引入SpringBoot和Mybatis-Plus相关依赖3.5.第一…

融资项目——OpenFeign的降级与熔断

当一个微服务调用其他微服务时&#xff0c;如果被调用的微服务因各种原因无法在规定时间内提供服务&#xff0c;则可以直接使用本地的服务作为备选&#xff0c;即进行降级熔断。 如之前所提到的微服务为例&#xff1a; 如果希望实现降级熔断&#xff0c;可以在本地创建一个实现…

探索vue框架的世界: 内部、外部样式和内联样式动态绑定的方法

在实际项目中&#xff0c;经常会遇到这样的场景&#xff0c;可以通过逻辑层中设定的变量&#xff0c;在视图层中来呈现不同的样式&#xff0c;那么这种动态绑定样式的方式如何实现呢&#xff1f; 本篇文章&#xff0c;博主将和大家分享动态绑定内联样式style 和 动态绑定内部和…

AI改变游戏规则:内容创作的新时代!

AI技术&#xff0c;尤其是人工智能&#xff08;AI&#xff09;在内容创作领域的应用&#xff0c;正开启了一个全新的时代。这一时代的核心在于利用AI的能力&#xff0c;不仅提高内容创作的效率&#xff0c;还能引入前所未有的创新元素&#xff0c;从而彻底改变游戏规则。 AI在…

OpenCV与AI深度学习 | 基于OpenCV实现模糊检测 / 自动对焦

本文来源公众号“OpenCV与AI深度学习”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;基于OpenCV实现模糊检测 / 自动对焦 导 读 本文主要介绍使用OpenCV实现图像模糊检测/相机自动对焦功能。 前 言 为了检测图片是否对焦&…

coqui-ai/TTS 案例model文件

GitHub - coqui-ai/TTS: &#x1f438;&#x1f4ac; - a deep learning toolkit for Text-to-Speech, battle-tested in research and production Coqui AI的TTS是一款开源深度学习文本转语音工具&#xff0c;以高质量、多语言合成著称。它提供超过1100种语言的预训练模型库&…

C#,哈夫曼编码(Huffman Code)压缩(Compress )与解压缩(Decompress)算法与源代码

David A. Huffman 1 哈夫曼编码简史&#xff08;Huffman code&#xff09; 1951年&#xff0c;哈夫曼和他在MIT信息论的同学需要选择是完成学期报告还是期末考试。导师Robert M. Fano给他们的学期报告的题目是&#xff0c;寻找最有效的二进制编码。由于无法证明哪个已有编码是…

java编程的简化表达方法——Lambda表达式及方法引用概述

前言&#xff1a; 学到简化写法了&#xff0c;感觉需要对代码非常熟悉才能用得好&#xff0c;整理下写法。打好基础&#xff0c;daydayup! Lambda表达式 Lambda表达式是JDK8开始新增得一种语法形式&#xff1b;作用&#xff1a;用于简化匿名内部类的代码写法。 Lambda表达式的格…

CPU处理器模式与异常

ARM架构中的Exception Level&#xff08;EL&#xff09; 在ARM架构中&#xff0c;Exception Level&#xff08;EL&#xff09;是一个关键概念&#xff0c;它表示了处理器当前处理异常或中断的层次。ARMv8-A架构定义了四个Exception Levels&#xff1a;EL0、EL1、EL2和EL3&…

蓝桥杯嵌入式模板构建——RCT时钟

在CubeMX里的RTC模块启用RTC时钟和日历功能 输入到RTC的时钟要配置成1HZ,这样的话RTC每经过1s走时一次 由于RTC时钟默认配置为32Khz 所以我们需要将异步分频值与同步分频值的乘积调整为32K分频即可一秒走时一次 频率&#xff1a;32000hz / 32000hz 1hz 必须是31和999&#…

程序员的最佳副业居然是这个

程序员的副业思考 从 2008 年开始接触编程&#xff0c;已经在程序开发领域摸爬滚打 16 年。期间呆过私企&#xff0c;国企&#xff0c;外企&#xff0c;500 强&#xff0c;打过杂&#xff0c;创过业&#xff0c;干过核心开发&#xff0c;也搞过代码测试。总结起来就是四个字&a…

阿珊详解Vue路由的两种模式:hash模式与history模式

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

基于SpringBoot的在线拍卖系统设计与实现(源码)

项目源码&#xff1a;https://gitee.com/oklongmm/biye2 引言 随着互联网技术的发展&#xff0c;电子商务得以快速发展&#xff0c;其中之一的在线拍卖系统也逐渐得到了广泛的应用。但是&#xff0c;现有的在线拍卖系统在操作复杂性、安全性和稳定性方面存在一定的问题。为了…