【问题标题】:Create BSOD from user mode?从用户模式创建蓝屏?
【发布时间】:2011-10-25 11:07:07
【问题描述】:

有一天我对我的 XP 盒子感到厌烦,所以我决定尝试this question 的一些答案,看看它们中的任何一个是否会导致 BSOD。
他们没有,而且他们似乎最有可能这样做,所以我想知道是否可以在 C/C++ 中从用户模式触发 BSOD,如果可以,如何?

【问题讨论】:

  • 你的意思是,除了在内核模式代码中触发错误?
  • 蓝屏是 Windows 内核对 内核中的错误的响应。所以不,除了利用内核中的错误之外,用户模式下的崩溃处理方式也不同。
  • 数以百万计的 Windows 用户走在您之前,尽管是在不知不觉中。但是糟糕的 C 或 C++ 代码可以很好地协助。所剩无几。视频驱动程序是您最好的选择。

标签: c++ c kernel bsod


【解决方案1】:

就是这样:

#include <iostream>
#include <Windows.h>
#include <winternl.h>
using namespace std;
typedef NTSTATUS(NTAPI *pdef_NtRaiseHardError)(NTSTATUS ErrorStatus, ULONG NumberOfParameters, ULONG UnicodeStringParameterMask OPTIONAL, PULONG_PTR Parameters, ULONG ResponseOption, PULONG Response);
typedef NTSTATUS(NTAPI *pdef_RtlAdjustPrivilege)(ULONG Privilege, BOOLEAN Enable, BOOLEAN CurrentThread, PBOOLEAN Enabled);
int main()
{
    BOOLEAN bEnabled;
    ULONG uResp;
    LPVOID lpFuncAddress = GetProcAddress(LoadLibraryA("ntdll.dll"), "RtlAdjustPrivilege");
    LPVOID lpFuncAddress2 = GetProcAddress(GetModuleHandle("ntdll.dll"), "NtRaiseHardError");
    pdef_RtlAdjustPrivilege NtCall = (pdef_RtlAdjustPrivilege)lpFuncAddress;
    pdef_NtRaiseHardError NtCall2 = (pdef_NtRaiseHardError)lpFuncAddress2;
    NTSTATUS NtRet = NtCall(19, TRUE, FALSE, &bEnabled); 
    NtCall2(STATUS_FLOAT_MULTIPLE_FAULTS, 0, 0, 0, 6, &uResp); 
    return 0;
}

【讨论】:

  • 如果有人在第 12 行收到错误,请将其更改为:LPVOID lpFuncAddress2 = GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtRaiseHardError");
【解决方案2】:

有一个未记录的函数 NtRaiseHardError。

http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/Error/NtRaiseHardError.html

http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/Error/HARDERROR_RESPONSE_OPTION.html

如果第五个参数是 6 (OptionShutdownSystem),你会得到一个 BSOD。这需要启用关机权限。

