Android 下通过触发 SIGTRAP 信号实现反调试
版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/
详细的 Linux 信号列表
Linux 信号是一种用于进程间通信(IPC)和异常处理的机制。以下是详细的 Linux 信号列表,包含信号名称、默认行为及用途
信号编号 | 信号名称 | 默认行为 | 说明 |
---|---|---|---|
1 | SIGHUP | 终止进程 | 终止控制终端或配置文件发生变化时发出。 |
2 | SIGINT | 终止进程 | 来自用户输入(通常是 Ctrl+C)。 |
3 | SIGQUIT | 终止进程并生成core文件 | 来自用户输入(通常是 Ctrl+\)。 |
4 | SIGILL | 终止进程并生成core文件 | 非法指令执行。 |
5 | SIGTRAP | 终止进程并生成core文件 | 调试陷阱。 |
6 | SIGABRT | 终止进程并生成core文件 | 调用 abort 函数时发出。 |
7 | SIGBUS | 终止进程并生成core文件 | 总线错误(内存访问不对齐)。 |
8 | SIGFPE | 终止进程并生成core文件 | 浮点运算错误。 |
9 | SIGKILL | 终止进程 | 强制终止进程,无法被捕获或忽略。 |
10 | SIGUSR1 | 终止进程 | 用户自定义信号 1。 |
11 | SIGSEGV | 终止进程并生成core文件 | 无效的内存访问。 |
12 | SIGUSR2 | 终止进程 | 用户自定义信号 2。 |
13 | SIGPIPE | 终止进程 | 向没有读取端的管道写入数据时发出。 |
14 | SIGALRM | 终止进程 | 由 alarm 函数发出的定时器信号。 |
15 | SIGTERM | 终止进程 | 请求终止进程,可以被捕获和忽略。 |
16 | SIGSTKFLT | 终止进程 | 协处理器栈错误。 |
17 | SIGCHLD | 忽略 | 子进程停止或终止时发出。 |
18 | SIGCONT | 继续执行 | 让停止的进程继续运行。 |
19 | SIGSTOP | 停止进程 | 停止进程,无法被捕获或忽略。 |
20 | SIGTSTP | 停止进程 | 来自用户输入的停止信号(通常是 Ctrl+Z)。 |
21 | SIGTTIN | 停止进程 | 后台进程尝试从终端读取输入时发出。 |
22 | SIGTTOU | 停止进程 | 后台进程尝试向终端写入输出时发出。 |
23 | SIGURG | 忽略 | 套接字有紧急数据到达时发出。 |
24 | SIGXCPU | 终止进程 | 超出 CPU 时间限制。 |
25 | SIGXFSZ | 终止进程 | 超出文件大小限制。 |
26 | SIGVTALRM | 终止进程 | 虚拟时钟信号,由 |
27 | SIGPROF | 终止进程 | 定时器到期,由 |
28 | SIGWINCH | 忽略 | 终端窗口大小改变时发出。 |
29 | SIGIO | 忽略 | I/O 事件发生时发出。 |
30 | SIGPWR | 终止进程 | 电源故障时发出。 |
31 | SIGSYS | 终止进程并生成core文件 | 非法的系统调用。 |
此外,Linux 还支持实时信号(Real-Time Signals),编号从 32 开始,通常是用于用户自定义的信号,应用程序可根据需要使用这些信号。
利用 SIGTRAP 检测调试器
SIGTRAP 是一个陷阱信号,通常由调试器在调试被调试程序时触发。
如果一个程序主动触发 SIGTRAP 信号,并且信号处理函数被成功调用,则意味着没有调试器存在,因为信号并未被拦截。
反之,如果信号处理函数没有被调用,则意味着调试器捕获并处理了该信号,从而可以推测出程序正处于被调试状态。
Android下反调试的流程
1. 我们通过 JNI 调用 C 代码来设置一个 SIGTRAP 信号处理器。
2. 当触发 SIGTRAP 时,信号处理器将会捕获信号。如果信号处理器成功处理了信号,则表明没有调试器。
3. 如果调试器存在,SIGTRAP 信号不会到达我们的信号处理器,程序将检测到这一情况并在 3 秒后退出。
Android下反调试实现
1. 定义信号处理器并检测调试器
首先,我们在 C 代码中编写反调试逻辑,核心是通过 raise(SIGTRAP) 触发 SIGTRAP 信号,并判断信号是否被捕获。
#include <jni.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <android/log.h>#define LOG_TAG "AntiDebug"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)// 标志变量,判断 SIGTRAP 是否被捕获
volatile int sigtrap_caught = 0;// SIGTRAP 信号处理函数
void sigtrap_handler(int sig) {LOGI("Caught SIGTRAP. No debugger present.");sigtrap_caught = 1; // 标记 SIGTRAP 被捕获
}// JNI 方法,触发 SIGTRAP 信号并检测调试器
JNIEXPORT jboolean JNICALL
Java_com_cyrus_example_antidebug_AntiDebug_detectDebugger(JNIEnv *env, jobject instance) {// 注册 SIGTRAP 处理器signal(SIGTRAP, sigtrap_handler);// 触发 SIGTRAP 信号raise(SIGTRAP);// 检查信号是否被捕获if (sigtrap_caught) {LOGI("No debugger detected.");return JNI_FALSE; // 没有检测到调试器} else {// 如果信号未被捕获,说明有调试器LOGI("Debugger detected! The program will exit in 3 seconds...");sleep(3); // 等待 3 秒exit(EXIT_FAILURE); // 退出程序return JNI_TRUE; // 返回 true,表示检测到调试器}
}
配置 CMakeLists.txt 文件
cmake_minimum_required(VERSION 3.4.1)find_library( # 查找 log 库log-lib# 库名log )add_library( # 库名称antidebug# 库类型SHARED# 源文件anti_debug.c )target_link_libraries( # 绑定库到 log 库antidebug${log-lib} )
2. Kotlin 层调用 JNI 方法
在 Kotlin 层,我们通过 JNI 调用 detectDebugger 函数,以检测是否存在调试器。根据结果,程序可以作出不同的响应。
package com.cyrus.example.antidebugimport android.util.Logobject AntiDebug {init {// 加载 native 库System.loadLibrary("antidebug")}external fun detectDebugger(): Booleanfun isDebuggerDetected(): Boolean {val detected = detectDebugger()if (detected) {Log.i("AntiDebug", "Debugger detected!")} else {Log.i("AntiDebug", "No debugger detected.")}return detected}
}
3. 调用反调试功能
val debuggerDetected = AntiDebug.isDebuggerDetected()
if (debuggerDetected) {Toast.makeText(this, "Debugger Detected", Toast.LENGTH_SHORT).show()
} else {Toast.makeText(this, "No Debugger Detected", Toast.LENGTH_SHORT).show()
}
测试反调试
1. 无调试状态
无调式状态 App 中点击 “SIGTRAP 反调试” 按钮调用反调试功能,未检测到调试器,程序正常运行。
2. 调试状态下
通过 IDA Pro 附加到当前应用
关于如何使用 IDA Pro 动态调试 Android App 可以参考这篇文章【使用IDA Pro动态调试Android APP】
App 中点击 “SIGTRAP 反调试” 按钮调用反调试功能,SIGTRAP 信号 被 IDA Pro 调试器捕获。
触发程序反调试机制,程序在 3 秒后退出。
源码
完整源码:https://github.com/CYRUS-STUDIO/AndroidExample
相关文章:

Android 下通过触发 SIGTRAP 信号实现反调试
版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/ 详细的 Linux 信号列表 Linux 信号是一种用于进程间通信(IPC)和异常处理的机制。以下是详细的 Linux 信号列表,包含信号名…...

【MySQL】 表的增删操作
目录 1.Create(增) 1.1.单行数据 全列插入 1.2.多行数据 指定列插入 1.3.插入否则更新 1.4.替换数据(REPLACE) 2.Delete(删) 2.1.删除表中的某个条目 2.2.删除整张表数据 2.3.截断表 1.Create…...

新生入门季 | 学习生物信息分析,如何解决个人电脑算力不足的问题?
随着生物信息学在科研和教育中的快速普及,越来越多的新生开始接触基因组测序、RNA分析等复杂计算任务。然而,在面对这些大规模数据时,个人电脑的算力往往显得捉襟见肘。你是否也在为自己的笔记本性能不足而苦恼? 这篇文章将为你提…...

20255 - 中医方剂学 - 考研 - 执业
第1章 总论 1.我国现存最早的记载方剂的医书是()( ) [单选] A.《太平圣惠方》 B.《黄帝内经》 C.《五十二病方》 D.《千金要方》 E.《外台秘要》 正确答案: C 2.我国最早的中医经典理论著作是()( ) [单选] A.《伤寒杂病论…...

【Vue.js设计与实现】第三篇第9章:渲染器-简单Diff算法-阅读笔记
文章目录 9.1 减少 DOM 操作的性能开销9.2 DOM 复用与 key 的作用9.3 找到需要移动的元素9.4 如何移动元素9.5 添加新元素9.6 移除不存在的元素 系列目录:【Vue.js设计与实现】阅读笔记目录 当新旧vnode 的子节点都是一组节点时,为了以最小的性能…...

服务器软件之Tomcat
服务器软件之Tomcat 服务器软件之Tomcat 服务器软件之Tomcat一、什么是Tomcat二、安装Tomcat1、前提:2、下载3、解压下载的tomcat4、tomcat启动常见错误4.1、tomcat8.0 startup报错java.util.logging.ErrorManager: 44.2、java.lang.UnsatisfiedLinkError 三、Tomca…...

Flutter包管理(三)
1、作用 在APP的实际开发过程中往往会依赖很多包,而这些包之间存在着交叉依赖、版本依赖,由开发者自己管理手动管理会非常麻烦,每种开发生态或编程官方会提供一些包的管理工具,在Flutter中我们在pubspec.yaml文件中来管理第三方依…...

CGNS资料
CGNS数据文件 资料 CFD General Notation System CGNS Converters vtkCGNSReader cgnsToFromFoam Example Computer Codes 8.1.2. CGNS Mesh Format and Multizone Interface Connectivity 8 Multizone Interface Connectivity pyvista.cgnsreader CGNS for MATLAB and Octave…...

论文阅读(十六):Deep Residual Learning for Image Recognition
文章目录 1.介绍2.基本原理3.两种残差块4.网络结构 论文:Deep Residual Learning for Image Recognition 论文链接:Deep Residual Learning for Image Recognition 代码链接:Github 1.介绍 在ResNet网络提出之前,传统的卷…...

Dubbo 序列化方式
Hession 这是dubbo的默认序列化协议,是一种二进制协议,他的特点是序列化的速度比较快,并且序列化的数据体积比较小。Hession适合于大部分场景,因此被选为dubbo的默认序列化协议。 Json Json是一种基于文本的序列化方式…...

如何替换OCP节点(二):使用 antman脚本 | OceanBase应用实践
前言: OceanBase Cloud Platform(简称OCP),是 OceanBase数据库的专属企业级数据库管理平台。 在实际生产环境中,OCP的安装通常是第一步,先搭建OCP平台,进而依赖OCP来创建、管理和监控我们的生…...

15.JVM垃圾收集算法
一、垃圾收集算法 1.分代收集理论 分代收集理论是JAVA虚拟机进行垃圾回收的一种思想,根据对象存活周期的不同将内存分成不同的几个区域;一般将JAVA堆内存分为新生代和老年代;根据每个分代特点选择不同的垃圾收集器; 在新生代中&am…...

软件工程:图书管理系统甘特图
1 实验目的 熟悉GanttProject 软件环境,能够使用GanttProject绘制甘特图,进行项目管理与规划。 2 实验内容 为小型图书管理系统项目的实施计划绘制甘特图。 小型图书管理系统项目包含登录、浏览、管理读者、管理图书资料、管理书目、登记借书、登记还书、预定图书、…...

视频的编解码格式
文章目录 视频的编解码格式概念术语视频处理流程视频封装格式视频编码格式视频编解码器,视频容器和视频文件格式之间的区别补充视频码率 参考资料 视频的编解码格式 概念术语 两大组织主导视频压缩的组织及其联合(joint)组织 ITU-T(VCEG) ITU-T的中文名称是国际电信…...

网络资源模板--Android Studio 实现简易新闻App
目录 一、项目演示 二、项目测试环境 三、项目详情 四、完整的项目源码 一、项目演示 网络资源模板--基于Android studio 实现的简易新闻App 二、项目测试环境 三、项目详情 登录页 用户输入: 提供账号和密码输入框,用户可以输入登录信息。支持“记…...

LabVIEW提高开发效率技巧----离线调试
离线调试是LabVIEW开发中一项重要的技巧,通过使用Simulate Signal Express VI生成虚拟数据,开发者能够有效减少对实际硬件的依赖,加速开发过程。这种方法不仅可以提高开发效率,还能降低成本,增强系统的灵活性。 离…...

6N137S1取反电路图
文章目录 一、前言二、6N137S1性能介绍三、应用电路图 一、前言 在硬件电路设计中需要用到隔离电路,但此引脚输出为WS2812的信号,频率有840khz,所以需要使用逻辑光耦,选用6N137S1光耦,速率能达到10Mhz,能满…...

Nullinux:一款针对Linux操作系统的安全检测工具
关于Nullinux Nullinux是一款针对Linux操作系统的安全检测工具,广大研究人员可以利用该工具针对Linux目标设备执行网络侦查和安全检测。 该工具可以通过SMB枚举目标设备的安全状况信息,其中包括操作系统信息、域信息、共享信息、目录信息和用户信息。如…...

学会这 5 个 AI 神器做字体设计,保证让你私单接到爆!
最近我在浏览 AI 绘画的相关内容时,发现不少图像都是与字体相关的,而且其中一些呈现出的艺术特效很是让人眼前一亮。 放在之前,我们需要掌握一些专业技能、并花费大量时间才能设计出精致酷炫的艺术字,但是现在却可以轻松用文本直…...

《Vue3 踩坑》expose 和 defineExpose 暴露属性或方法注意事项
选项式写法 使用 选项式API - 状态选项 - expose 一定要注意: 接下来,进一步看示例说明: 设置 expose 仅显示列出的属性/方法才能被父组件调用;代码第 2 行,父组件可访问属性 a 和 方法 myFunc01,不可访…...

10.13论文阅读
通过联合学习检测和描述关键点增强可变形局部特征 摘要 局部特征提取是计算机视觉中处理图像匹配和检索等关键任务的常用方法。大多数方法的核心理念是图像经历仿射变换,忽略了诸如非刚性形变等更复杂的效果。此外,针对非刚性对应的新兴工作仍然依赖于…...

六西格玛黑带项目:TBX-02无人机飞行稳定性提升——张驰咨询
一、项目背景与问题定义 TBX-02是该公司最新发布的消费级无人机,面向摄影爱好者和户外探险者。产品上市后,通过客户反馈和实际测试数据发现,该无人机在复杂飞行环境中,如强风或快速移动时,存在明显的飞行抖动和稳定性…...

git clone 国内镜像
比如 git clone https://github.com/HKUST-Aerial-Robotics/A-LOAM.git 改成 git clone https://gitclone.com/github.com/HKUST-Aerial-Robotics/A-LOAM.git...

【服务器虚拟化】
服务器虚拟化是一种将一台物理服务器划分为多个虚拟服务器的技术,每个虚拟服务器都可以独立运行操作系统和应用程序。下面是一个详细的教程,以KVM虚拟化为例,介绍了具体的操作步骤和执行命令。 准备工作 a. 确保你的服务器支持虚拟化技术&…...

【RAG】aiops第一名方案-EasyRAG:自动网络运营的高效检索增强生成框架
来看一个RAG比赛方案,提出了一个名为EasyRAG的框架,用于自动化网络操作的检索增强生成。该框架旨在解决网络操作中信息检索和生成效率低、准确性差的问题。研究难点包括:如何在保证准确性的前提下提高检索和生成的效率;如何实现简…...

3款备受好评的电脑数据恢复软件,赶紧收藏以备不时之需
在日常工作和生活中,电脑数据丢失是许多人都会遇到的问题。无论是误删文件、硬盘格式化,还是系统崩溃,都可能导致重要数据的丢失。所以,好用的数据恢复软件必不可少。 但在如今的市场上数据恢复软件琳琅满目,它们在恢复…...

.net core 实现多线程方式有哪些
在 .NET Core 中,有多种方式可以实现多线程编程。这些方式包括使用 Thread 类、Task 和 Parallel 类库。每种方法都有其适用场景和优缺点。下面我将通过代码示例来展示这些不同的多线程实现方式。 1. 使用 Thread 类 Thread 类是 .NET 中最基本的多线程实现方式。…...

《Linux从小白到高手》综合应用篇:深入理解Linux磁盘及IO优化
1. 前言 其实磁盘优化和IO优化,我在前面的其他Linux调优博文中已经讲述过或者涉及过了,但是太过零碎,所以本篇就来集中深入讨论下Linux磁盘和IO调优。 2.磁盘调优 结合我多年的经验,本人认为磁盘调优最重要的是读写性能的提升和…...

【Linux】内存文件系统的I/O、重定向
文章目录 1. 系统中的文件2. 回顾C中的文件接口3. 文件类的系统调用3.1 open3.2 文件描述符 4. IO的基本过程5.重定向5.1 引入重定向5.2 系统中的重定向接口 6. 缓冲区问题7. 简单版shell的实现 1. 系统中的文件 在学习完Linux权限后,我们清楚的知道:文…...

力扣10.18
1463. 摘樱桃 II 给你一个 rows x cols 的矩阵 grid 来表示一块樱桃地。 grid 中每个格子的数字表示你能获得的樱桃数目。 你有两个机器人帮你收集樱桃,机器人 1 从左上角格子 (0,0) 出发,机器人 2 从右上角格子 (0, cols-1) 出发。 请你按照如下规则…...