【CTF-Reverse】IDA动态调试,反调试技术

news2024/9/22 13:28:47

在本专栏前两篇文章中,带领大家讲解了逆向加密算法,AES,TEA,RC4,Base64加密算法,并带领大家识别各种密码算法特征,这一篇文章来带领大家学习在逆向过程中的动态调试:IDA动态调试,反调试技术。

一.动态调试概述

IDA作为一款强大的逆向集成工具,对于动态调试也有比较好的支持。利用IDA自带的动态调试功能可以完成大部分的动态调试任务。

  • 动态调试是一种观察程序运行状态的一种手段。

  • 逆向工程中动态调试的目的主要有:

      1. 验证静态分析的结果
      1. 观察程序运行时的数据
  • IDA调试器支持的特性

      1. 软件断点/硬件断点/条件断点/脚本断点
      1. 步入/步过/步出函数/执行到光标位置
      1. 汇编级/伪代码级/源码级 调试代码支持
      1. 寄存器/内存 读写
      1. 启动进程调试/附加调试

二.反调试介绍

动态调试是一种观察程序运行状态的一种手段。

逆向工程中的动态调试的目的主要有:验证静态分析结果和观察程序运行时的数据。

而为了防止我们对程序进行调试,程序开发者通常会设置反调试来检测自己开发的程序是否正在被调试。

但是不管是什么反调试,都有绕过方法,反调试与反反调试一直处于对抗状态,安全研究人员在其中各施手段。

下面我们将江街道Windows和Linux下常见的反调试。

1. Windows下的反调试

1. 反调试基础(结构体)

    1. 基于PEB的静态反调试

很多常见的反调试都是用这个来判断的,比如IsDebugPresent()等,那么PEB是什么呢?

Process Environment Block(进程环境块),存放进程信息的一个结构体

eg:
InheritedAddressSpace:UChar
ReadImageFileExecOptions:UChar
BeingDebugged:UChar调试标志
SpareBool:UChar
Mutant:Ptr32 Void
ImageBaseAddress:Ptr32 Void 映像基址
Ldr:Ptr_32PEB_LDR_DATA进程加载模块链表

TEB(Thread Environment Block,线程环境块)结构体也是必须要知道的,该结构体包含进程中运行线程的各种信息,进程中的每一个线程都对应着一个TEB结构体。

NtTib:——NT_TIB
EnvironmentPointer:PTR32 Void
Clientld:_CLENT_ID:当前进程ID
ActiveRpHandle:Ptr32 Void
ThreadLocalStoragePointer:Ptr32 Void
ProcessEnvironmentBlock:Ptr_32PEB 当前进程的PEB指针
LastErrorValue:Unit4B

  • 获取PEB结构体的方法:
    借助FS段寄存器所指的TEB结构体可以轻松获取进程的PEB结构体地址。TEB.ProcessEnvironmentBlock成员(偏移位+0x30h)指向PEB结构体地址,有以下两种方法可以获取PEB结构体的地址:
      1. 直接获取PEB的地址:
        MOV EAX,DWORD PTR FS:[0x30h]; //FS:[0x30h]就是AddressOfPEB
      1. 先获取TEB的地址,再通过ProcessEnvironmentBlock成员(偏移为+30h)获取PEB地址
MOV EAX,DWORD PTR FS:[0x30h];   //FS:[0x18为AddressOfTEB
MOV EAX,DWORD PTR DS:[EAX+0x30];   //DS:[EAX+0x30h]为AddressOfPEB

2. Windows下反调试的原理

    1. BeginDebugged(+0x2)

很简单,如果进程处于被调试状态,那么这个成员的值就会被设置为1,非调试状态下运行时,其值被设置为0.

IsDebuggerPresent()这个函数就是通过检测这个值来判断程序是否正在被调试

mov eax,dword ptr fs:[18];          //获取TEB地址
mov eax,dword ptr ds:[eax+30];    //通过TEB获取PEB的地址
mov eax byte ptr da:[eax+2];          //获取PEB偏移为2的结构体元素BeginDebugged,并返回这个值
retn

破解方法:在获取到PEB地址之后,使用调试器跳转到PEB地址将偏移为2的BeginDebugged成员设置为0即可。

    1. Process Heap(+0x18)

这是是利用进程堆(HEAP)进行反调试
PEB.ProcessHeap成员是指向HEAP结构体的指针

GetProcZessHeap()的实现原理:

