首页 > 其他分享 >8.2 BeingDebugged

8.2 BeingDebugged

时间:2023-09-26 12:22:25浏览次数:39  
标签:8.2 00000000 BeingDebugged mov 调试 进程 PEB

BeingDebugged 是Windows系统PEB结构体中的一个成员,它是一个标志位,用于标识当前进程是否正在被调试。BeingDebugged的值为0表示当前进程未被调试,值为1表示当前进程正在被调试。由于BeingDebugged是在PEB结构体中存储的,因此可以通过访问PEB结构体来获取BeingDebugged的值。恶意软件可以使用BeingDebugged来判断自己是否正在被调试,以此来防止被反病毒工程师或调试程序进行分析。反病毒工程师们也可以通过检查BeingDebugged的值来判断程序是否正被调试从而进行恶意软件的检测和分析。

进程在运行时,位置FS:[30h]指向PEB的基地址,为了实现反调试,恶意代码通过这个位置来检查BeingDebugged标志位是否为1,如果为1则说明进程被调试。

首先我们可以使用dt _teb命令解析一下TEB的结构,如下TEB结构的起始偏移为0x0,而0x30的位置指向的是ProcessEnvironmentBlock也就是指向了进程环境块PEB。

0:000> dt _teb
ntdll!_TEB
   +0x000 NtTib            : _NT_TIB
   +0x01c EnvironmentPointer : Ptr32 Void
   +0x020 ClientId         : _CLIENT_ID
   +0x028 ActiveRpcHandle  : Ptr32 Void
   +0x02c ThreadLocalStoragePointer : Ptr32 Void
   +0x030 ProcessEnvironmentBlock : Ptr32 _PEB       // PEB 进程环境块

只需要在进程环境块的基础上+0x2就能定位到线程环境块TEBBeingDebugged的标志,此处的标志位如果为1则说明程序正在被调试,为0则说明没有被调试。

0:000> dt _peb
ntdll!_PEB
   +0x000 InheritedAddressSpace : UChar
   +0x001 ReadImageFileExecOptions : UChar
   +0x002 BeingDebugged    : UChar
   +0x003 BitField         : UChar
   +0x003 ImageUsesLargePages : Pos 0, 1 Bit
   +0x003 IsProtectedProcess : Pos 1, 1 Bit

我们手动来验证一下,首先线程环境块地址是007f1000,在此基础上加0x30即可得到进程环境快的基地址,位置FS:[0x30]指向PEB的基地址,007ee000继续加0x2即可得到BeingDebugged的状态ffff0401此处我们只需要看byte位是否为1即可。

0:000> r $teb
$teb=007f1000

0:000> dd 007f1000 + 0x30
007f1030  007ee000 00000000 00000000 00000000
007f1040  00000000 00000000 00000000 00000000

0:000> r $peb
$peb=007ee000

0:000> dd 007ee000 + 0x2
007ee002  ffff0401 0000ffff 0c400112 19f0775f
007ee012  0000001b 00000000 09e0001b 0000775f

有了上述知识点的理解,写出一段反调试代码来将变得很容易,如下代码片段所示,如果独立运行则会提示正常程序,一旦进程被调试则会提示异常,此处分别使用三段实现方式,读者可通过向IsDebug()传入不同的参数启用。

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

// 判断程序是否被调试
int IsDebug(DWORD x)
{
    BYTE Debug = 0;

    if (x == 1)
    {
        __asm
        {
            mov eax, dword ptr fs : [0x30]
            mov bl, byte ptr[eax + 0x2]
            mov Debug, bl
        }
    }
    if (x == 2)
    {
        __asm
        {
            push dword ptr fs : [0x30]
            pop edx
            mov al, [edx + 2]
            mov Debug, al
        }
    }
    if (x == 3)
    {
        __asm
        {
            mov eax, fs:[0x18]         // TEB Self指针
            mov eax, [eax + 0x30]      // PEB
            movzx eax, [eax + 2]       // PEB->BeingDebugged
            mov Debug, al
        }
    }
    return Debug;
}

int main(int argc, char* argv[])
{

    if (IsDebug(1) && IsDebug(2) && IsDebug(3))
    {
        printf("[-] 进程正在被调试器调试 \n");
    }
    else
    {
        printf("[*] 正常运行 \n");
    }

    system("pause");
    return 0;
}

上述程序被运行,一旦处于调试器模式则会触发被调试的告警,如果恶意代码中使用该种技术阻碍我们正常调试,只需要在x64dbg的命令行中执行dump fs:[30]+2来定位到BeingDebugged()的位置,并将其数值改为0然后运行程序,会发现反调试已经被绕过了。

这里补充一个知识点,通过运用IsDebuggerPresent()调试函数同样可实现此类功能,IsDebuggerPresent 返回一个布尔值,用于指示调用进程是否正在被调试器调试。该函数不接受参数,并且如果进程正在被调试,则返回 TRUE,否则返回 FALSE。该函数的实现原理同样应用了BeingDebugged标志位的检测方法。

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

DWORD WINAPI ThreadProc(LPVOID lpParam)
{
    while (TRUE)
    {
        // 检测用ActiveDebugProcess()来创建调试关系
        if (IsDebuggerPresent() == TRUE)
        {
            printf("当前进程正在被调试 \r\n");

            // 产生int3异常
            DebugBreak();
            break;
        }
        Sleep(1000);
    }
    return 0;
}

