Web View
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
### Windows 下有哪些常用的反调试技术
|
||||
|
||||
**1. 基于 Windows API 的反调试**
|
||||
|
||||
这是最常见、最容易实现的反调试技术,利用 Windows 系统提供的特定函数来查询进程状态
|
||||
|
||||
- **`IsDebuggerPresent`:** 这是最直接、最经典的 API。它位于 `kernel32.dll` 中,会检查 **进程环境块 (PEB)** 中的 `IsDebugged` 标志位。如果该位被设置为 `1`,函数就返回 `TRUE`。攻击者只需要简单地调用这个函数,然后根据返回值决定是否执行恶意代码
|
||||
- **`CheckRemoteDebuggerPresent`:** 这个 API 用来检查**另一个进程**是否正在被调试。它通常用于一个父进程检查其子进程是否被调试。攻击者可以启动一个子进程,然后父进程不断调用此 API 来监视子进程的状态
|
||||
- **`OutputDebugString`:** 这个函数原本用于向调试器输出调试信息。如果程序在没有调试器附加的情况下调用此函数,并随后调用 `GetLastError`,返回的错误码通常是 `ERROR_NOT_ENOUGH_MEMORY`(`0x08`)。如果返回其他值,则很可能存在调试器
|
||||
- **`NtQueryInformationProcess`:** 这是一个更底层的、功能强大的未公开(undocumented)API。通过查询 `ProcessDebugPort`、`ProcessDebugObject` 或 `ProcessDebugFlags` 等信息,可以精确地判断程序是否被调试。这是许多高级反调试技术的基石,因为不像 `IsDebuggerPresent`,它更难被简单地 Hook 或篡改
|
||||
|
||||
**2. 基于异常和 SEH(结构化异常处理) 的反调试**
|
||||
|
||||
调试器在处理异常时与正常程序有不同的行为,这为反调试提供了可乘之机
|
||||
|
||||
- **`INT 3` 断点:** 调试器通常通过 `INT 3` (opcode `0xCC`) 指令来设置软件断点。攻击者可以在代码中故意插入一个 `INT 3` 指令,并设置自己的异常处理器。如果程序在执行 `INT 3` 后进入了预设的异常处理器,说明没有调试器存在(因为调试器会捕获 `INT 3` 并暂停程序)。如果程序没有进入异常处理器,就说明有调试器存在
|
||||
- **`Trap Flag (TF)` 检测:** 当调试器设置了硬件断点或启用单步执行时,CPU 的 EFLAGS 寄存器中的 `Trap Flag` 会被设置。攻击者可以通过内联汇编代码来检查这个标志位,判断是否正在进行单步调试
|
||||
- **利用 `VEH`(向量化异常处理):** `VEH` 是比 `SEH` 更早被调用的异常处理机制。攻击者可以在 `VEH` 中设置反调试逻辑,因为它更难被调试器忽略或绕过
|
||||
|
||||
**3. 基于时间差和指令计数的反调试**
|
||||
|
||||
调试器在执行单步调试或设置断点时,会引入额外的延迟。正常程序可以利用这个时间差来检测调试器的存在
|
||||
|
||||
- **`RDTSC` (Read Time-Stamp Counter):** 这是一个 CPU 指令,用于读取 CPU 的时间戳计数器。攻击者可以在代码中的两个点调用 `RDTSC`,并计算两次调用之间的时间差。如果这个时间差异常地长,很可能是因为调试器在单步执行或处理断点
|
||||
- **`QueryPerformanceCounter`:** 这是一个高精度的 Windows API。与 `RDTSC` 类似,攻击者可以调用两次这个 API 并计算时间差。如果时间差超过一个阈值,则认为存在调试器
|
||||
- **线程休眠检测:** 当程序进入休眠状态时,调试器通常会唤醒它以便继续执行。攻击者可以调用 `Sleep()` 函数,然后检查实际休眠的时间是否与期望的时间相符。如果实际休眠时间比期望的短,说明调试器可能干预了线程的运行
|
||||
|
||||
**4. 基于进程和线程状态的反调试**
|
||||
|
||||
调试器通常会改变被调试进程或线程的某些状态
|
||||
|
||||
- **父进程检测:** 正常程序通常由 `explorer.exe` 或 `cmd.exe` 等合法进程启动。而调试器会成为被调试进程的父进程。攻击者可以调用 `NtQueryInformationProcess` 或 `CreateToolhelp32Snapshot` 等 API,检查父进程 ID (`PPID`) 是否是已知的调试器进程 ID,或者干脆检查 `PPID` 是否不等于 `explorer.exe` 的 `PPID`
|
||||
- **线程上下文检测:** 调试器会修改被调试线程的寄存器和线程上下文。攻击者可以检查 `TEB` (Thread Environment Block) 中与调试相关的字段,或者检查线程的上下文信息是否被篡改
|
||||
|
||||
**5. 其他高级反调试技术**
|
||||
|
||||
- **调试器检测点:** 在代码中故意创建多个 `INT 3` 断点或 `CALL` 调试 API 的分支,但让程序在没有调试器的情况下跳过这些分支。当调试器附加时,这些分支被执行,从而暴露调试器的存在
|
||||
- **自修改代码:** 在程序运行时修改自己的代码,例如用 `NOP` 指令覆盖反调试代码,或用 `jmp` 指令跳转到真正的逻辑代码。调试器很难追踪和分析这种行为,因为其静态分析视图与运行时视图不符
|
||||
- **反汇编器检测:** 有些技术不仅针对调试器,还针对 IDA Pro 等反汇编工具。例如,在代码中插入一些特殊指令序列,这些序列在 CPU 上执行正常,但在反汇编器中会被错误地解析,导致代码流被混淆
|
||||
Reference in New Issue
Block a user