mov eax,dword ptr fs:[0x18];   //TEB的起始地址
mov eax,dword ptr ds:[eax+30];   //PEB的地址
mov eax,dword ptr ds:[eax+18];   //PEB.Processheap的地址

获取到HEAP结构体之后,比较两个重要的成员就是Flags和ForceFlags,进程正常运行时,Heap.Flags成员(+0xC)的值为0x2,Heap.ForceFlags成员(+0x10)的值为0.进程处于被调试状态时,这些值也会随之改变。

破解方法:利用调试器获取到Heap结构体之后将Heap.Flags与Heap.ForceFlags的值重新设置为2和0即可。

    1. NtFlobalFlag(+0x68)

调试进程的时候,PEB.NtGlobalFlag成员(+0x68)的值会被设置为0x70,检测该成员就可以判断进程是否处于被调试状态。

0x70时一下Flags值按位或的结果:

FLG_HEAP_ENABLE_TAIL_CHECK(0x10)
FLG_HEAP_ENABLE_FREE_CHEVK(0x20)
FLG_HEAP_VALIDATE_PARAMETERS(0x40)

破解方法:
重新将PEB.NtGlobalFlag的值设置为0即可
这里有个技巧,如果是将运行中的进程附加到调试器时,NtGlobalFlag的值不变。

3. Windows下反调试相关函数

NtQueryInformationProcess()函数

MSDN技术文档解释NtQueryInformationProcess函数

  • 函数功能:检索有关指定进程的信息。

  • 函数原型:

__kernel_entry NTSTATUS NtQueryInformationProcess(
  [in]            HANDLE           ProcessHandle,
  [in]            PROCESSINFOCLASS ProcessInformationClass,
  [out]           PVOID            ProcessInformation,
  [in]            ULONG            ProcessInformationLength,
  [out, optional] PULONG           ReturnLength
);

参数解释:
ProcessHandle:要为其检索信息的进程句柄。
ProcessInformationClass:要检索的进程信息的类型。
ProcessInformation:指向调用应用程序提供的缓冲区的指针,函数将请求的信息写入其中。 写入的信息的大小因 ProcessInformationClass 参数的数据类型而异。
ProcessInformationLength:指向的缓冲区的大小(以字节为单位)。
ReturnLength:指向变量的指针,其中函数返回所请求信息的大小。 如果函数成功,则这是 由 ProcessInformation 参数指向的缓冲区中写入的信息的大小 (如果缓冲区太小,则为成功接收信息) 所需的最小缓冲区大小。

第二个PEOCESSINFOCLASS类型的参数反调试选用的结构体成员:

ProcessDebugPort,//0x7
ProcessDebugObjectHandle,//0x1E
PrecessDebugFlags, //0x1F

  • ProcessDebugPort(0x7):
    当一个进程处于调试状态时,系统就会为它分配一个调试窗口(DebugPort),当PEOCESSINFOCLASS的ProcessDebugPort的值为7,调用NtQueryInformationProcess就可以获取调试端口,如果没有调试则返回0.

  • CheckRemoteDebuggerPresent()函数:

  • MSDN官方文档解释CheckRemoteDebuggerPresent函数
    用来检测进程是否处于被调试状态,CheckRemoteDebuggerPresent()函数不仅可以用来检测当前进程,还可以用来检测其他进程是否处于被调试状态。查看该API,实际上调用了NtQueryInformationProcess

  • ProcessDebuggerObjectHandel(0x1E)
    调试进程时会生成调试对象(Debug Object)。函数的第二个参数值为ProcessDebug-ObjectHandle(0x1E)时,调用函数后通过第三个擦拭农户就能获取调试对象句柄。进程处于调试状态时,调试对象句柄的值就存在,若进程处于非调试状态,则调试对象句柄值为NULL。

  • ProcessDebugFlags(0x1F)
    检测DebugFlags(调试标志)的值来判断进程是否处于被调试状态,函数的第二个参数设置为这个是,调用函数后通过第三个参数即可获取调试标志的值,为0则进程处于被调试状态,为1,则进程处于非调试状态。

