BeingDebugged 标志位

一、通过检测 BeingDebugged 标志位

在调试过程中,当被调试进程被调试器附加后,被调试进程中的所有线程的 PEB 结构中的 BeingDebugged 位会被置为 1,因此我们可以通过检测该标志位来检测是否有调试器进行附加。

我们首先通过 windbg 软件来看一下这个标志位位于进程的哪个地方,我们首先通过 windbg 附加任意一个 32 位或 64 位程序,然后输入命令显示当前进程中的所有线程:

~

得到如下结果:

我们任选一个线程,然后查看它的 TEB 结构:

dt ntdll!_TEB 0x000000b3`1cf88000

结果如下:

我们可以从一个线程的 TEB 结构中偏移为 0x60 的位置找到其 PEB 结构地址,接下来继续通过命令来解析该线程的 PEB

dt ntdll!_PEB 0x000000b3`1cf87000

结果如下:

可以看到,BeingDebugged 标志位于 PEB 结构体中偏移为 0x2 的位置,事实上这个标志位在其他 Windows 版本的系统上也位于这个位置,很少变动,我们演示的进程为 64 位的,对于 32 位的进程也是同理。

1 通过 IsDebuggerPresent 函数来检测调试器

Windows 系统提供了一个 API 来专门对该标志位进行检测,那就是 IsDebuggerPresent 函数,我们来看一下这个函数的底层汇编实现,首先来看一下 32 位的系统是如何实现的。

我们通过 x64dbg 来加载一个 32 位的程序,并跳转到该函数的实现:

从上面的截图中我们可以得到一些信息,首先,这个 IsDebuggerPresent 函数位于 kernelbase.dll 中,其次,第一行汇编代码先从 fs:[30] 中取值,在 32 位程序中,fs 段寄存器保存的是当前线程的 TEB 地址,因此该汇编指令其实是直接取当前线程的 TEB 结构中偏移为 0x30 的值,这个值其实就是 32 位程序中的 PEB 结构地址,然后再通过 PEB 结构地址偏移 0x2,得到了 BeingDebugged 标志位并返回。

那么 64 位的程序呢?我们上面通过 windbg 分析过,64 位程序中,PEBTEB 结构中偏移为 0x60 的位置,只不过 64 位程序中保存 TEB 结构地址的段寄存器为 gs,我们用 x64dbg 随便打开一个 64 位程序进行验证:

分析完 IsDebuggerPresent 函数的原理后,我们可以直接编写 C 语言代码调用 API 函数进行检测,也可以自己编写汇编代码来进行检测,接下来我们以 C 语言代码来进行示范:

#include <stdio.h>
#include <Windows.h>

int main()
{
	if (IsDebuggerPresent())
	{
		printf("检测到调试器\r\n");
	}
	else
	{
		printf("未检测到调试器\r\n");
	}

	system("pause");
}

用调试器打开该程序,结果如下:

posted @ 2025-02-12 13:12  lostin9772  阅读(7)  评论(0)    收藏  举报