详解C++的反调试技术与绕过手法

news2026/4/28 20:16:45
反调试技术的实现方式有很多最简单的一种实现方式莫过于直接调用Windows系统提供给我们的API函数这些API函数中有些专门用来检测调试器的有些则是可被改造为用于探测调试器是否存在的工具多数情况下调用系统API函数实现反调试是不明智的原因很简单目标主机通常会安装主动防御系统而作为主动防御产品默认会加载RootKit驱动挂钩这些敏感函数的使用如果被非法调用则会提示错误信息病毒作者通常会使用汇编自行实现这些类似于系统提供给我们的反调试函数并不会使用系统的API这样依附于API的主动防御的系统将会失效。1.加载调试符号链接文件并放入d:/symbols目录下.1230:000 .sympath srv*d:\symbols*http://msdl.microsoft.com/download/symbols0:000 .reloadReloading current modules2.位于fs:[0x30]的位置就是PEB结构的指针,接着我们分析如何得到的该指针,并通过通配符找到TEB结构的名称.1234560:000 dt ntdll!*teb*ntdll!_TEBntdll!_GDI_TEB_BATCHntdll!_TEB_ACTIVE_FRAMEntdll!_TEB_ACTIVE_FRAME_CONTEXTntdll!_TEB_ACTIVE_FRAME_CONTEXT3.接着可通过dt命令,查询下ntdll!_TEB结构,如下可看到0x30处ProcessEnvironmentBlock存放的正是PEB结构.12345670:000 dt -rv ntdll!_TEBstruct _TEB, 66 elements, 0xfb8 bytes0x000 NtTib : struct _NT_TIB, 8 elements, 0x1c bytes# NT_TIB结构0x018 Self : Ptr32 to struct _NT_TIB, 8 elements, 0x1c bytes# NT_TIB结构0x020 ClientId : struct _CLIENT_ID, 2 elements, 0x8 bytes# 保存进程与线程ID0x02c ThreadLocalStoragePointer : Ptr32 to Void0x030 ProcessEnvironmentBlock : Ptr32 to struct _PEB, 65 elements, 0x210 bytes# PEB结构偏移地址0x18是_NT_TIB结构,也就是指向自身偏移0x0的位置.1234560:000 r $teb$teb7ffdf0000:000dd$teb0x187ffdf018 7ffdf000 00000000 00001320 00000c107ffdf028 00000000 00000000 7ffd9000 00000000而!teb地址加0x30正是PEB的位置,可以使用如下命令验证.1234567891011121314151617180:000dd$teb0x307ffdf030 7ffd9000 00000000 00000000 000000007ffdf040 00000000 00000000 00000000 000000000:000 !tebTEB at 7ffdf000ExceptionList: 0012fd0cStackBase: 00130000StackLimit: 0012e000SubSystemTib: 00000000FiberData: 00001e00ArbitraryUserPointer: 00000000Self: 7ffdf000EnvironmentPointer: 00000000ClientId: 00001320 . 00000c10RpcHandle: 00000000Tls Storage: 00000000PEB Address: 7ffd9000# 此处teb地址上方的查询结果可得知偏移位置fs:[0x18]正是TEB的基址TEB:7ffdf00012345678910111213140:000ddfs:[0x18]003b:00000018 7ffdf000 00000000 000010f4 00000f6c003b:00000028 00000000 00000000 7ffda000 000000000:000 dt _teb 0x7ffdf000ntdll!_TEB0x000 NtTib : _NT_TIB0x01c EnvironmentPointer : (null)0x020 ClientId : _CLIENT_ID# 这里保存进程与线程信息0:000 dt _CLIENT_ID 0x7ffdf000# 查看进程详细结构ntdll!_CLIENT_ID0x000 UniqueProcess : 0x0012fd0c Void# 获取进程PID0x004 UniqueThread : 0x00130000 Void# 获取线程PID上方TEB首地址我们知道是fs:[0x18],接着我们通过以下公式计算得出本进程的进程ID.在Windows系统中如果想要获取到PID进程号,可以使用NtCurrentTeb()这个系统API来实现,但这里我们手动实现该API的获取过程.获取进程PID:1234567891011121314151617181920#include stdafx.h#include Windows.hDWORDGetPid(){DWORDdwPid0;__asm{mov eax,fs:[0x18]// 获取PEB地址add eax,0x20// 加0x20得到进程PIDmov eax,[eax]mov dwPid,eax}returndwPid;}intmain(){printf(%d\n,GetPid());return0;}获取线程PID:123456789101112131415161718192021#include stdafx.h#include Windows.hDWORDGetPid(){DWORDdwPid0;__asm{mov eax,fs:[0x18]// 获取PEB地址add eax,0x20// 加0x20得到进程PIDadd eax,0x04// 加0x04得到线程PIDmov eax,[eax]mov dwPid,eax}returndwPid;}intmain(){printf(%d\n,GetPid());return0;}通过标志反调试下方的调试标志BeingDebugged是Char类型,为1表示调试状态.为0表示没有调试.可以用于反调试.12345670:000 dt _pebntdll!_PEB0x000 InheritedAddressSpace : UChar0x001 ReadImageFileExecOptions : UChar0x002 BeingDebugged : UChar0x003 SpareBool : UChar0x004 Mutant : Ptr32 Void123456789101112131415161718192021222324#include stdafx.h#include Windows.hintmain(){DWORDdwIsDebug 0;__asm{mov eax, fs:[0x18];// 获取TEBmov eax, [eax 0x30];// 获取PEBmovzx eax, [eax 2];// 获取调试标志mov dwIsDebug,eax}if(1 dwIsDebug){printf(正在被调试);}else{printf(没有被调试);}return0;}通过API反调试1234567891011121314151617#include stdio.h#include stdlib.h#include Windows.hintmain(){STARTUPINFO temp;temp.cb sizeof(temp);GetStartupInfo(temp);if(temp.dwFlags ! 1){ExitProcess(0);}printf(程序没有被反调试);return0;}反调试与绕过思路BeingDebugged 属性反调试:进程运行时位置FS:[30h]指向PEB的基地址为了实现反调试技术恶意代码通过这个位置来检查BeingDebugged标志位是否为1如果为1则说明进程被调试。1.首先我们可以使用 dt _teb 命令解析一下TEB的结构如下TEB结构的起始偏移为0x0而0x30的位置指向的是 ProcessEnvironmentBlock 也就是指向了进程环境块。1234567891011121314150:000 dt _tebntdll!_TEB0x000 NtTib : _NT_TIB0x01c EnvironmentPointer : Ptr32 Void0x020 ClientId : _CLIENT_ID0x028 ActiveRpcHandle : Ptr32 Void0x02c ThreadLocalStoragePointer : Ptr32 Void0x030 ProcessEnvironmentBlock : Ptr32 _PEB// 此处是进程环境块0x034 LastErrorValue : Uint4B0x038 CountOfOwnedCriticalSections : Uint4B0x03c CsrClientThread : Ptr32 Void0x040 Win32ThreadInfo : Ptr32 Void0x044 User32Reserved : [26] Uint4B0x0ac UserReserved : [5] Uint4B0x0c0 WOW32Reserved : Ptr32 Void只需要在进程环境块的基础上 0x2 就能定位到线程环境块TEB中 BeingDebugged 的标志此处的标志位如果为1则说明程序正在被调试为0则说明没有被调试。123456780:000 dt _pebntdll!_PEB0x000 InheritedAddressSpace : UChar0x001 ReadImageFileExecOptions : UChar0x002 BeingDebugged : UChar0x003 BitField : UChar0x003 ImageUsesLargePages : Pos 0, 1 Bit0x003 IsProtectedProcess : Pos 1, 1 Bit我们手动来验证一下首先线程环境块地址是007f1000在此基础上加0x30即可得到进程环境快的基地址007ee000继续加0x2即可得到BeingDebugged的状态 ffff0401 需要 byte1123456789101112130:000 r $teb$teb007f10000:000 dd 007f1000 0x30007f1030 007ee000 00000000 00000000 00000000007f1040 00000000 00000000 00000000 000000000:000 r $peb$peb007ee0000:000 dd 007ee000 0x2007ee002 ffff0401 0000ffff 0c400112 19f0775f007ee012 0000001b 00000000 09e0001b 0000775f梳理一下知识点我们可以写出一下反调试代码本代码单独运行程序不会出问题一旦被调试器附加则会提示正在被调试。123456789101112131415161718192021222324252627#include stdio.h#include windows.hintmain(){BYTEIsDebug 0;__asm{mov eax, dword ptr fs:[0x30]mov bl, byte ptr [eax 0x2]mov IsDebug, bl}/* 另一种反调试实现方式__asm{push dword ptr fs:[0x30]pop edxmov al, [edx 2]mov IsDebug,al}*/if(IsDebug ! 0)printf(本程序正在被调试. %d, IsDebug);elseprintf(程序没有被调试.);getchar();return0;}复制讲解如果恶意代码中使用该种技术阻碍我们正常调试该如何绕过呢如下我们只需要在命令行中执行dump fs:[30]2来定位到BeingDebugged的位置并将其数值改为0然后运行程序会发现反调试已经被绕过了。

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

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

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…