当前位置: 首页 > article >正文

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

反调试技术的实现方式有很多最简单的一种实现方式莫过于直接调用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然后运行程序会发现反调试已经被绕过了。

相关文章:

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

反调试技术的实现方式有很多,最简单的一种实现方式莫过于直接调用Windows系统提供给我们的API函数,这些API函数中有些专门用来检测调试器的,有些则是可被改造为用于探测调试器是否存在的工具,多数情况下,调用系统API函…...

从防御者视角看ARP欺骗:除了静态绑定,你的内网还能如何加固?

从防御者视角看ARP欺骗:内网安全加固实战指南 当你在深夜收到内网异常告警时,是否曾想过——那个看似平静的局域网里,可能正有人通过ARP欺骗监听所有通信?ARP协议作为局域网通信的"翻译官",其设计缺陷让攻击…...

科研绘图效率翻倍:用ArcGIS Pro快速搞定论文中的研究区位置示意图

科研绘图效率革命:ArcGIS Pro智能工作流打造学术级研究区示意图 在赶论文deadline的前夜,你是否还在为一张合格的研究区示意图熬夜调整比例尺?当审稿人要求补充流域位置示意图时,是否还在传统GIS软件中逐个菜单寻找功能&#xff1…...

MAUI 嵌入式 Web 架构实战(七) 构建设备实时通信与控制系统

