C#如何P/调用NtRaiseHardError [英] C# How to P/Invoke NtRaiseHardError

查看:513
本文介绍了C#如何P/调用NtRaiseHardError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下C ++代码会导致蓝屏.

The following C++ code causes a bluescreen.

    #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,因为未记录该信息.)
这是我尝试过的:

I want to use C# for this so I tried to use P/Invoke. But it doesn't work. The problem is properly at the NtRaiseHardError signature. I haven't found anything about it online (pinvoke.net for example doesn't show NtRaiseHardError because it is undocumented.)
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);
        }
    }

推荐答案

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

Both of your pinvoke declarations are wrong. Principally your use of C# ulong which is a 64 bit type. The C++ long type is 32 bits in Windows.

我会这样宣告他们

[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更加容易.

I've taken a short cut with the PULONG_PTR. Because you are passing the null pointer it's easier to declare it as IntPtr and pass IntPtr.Zero.

这篇关于C#如何P/调用NtRaiseHardError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