int main(int argc, char * argv[])
{
    HANDLE hThread = CreateThread(0, 0, ThreadProc, 0, 0, 0);
    if (hThread == NULL)
    {
        return -1;
    }

    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);

    system("pause");
    return 0;
}

上述代码中我们通过使用CreateThread()函数创建了一个子线程用于每隔1000毫秒就检测一次是否被调试了,如果被调试则直接产生一个DebugBreak()也就是int3断点,其反调试效果如下图所示;

本文作者: 王瑞
本文链接: https://www.lyshark.com/post/800bf906.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

标签:8.2,00000000,BeingDebugged,mov,调试,进程,PEB
From: https://www.cnblogs.com/LyShark/p/17729824.html

相关文章

  • 升级PHP8.2
    1.官网下载PHP压缩包:  页面上有不同的PHP版本,这里我们下载的是VS16x64NonThreadSafe: php-8.2.10-nts-Win32-vs16-x64.zip  官网地址2.解压缩包  将下载的压缩包解压到D:\phpstudy_pro\Extensions\php并重命名为php8.2.10nts3.修改配置文件  3.1复制一份p......
  • wzOI 2023.8.24 模拟赛(附树的直径和三分法)
    2023-08-2815:53:53$$A$$典型错误一知半解看样例型:如果该队某个数组的值比最大值大就算入答案。上第一次厕所前我的思路:开局\(30\)分钟。显然,我并不需要有一个数值最大才能赢,我只需要其中一个数值比其中一个数值比其中一个数值最大的那个要大的队要大即有可能获胜......
  • 8.27-9.8暑假总结报告
    本周我快开学了准备好进入开学的状态,作息上开始提前进入睡眠状态。周六我进行了大数据学习,虚拟机的时间到了我在网上找了一个解决好了周一我晚上睡觉突然感觉不舒服,身体突然发晕,从此以后我精神失常,严重失眠状态,呼吸不顺畅,头晕本周我身体出现反常,我去医院检查,检查的结果都是正常......
  • 文心一言 VS 讯飞星火 VS chatgpt (86)-- 算法导论8.2 3题
    三、用go语言,假设我们在COUNTING-SORT的第10行循环的开始部分,将代码改写为:10forj=1toA.length试证明该算法仍然是正确的。它还稳定吗?文心一言:首先,让我们先明确COUNTING-SORT算法的基本思想。COUNTING-SORT是一种线性时间复杂度的排序算法,它适用于对一定范围内的整数......
  • 文心一言 VS 讯飞星火 VS chatgpt (86)-- 算法导论8.2 3题
    三、用go语言,假设我们在COUNTING-SORT的第10行循环的开始部分,将代码改写为:10forj=1toA.length试证明该算法仍然是正确的。它还稳定吗?文心一言:首先,让我们先明确COUNTING-SORT算法的基本思想。COUNTING-SORT是一种线性时间复杂度的排序算法,它适用于对一定范围内的......
  • 8.20-9.3总结
    这一段时间中间学习了一段时间不长也基本没学到什么东西,主要的是旅游从25号的时候去了江苏,我爸那玩了两天吃了小龙虾,还是之前的味道,然后28-9.1号去了青岛和淄博,去了青岛转了极地海洋世界,小的时候去了极地海洋馆,比起这个我觉得这个新的极地海洋世界比以前的更好看,里面的节目比......
  • php:查看安装时的编译参数(php 8.2.5)
    一,用-i参数[liuhongdi@img~]$/usr/local/soft/php8.2.5/bin/php-i|grepconfigureConfigureCommand=>  './configure'  '--prefix=/usr/local/soft/php8.2.5''--with-config-file-path=/usr/local/soft/php8.2.5/etc''--with-c......
  • php:命令行的常用例子(php 8.2.5)
    一,查看安装配置信息[liuhongdi@img~]$/usr/local/soft/php8.2.5/bin/php-i           相当于执行:[liuhongdi@img~]$/usr/local/soft/php8.2.5/bin/php-r"phpinfo();”二,列出开启的扩展模块:[liuhongdi@img~]$/usr/local/soft/php8.2.5/bin/php-m[......
  • 文心一言 VS 讯飞星火 VS chatgpt (85)-- 算法导论8.2 2题
    二、用go语言,试证明COUNTING-SORT是稳定的。文心一言:要证明COUNTING-SORT是稳定的,我们需要证明在排序过程中,具有相同值的元素在排序后仍保持其原始的相对顺序。COUNTING-SORT是一种基于计数的排序算法,其核心思想是利用计数数组记录待排序元素的数量。下面是COUNTING-SORT的......
  • 文心一言 VS 讯飞星火 VS chatgpt (85)-- 算法导论8.2 2题
    二、用go语言,试证明COUNTING-SORT是稳定的。文心一言:要证明COUNTING-SORT是稳定的,我们需要证明在排序过程中,具有相同值的元素在排序后仍保持其原始的相对顺序。COUNTING-SORT是一种基于计数的排序算法,其核心思想是利用计数数组记录待排序元素的数量。下面是COUNTING-SORT......