springboot自动配置 自动配置了大量组件,配置信息可以在application.properties文件中修改。 当添加了特定的Starter POM后,springboot会根据类路径上的jar包来自动配置bean(比如:springboot发现类路径上的MyBatis相关类&#xff…...

又一个开源的逆向 Qwen API 项目, 实现无限token还支持AI生图功能!

又一个开源的逆向 Qwen API 项目, 实现无限token还支持AI生图功能! 关键词: Qwen API、AI API网关、Docker部署大模型、LLM中转服务、AI接口调用、Cloud Code 调用AI 最近在做 AI 工具接入时,发现一个很现实的问题: 不同平台的模型接口调用方…...

别再只盯着ADC位数了!采样保持电路里这个‘电容’选多大,直接决定你的信噪比

采样电容选型:被工程师忽视的信噪比杀手 当新手工程师第一次设计数据采集系统时,往往会把全部注意力放在ADC的位数上——16位一定比12位好,24位更是"高保真"的代名词。但很少有人告诉你,即使选用最顶级的ADC芯片&#…...

GetQzonehistory:QQ空间历史数据备份的完整指南

GetQzonehistory:QQ空间历史数据备份的完整指南 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否担心QQ空间中的珍贵回忆会随着时间流逝而消失?GetQzonehis…...

收藏!2026年版AI发展全解析|程序员小白必看,看懂趋势抓住大模型时代红利

本文完整复盘2026年AI全周期发展脉络、当下核心行业变革趋势与中长期落地方向,清晰拆解AI从辅助工具进阶为人类智能合作伙伴的完整蜕变逻辑。深度解读编排者经济、技能蒸发、静默生产等当下爆火的AI全新发展概念,结合大模型、AI Agent、插件生态等2026前…...

分钟搞懂深度学习AI:实操篇:池化层

1. 流图:数据的河流 如果把传统的堆叠面积图想象成一块块整齐堆叠的积木,那么流图就像一条蜿蜒流淌的河流,河道的宽窄变化自然流畅,波峰波谷过渡平滑。 它特别适合展示多个类别数据随时间的变化趋势,尤其是当你想强调整…...

从‘听’到‘看’:语音识别/音频降噪项目中,频谱、功率谱、语谱图到底该怎么选?避坑指南

从‘听’到‘看’:语音信号处理中的频域分析工具实战指南 当你第一次将麦克风捕捉到的声波转化为数字信号时,那串看似杂乱无章的数值背后隐藏着怎样的秘密?在语音识别、降噪处理等项目中,选择合适的频域分析工具往往决定了整个系…...

医学图像分割模型‘瘦身’实战:如何用UNet++的深度监督功能,在推理速度与精度间找到最佳平衡点

医学图像分割模型优化实战:UNet深度监督与剪枝策略全解析 在医疗AI领域,实时性和准确性往往是一对难以调和的矛盾。临床医生需要快速获取分割结果辅助诊断,而放射科图像的高精度要求又让模型复杂度居高不下。UNet通过创新的嵌套架构和深度监督…...

从ARM架构到台积电工艺:手把手教你读懂手机芯片发布会上的‘黑话’

从ARM架构到台积电工艺:手把手教你读懂手机芯片发布会上的‘黑话’ 每次手机新品发布会,厂商总爱用一堆专业术语轰炸观众——"X3超大核性能提升25%"、"全球首发4nm工艺"、"LPDDR5X内存带宽翻倍"。这些看似高大上的参数&a…...

技术演讲从入门到精通:如何让台下开发者为你鼓掌?

在软件测试的职业生涯中,我们常常需要展示自己的工作成果、推广新的测试方法、或者在技术社区分享经验。无论是团队内部的分享会、跨部门的技术评审,还是在行业大会上的主题演讲,一场精彩的技术演讲,不仅能清晰地传递信息&#xf…...

保姆级教程:用Fast DDS(ROS2同款)在Ubuntu上快速搭建你的第一个DDS通信Demo

从零构建DDS通信系统:Fast DDS实战指南与车载通信深度解析 在智能汽车与分布式系统开发领域,数据分发服务(DDS)正成为新一代通信架构的核心支柱。不同于传统点对点通信模式,DDS以数据为中心的发布/订阅机制&#xff0…...

3个突破性功能让B站视频管理效率提升300%:BiliTools跨平台工具箱深度解析

3个突破性功能让B站视频管理效率提升300%:BiliTools跨平台工具箱深度解析 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bili…...

告别样本失衡:用PyTorch手把手实现Focal Loss,让你的目标检测模型更关注‘难啃的骨头’

用Focal Loss解决目标检测中的样本失衡难题:PyTorch实战指南 当你盯着训练日志里那些"虚高"的准确率指标时,是否注意到模型对小目标、遮挡目标的识别率始终低迷?这很可能不是数据标注的问题,而是经典交叉熵损失函数在面…...

别再乱画UML了!用包图整理你的用例图和类图,让项目结构一目了然

用UML包图重构项目架构:从混乱到清晰的实战指南 当你的代码库膨胀到几十万行,当每次需求变更都引发连锁反应,当新成员需要三个月才能摸清模块边界——是时候重新审视项目的组织结构了。UML包图就像软件架构的GPS导航系统,它能将散…...

别再死磕GPIO了!用STM32的PWM+DMA驱动WS2812灯带,CPU占用率直降90%

STM32实战:PWMDMA驱动WS2812灯带的极致性能优化 在智能家居和物联网设备开发中,绚丽的灯光效果往往能大幅提升产品体验。但当你用STM32的GPIO模拟时序驱动WS2812灯带时,是否遇到过这些困扰:CPU占用率飙升导致传感器数据采集延迟、…...

别再死记硬背了!用这5个NIFI处理器组合,轻松搞定90%的数据流转场景

5组NIFI处理器黄金搭档:解决90%数据流转难题的实战方案 在数据流转的世界里,Apache NiFi就像一把瑞士军刀,但真正的高手都知道,单靠一个处理器很难完成复杂任务。本文将揭示五组经过实战检验的处理器组合,它们能像精密…...

玻尔兹曼脑伦理:测试从业者的哲学镜像与技术思辨

一个来自物理学的“Bug”报告在软件测试的日常中,我们习惯于追踪缺陷、验证逻辑、确保系统行为符合预期。我们深信,在一个确定性的输入下,系统应给出确定性的输出,世界的运行建立在可观测、可复现的规律之上。然而,物理…...

超自动化:RPA+AI Agent 深度融合

超自动化:RPAAI Agent 深度融合 📝 本章学习目标:本章展望未来趋势,帮助读者把握AI Agent发展方向。通过本章学习,你将全面掌握"超自动化:RPAAI Agent 深度融合"这一核心主题。 一、引言&#xf…...

DS4Windows终极指南:如何让PlayStation手柄在Windows电脑上完美运行

DS4Windows终极指南:如何让PlayStation手柄在Windows电脑上完美运行 【免费下载链接】DS4Windows Like those other ds4tools, but sexier 项目地址: https://gitcode.com/gh_mirrors/ds/DS4Windows 还在为PC游戏无法识别你的PlayStation手柄而烦恼吗&#x…...

3个关键步骤解决Firefox中GM_addElement脚本兼容性问题

3个关键步骤解决Firefox中GM_addElement脚本兼容性问题 【免费下载链接】scriptcat ScriptCat, a browser extension that can execute userscript; 脚本猫,一个可以执行用户脚本的浏览器扩展 项目地址: https://gitcode.com/gh_mirrors/sc/scriptcat Script…...

电路分析‘偷懒’神器:互易定理在求解复杂电阻网络时的实战技巧与避坑指南

电路分析‘偷懒’神器:互易定理在求解复杂电阻网络时的实战技巧与避坑指南 深夜的实验室里,老张盯着电路板上密密麻麻的电阻网络叹了口气。这个由47个电阻组成的测试电路,客户要求明天一早提交关键节点的电压分析报告。正当他准备熬夜列方程…...

Stable Diffusion WebUI 本地部署与创作:从零到出图

文章目录 Stable Diffusion WebUI 本地部署与创作:从零到出图 一、为什么选 Stable Diffusion 二、环境搭建 2.1 硬件 2.2 安装 2.3 GPU 加速 三、第一次出图 3.1 WebUI 界面分区 3.2 Prompt 3.3 参数推荐 四、模型与 LoRA 4.1 Checkpoint 模型 4.2 LoRA 五、ControlNet 精准控…...

前列腺 MRI-病理 3D 配准:弹性形变场 + 体素重建全流程

文章目录 前列腺 MRI-病理 3D 配准:弹性形变场 + 体素重建全流程 一、任务 二、环境 三、数据 3.1 结构 3.2 MRI 预处理 四、模型 4.1 弹性配准网络 4.2 损失函数 五、训练 六、评估 七、消融 八、调试 九、总结 代码链接与详细流程 购买即可解锁1000+YOLO优化文章,并且还有海…...

Linux CPUfreq动态调频技术与电源管理优化

1. Linux CPUfreq动态电压频率调节技术解析在嵌入式系统和移动设备开发中,电源管理一直是工程师面临的核心挑战之一。我曾参与过一个基于TI OMAP处理器的智能终端项目,当设备在播放视频时,电池续航只能维持3小时,而通过合理配置CP…...

高端化战略落地,爱芯元智如何撬动全球智驾市场?

2026年,智能汽车芯片的竞技场已经从“拼算力参数”全面转向“拼量产落地与商业生态”。在2026北京车展上,全球领先的AI推理系统级芯片(SoC)供应商爱芯元智(0600.HK)不仅正式宣告了智能汽车芯片产品线的高端…...

空间权重矩阵选哪个?用Stata实操对比邻接、反距离和经济地理矩阵的差异

空间权重矩阵选择指南:Stata实战中的邻接、反距离与经济地理矩阵对比 当研究者面对空间数据分析时,权重矩阵的选择往往成为关键决策点。不同的矩阵构建方法会直接影响空间自相关检验和空间回归模型的结果解读。本文将深入探讨三种主流空间权重矩阵——邻…...

SZBOX S100迷你主机评测:双4K输出与低功耗设计

1. SZBOX S100迷你主机开箱与硬件解析当拆开SZBOX S100的包装时,这台仅7.17.14.6厘米的金属机身给人第一印象就是难以置信的紧凑。全金属外壳不仅提供了良好的散热基础,磨砂表面处理也避免了指纹残留的问题。包装内除了主机本体,还包含一个US…...