Kei*_*ung 3 c# pinvoke c++-cli 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;
}
Run Code Online (Sandbox Code Playgroud)
我想为此使用 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);
}
}
Run Code Online (Sandbox Code Playgroud)
您的两个 pinvoke 声明都是错误的。主要是您使用的ulong是 64 位类型的 C# 。longWindows 中的 C++类型是 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
);
Run Code Online (Sandbox Code Playgroud)
我在PULONG_PTR. 因为您正在传递空指针,所以将其声明为IntPtr和 pass更容易IntPtr.Zero。