破解方法:
对该哈桑农户在第二个参数为特定的值的时候返回的第三个参数的值进行操作,特定的参数值就是前面提起的那个三个,若只是少调用几次API,那么我们直接手动操作输出值(先找到调用NtQueryInformationProcess之前压入的第三个参数的地址,跳转到对应地址,然后调用完之后将其值修改为非调试的值,如果是多次的话,我们就可以使用API钩取这个函数,然后在钩取函数中根据第二个参数的值,来修改第三个参数在返回的值。

4. 基于环境检测的反调试技术

1. NtQuerySystemInformation()

系统函数,用来获取当前运行的多种OS信息
这里给出MSDN官方文档的解释,但是该函数好像已经过时。MSDN官方文档
环境检测反调试技术1

2. NtQueryObject()函数

这里给出MSDN官方文档地址,大家可以过去看看:官方文档
类似的给第二个参数赋予某个值,调用API后,相关信息的结构体指针就会被返回到第三个参数中。

破解方法:
在调用ntdll.ZwQueryObject()API的时候,查看栈可以看到压入的第二个参数的值,我们将这个值改为0之后,就无法探测到调试了。
也可以直接钩取ntdll.ZwQueryObject这个API,修改输入值或修改结果值也能不被探测到。

5.其他检测

  • GetForegroundWindow和GetWindowText
    GetForgroundWindow:获取一个前台的窗口句柄(用户当前工作的窗口)。
    GetWindowText:将指定窗口的标题栏(如果有的话)的文字拷贝到缓冲区,如果指定的窗口是一个空间,那么该控件的text属性将被拷贝到缓冲区。但是Get WindowText不饿能取回其他程序中控件的text。
    之后再检测字符串:
    其他检测方法
  • 时钟检测
    时钟检测
  • TLS回调函数
    TLS1
    TLS2
    这篇文章就分享到这里,逆向技术还是需要我们多动手实战的,希望我们共同进步!!!

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

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

相关文章

5SHY3545L0016 3BHB020720R0002可控硅模块IGCT

​ 5SHY3545L0016 3BHB020720R0002可控硅模块IGCT 5SHY3545L0016 3BHB020720R0002可控硅模块IGCT 1) dcs系统往往具有丰富的自诊断功能。根据报警,可以直接找到故障点,并且还可通过报警的消除来验证维修结果。 2) 通信接头接触不良会引起通信故障,确认通信接头接触不良后,可以…

ssm企业网站的设计与实现-计算机毕设 附源码82639

ssm企业网站的设计与实现 摘 要 科技进步的飞速发展引起人们日常生活的巨大变化,电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流,人类发展的历史正进入一个新时代。在现实运用中…

docker安装sentinel

关于如何安装docker 可以看我的这篇文章 ​​​​​​http://t.csdn.cn/3jKPm 第一步:拉取镜像 docker pull bladex/sentinel-dashboard 这里不加版本号默认拉取最新版本 第二步:查看已经安装的镜像 docker images 看到这个就是安装好了 第三步&…

基于Java+Swing实现飞机大战游戏

基于JavaSwing实现飞机大战游戏 一、系统介绍二、功能展示三、其他系统四、获取源码 一、系统介绍 基于Java的飞机大战游戏主要需要我方飞机和敌方飞机,还有子弹,特殊nPC,开始背景,结束背景,以及背景音乐。我方飞机可…

chatGPT对企业的发展有什么影响

ChatGPT目前正在全世界范围内掀起风暴,成为炙手可热的一个名词。作为基于人工智能的工具的最新产品,目前ChatGPT呈现给我们的似乎只是足够有趣,且从目前已知的信息来看,它似乎还没有任何商业运作相关的计划,大多应用聚…

webrtc stun协议

STUN(Simple Traversal of User Datagram Protocol Through Network Address Translators),即简单的用UDP穿透NAT,是个轻量级的协议,是基于UDP的完整的穿透NAT的解决方案。它允许应用程序发现它们与公共互联网之间存在…

死磕AI大模型网络,鹅厂出招了!

2023年,以ChatGPT为代表的AIGC大模型全面崛起,成为了整个社会关注的焦点。 大模型表现出了强悍的自然语言理解能力,刷新了人们对AI的认知,也掀起了新一轮的“算力军备竞赛”。 大家都知道,AIGC大模型的入局门槛是很高的…

西门子S7-1200系列PLC输入/输出接线

西门子S7-1200是一款紧凑型、模块化的PLC,可完成简单逻辑控制、高级逻辑控制、HMI 和网络通信等任务。下面分享S7-1200系列PLC输入/输出接线图给大家。 CPU 1211C 接线图 CPU 1211C AC/DC/继电器 (6ES7 211-1BE40-0XB0) ① 24 VDC 传感器电源 ② 对于漏型输入将负…

KingbaseES的学习心得和知识总结(三)|Kingbase数据库性能调优工具sys_kwr插件的简介和使用

