简体   繁体   English

C#如何P /调用NtRaiseHardError

[英]C# How to P/Invoke NtRaiseHardError

The following C++ code causes a bluescreen. 以下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;
    }

I want to use C# for this so I tried to use P/Invoke. 我想为此使用C#,所以我尝试使用P / Invoke。 But it doesn't work. 但这是行不通的。 The problem is properly at the NtRaiseHardError signature. 问题恰好在NtRaiseHardError签名处。 I haven't found anything about it online (pinvoke.net for example doesn't show NtRaiseHardError because it is undocumented.) 我还没有在线找到任何有关它的信息(例如,pinvoke.net没有显示NtRaiseHardError,因为它没有记录。)
This is what I tried: 这是我尝试的:

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

Both of your pinvoke declarations are wrong. 您的两个pinvoke声明都是错误的。 Principally your use of C# ulong which is a 64 bit type. 主要是您使用的C# ulong是64位类型。 The C++ long type is 32 bits in Windows. Windows中C ++ long类型为32位。

I'd declare them like this 我会这样宣告他们

[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
);

I've taken a short cut with the PULONG_PTR . 我已经使用PULONG_PTR进行了PULONG_PTR Because you are passing the null pointer it's easier to declare it as IntPtr and pass IntPtr.Zero . 因为要传递空指针,所以将其声明为IntPtr并传递IntPtr.Zero更加容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM