[英]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.