目录结构 注:提前言明 本文借鉴了以下博主、书籍或网站的内容,其列表如下: 1、KingbaseES V8产品文档首页,点击前往 2、Kingbase 文档库,点击前往 3、北京人大金仓信息技术股份有限公司 官网首页,点击前往…

单片机——时间表程序加仿真

一、程序 #include <REG52.h> #include "main.h" sbit key1P3^0; sbit key2P3^1; sbit key3P3^2; sbit key4P3^3; sbit SWP1^0; unsigned char code SEG[]{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x8E,0x86}; unsigned char i,cp,cp1,flash,key…

Python小白必看

Python学习计划&#xff1a; 1.先学习Python基础知识&#xff0c;包括&#xff1a; 变量、数据类型、运算符条件语句、循环语句函数、模块、包 2.掌握Python的常用库和框架&#xff0c;例如&#xff1a; NumPy&#xff1a;用于科学计算、数据分析等Pandas&#xff1a;用于数…

Vue表单验证,表单填写完成无法通过rules验证问题

表单校验使用的是ElementUI官网的表单校验规则&#xff0c;但是表单在填写完成后还是通不过校验&#xff0c;这就需要进行相应的检查 1.检查rules与ref&#xff0c;rules与ref的名字可以随便定义&#xff0c;但是要确保在这块写的与在data中定义的一致 2.检查<el-form-ite…

Pandas 解决保存H5文件发生异常问题

代码&#xff1a; #保存h5文件 #指定文件路径和读写模式 hdpd.HDFStore(mystock.h5,w) #将my的数据存入到hd中 hd[data]my #关闭文件 hd.close() 发生异常&#xff1a; 原因&#xff1a;缺少pytables 解决&#xff1a; 执行命令 pip install tables 安装好之后重启jupyter内核…

2023年1月至4月天猫平台美妆品类销售数据分析

如今&#xff0c;随着人们消费观念的突破&#xff0c;越来越多的人用美妆来诠释个性表达&#xff0c;美丽经济获得更多关注&#xff0c;化妆品消费理念逐渐增强&#xff0c;因此&#xff0c;美妆市场也形成了较大的规模。 根据鲸参谋电商数据显示&#xff0c;2023年1月至4月&am…

争取一文说透NuGet

一、NuGet是什么? NuGet是一个为大家所熟知的Visual Studio扩展&#xff0c;通过这个扩展&#xff0c;开发人员可以非常方便地在Visual Studio中安装或更新项目中所需要的第三方组件&#xff0c;同时也可以通过NuGet来安装一些Visual Studio的插件等。 二、官网&#xff1a;…

驱动开发:内核读写内存多级偏移

让我们继续在《内核读写内存浮点数》的基础之上做一个简单的延申&#xff0c;如何实现多级偏移读写&#xff0c;其实很简单&#xff0c;读写函数无需改变&#xff0c;只是在读写之前提前做好计算工作&#xff0c;以此来得到一个内存偏移值&#xff0c;并通过调用内存写入原函数…

Qt绘图高级编程-绘制文本

注意&#xff1a;以下代码是在paintEvent函数中使用的&#xff0c;坐标是在文本的左下角。 1、设置字体样式 /*-----------1、设置字体样式-----------*///设置画家写字的字体//字体名&#xff0c; 字体大小&#xff0c;粗体&#xff0c;是否斜体QFont font( "楷体"…

芝奇幻锋戟Z5 RGB DDR5-7200 24GB内存评测:稳上7800MHz、温度只有56度

一、前言&#xff1a;7200MHz CL36高频内存仅需1.35V电压 在DDR4年代&#xff0c;三星B-Die是当之无愧的超频王者&#xff0c;而今DDR5已然成为主流&#xff0c;大家公认的最好超频的颗粒是SK海力士A-Die。 但并不是每一款采用了海力士A-Die颗粒的内存条都会有强悍的超频能力&a…

B+数的设计步骤

1.节点的结构&#xff08;如下图&#xff09; &#xff08;1&#xff09;键值对--key是标识&#xff1b;value是存储的具体数据 &#xff08;2&#xff09;节点的子节点--存储的是具体的子节点 &#xff08;3&#xff09;节点的后节点--标记后一个节点 &#xff08;4&#xff0…

9 MFC CFileDialog

// SystemWndDlg.cpp: 实现文件 //#include "pch.h" #include "framework.h" #include "SystemWnd.h" #include "SystemWndDlg.h" #include "afxdialogex.h"#ifdef _DEBUG #define new DEBUG_NEW #endif// CSystemWndDlg 对…