【讨论】:

    【解决方案3】:

    除非用户模式程序与有错误的驱动程序交互(可能是特定的操作序列可以揭示特定驱动程序中的错误)干扰驱动程序堆栈,否则从用户模式制作蓝屏非常困难。从用户模式,输入在传递到内核模式之前经过验证,以确保系统的稳定性。大多数 Microsoft API/驱动程序都经过了很好的验证,以避免系统中的安全问题;驱动程序制造商也是如此。

    最好的办法是扰乱驱动栈,但不是用户态。

    您可以使用 NotMyFault SystInternals 实用程序创建 BSOD。它从根本上注入驱动程序并创建 BSOD

    http://download.sysinternals.com/Files/Notmyfault.zip

    【讨论】:

    • +1 用于提及 MS API/驱动程序输入验证和另一个 OTS 解决方案,以防需要进行测试。 (必须爱 sysinternals。)
    • 请注意 NtRaiseHardError
    【解决方案4】:

    除错误之外的方法是资源耗尽。您可以调查的一个领域是消耗机器上的所有 CPU(以实时优先级运行与内核一样多的线程),并消耗内核资源并依赖实时优先级来阻止内核清理起来。

    不知道什么是好的资源。针对无法清理 CPU 的设备执行大量未完成的异步操作?你至少可以朝那个方向尝试。

    【讨论】:

    • 如果您可以使 Windows 从用户模式蓝屏,那么这是一个纯粹而简单的内核模式组件中的错误。内核应该能够承受资源耗尽(对于承受的某些定义),否则它是潜在的 DOS 攻击。这同样适用于任何其他内核 - 如果您可以从用户模式停止内核,那就是一个错误。
    • 是和不是。特权用户被允许做可能破坏内核的事情。防御来自管理员帐户的 DoS 攻击不同于防御来自非特权用户的 DoS 攻击。像使用碎片 OVERLAPPED 结构分配启动许多异步 I/O 操作以消耗非分页池,然后让内核在临界点分配页面失败是使内核崩溃的合理途径。我认为这不是内核错误,而是管理失败(因此来自用户模式)。
    • 检查我的答案。例如,您可以通过获取 SeShutdownPrivilege 从用户模式生成蓝屏,然后调用带有浮点异常的 NtRaiseHardError。并非所有异常都会产生 BSOD,但 Floating Multiple Faults 会。
    【解决方案5】:

    如果操作系统中没有错误,那么从用户空间对机器进行蓝屏死机应该是不可能的。在最坏的情况下,它只会让有问题的应用程序崩溃。

    然而,没有什么是完美的。每个操作系统中都存在错误,并且每个操作系统都存在导致可从用户空间利用的 BSOD(或像 Linux 那样的 OOPS,或者给定的操作系统选择报告不可恢复的错误)的错误。

    就细节而言,这实际上取决于错误的性质。除了“是的,有可能”之外,没有通用的答案。

    有关更多详细信息,您应该更多地研究操作系统设计,以及如何使用分页、环级别和其他技术将进程彼此分离以及内核空间。

    【讨论】:

    • 一个 oops 不是不可恢复的,内核崩溃是
    【解决方案6】:

    嗯,蓝屏死机来自内核模式下发生的不可恢复的错误;如果不以某种方式触发内核错误,就无法导致这种情况发生。一般来说,如果你想这样做,你必须在驱动程序中找到一个缺陷[编辑:或者正如评论者指出的,一个系统调用]并利用它。

    或者,您可以执行此应用的操作:http://www.nirsoft.net/utils/start_blue_screen.html。只需编写自己的驱动程序即可以任何您想要的方式使系统崩溃。 :)

    维基百科页面有一些有趣的信息,因此我将其包括在内以供参考:http://en.wikipedia.org/wiki/Blue_Screen_of_Death

    【讨论】:

    • 编写自己的驱动程序并不完全是“从用户模式”;-)。
    • 公平地说,问题是:“所以我想知道是否可以在 C/C++ 中从用户模式触发 BSOD”而不是“是否可以在不调用司机”。 :P
    • 说真的,尽管真正的答案是,如果不利用某些缺陷或故意编写驱动程序就无法做到这一点,但我认为该驱动程序在某些测试场景中可能很有用;例如您有一个应用程序必须保持写入文件的一致性,并且您需要确保文件不会在 BSOD 时损坏。我不想成为做这些测试的测试工程师。 :D
    • 好吧,您忘记了系统调用,它不一定需要“驱动程序”,它们可以是核心内核功能......但除此之外,在有缺陷的驱动程序中调用例程和编写一个旨在崩溃的驱动程序是两件截然不同的事情。
    • 嗯,关于系统调用的要点很好,但它仍然需要找到可利用的缺陷。但我相信您在下一个陈述中完全不正确,至少只要您所指的“不同”是技术差异。所以,是的,它们在某种意义上是不同的,例如,如果您利用现有漏洞,则不需要管理权限来安装驱动程序。但从技术上讲,没有区别。您只是编写了一个故意内置了一个或多个缺陷的驱动程序。由驱动程序引起的任何蓝屏死机都是由驱动程序中的缺陷引起的。
    【解决方案7】:

    您可以使用键盘force a system crash。您的标题谈到了用户模式,我不确定这是否符合用户模式,但它可能有用。

    【讨论】:

      【解决方案8】:

      不使用驱动的两种方式:

      1. 正如有人指出的那样使用未记录的函数 NtRaiseHardError
      2. 使用未记录的函数 RtlSetProcessIsCritical 设置关键进程,然后终止它。需要 SE_DEBUG_NAME 权限。 http://www.codeproject.com/Articles/43405/Protecting-Your-Process-with-RtlSetProcessIsCriti

      【讨论】:

      • 这适用于使用 CRITICAL_PROCESS_DIED 退出的进程。您可以直接将 NtRaiseHardError 用于消息,并且曾经有过一次黑客攻击,甚至可以打印自定义文本(在 Windows 10 中不再适用)
      【解决方案9】:

      我在这个链接上找到了一个生成蓝屏的代码:https://www.mpgh.net/forum/showthread.php?t=1100477

      这是代码(我试过了,它可以工作,你只需要调用 BlueScreen() 函数)

      #include <windows.h>
      #pragma comment(lib, "ntdll.lib")
      
      extern "C" NTSTATUS NTAPI RtlAdjustPrivilege(ULONG Privilege, BOOLEAN Enable, BOOLEAN CurrentThread, PBOOLEAN OldValue);
      extern "C" NTSTATUS NTAPI NtRaiseHardError(LONG ErrorStatus, ULONG NumberOfParameters, ULONG UnicodeStringParameterMask,
          PULONG_PTR Parameters, ULONG ValidResponseOptions, PULONG Response);
      
          void BlueScreen()
          {
              BOOLEAN bl;
              ULONG Response;
              RtlAdjustPrivilege(19, TRUE, FALSE, &bl); // Enable SeShutdownPrivilege
              NtRaiseHardError(STATUS_ASSERTION_FAILURE, 0, 0, NULL, 6, &Response); // Shutdown
          }
      

      【讨论】:

        【解决方案10】:

        只需打开 Windows 运行并输入 C:\con\con

        【讨论】:

        • 那是针对 Windows 9x 的,已修复
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-21
        • 2012-01-10
        • 2012-11-13
        • 1970-01-01
        • 2015-12-28
        • 1970-01-01
        相关资源
        最近更新 更多