C#如何P / Invoke NtRaiseHardError

时间:2018-03-10 09:00:57

标签: c# c++-cli pinvoke blue-screen-of-death

以下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);
        }
    }

1 个答案:

答案 0 :(得分:4)

你的两个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