以下C ++代码导致蓝屏。

    #include "stdafx.h"
    #include <iostream>
    #include <string>
    #include <Windows.h>

    #pragma comment(lib, "ntdll.lib")


    using namespace std;


    EXTERN_C NTSTATUS NTAPI RtlAdjustPrivilege(ULONG, BOOLEAN, BOOLEAN, PBOOLEAN);

    EXTERN_C NTSTATUS NTAPI NtRaiseHardError(NTSTATUS, ULONG, ULONG, PULONG_PTR, ULONG, PULONG);

    int main(int argc, char **argv)
    {
        BOOLEAN bl;
        RtlAdjustPrivilege(19, TRUE, FALSE, &bl);
        unsigned long response;
        NtRaiseHardError(STATUS_ASSERTION_FAILURE, 0, 0, 0, 6, &response);
        return 0;
    }


我想为此使用C#,所以我尝试使用P / Invoke。但这是行不通的。问题恰好在NtRaiseHardError签名处。我还没有在网上找到有关它的任何信息(例如,pinvoke.net没有显示NtRaiseHardError,因为它没有记录。)
这是我尝试的:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Runtime.InteropServices;
    using System.IO;

    namespace BSCS
    {
        class Program
        {
            private static ulong STATUS_ASSERTION_FAILURE = 0xC0000420;

            static void Main(string[] args)
            {
                Console.WriteLine("Adjusting privileges");
                RtlAdjustPrivilege(19, true, false, out bool previousValue);
                Console.WriteLine("Triggering BSOD");
                NtRaiseHardError(STATUS_ASSERTION_FAILURE, 0, 0, 0, 6, out ulong oul);
                Console.WriteLine("Done");
            }

            [DllImport("ntdll.dll")]
            private static extern IntPtr RtlAdjustPrivilege(int Privilege, bool bEnablePrivilege, bool IsThreadPrivilege,
                out bool PreviousValue);

            [DllImport("ntdll.dll")]
            private static extern IntPtr NtRaiseHardError(ulong status, ulong ul, ulong ul2, ulong ul3, ulong ul4, out ulong oul);
        }
    }

最佳答案

您的两个pinvoke声明都是错误的。原则上,您使用的是64位类型的C#ulong。 Windows中C ++ long类型为32位。

我会这样宣告他们

[DllImport("ntdll.dll")]
private static extern uint RtlAdjustPrivilege(
    int Privilege,
    bool bEnablePrivilege,
    bool IsThreadPrivilege,
    out bool PreviousValue
);

[DllImport("ntdll.dll")]
private static extern uint NtRaiseHardError(
    uint ErrorStatus,
    uint NumberOfParameters,
    uint UnicodeStringParameterMask,
    IntPtr Parameters,
    uint ValidResponseOption,
    out uint Response
);


PULONG_PTR是我的捷径。因为您要传递空指针,所以将其声明为IntPtr并传递IntPtr.Zero更容易。

10-05 21:22