0

我正在编写一个调用 KeBugCheck 并导致系统崩溃的小应用程序,但 LoadLibrary 无法找到 ntoskrnl.exe(调用 GetLastError 时我得到 126 作为返回值)

这是我的代码:

void* fnc;
HMODULE bcLib;
bcLib = LoadLibrary((LPCWSTR)"ntoskrnl.exe");
fnc = (void*) GetProcAddress(bcLib, (LPCSTR)"KeBugCheck");
int(*KeBugCheck)(ULONG);
KeBugCheck = (int(*)(ULONG))fnc;
KeBugCheck(0x000000E2);

另外,在调试窗口中,我看到了这个错误:

app.exe 中 0x00000000 处的第一次机会异常:0xC0000005:执行位置 0x00000000 的访问冲突。

任何帮助都会非常感激

4

2 回答 2

8

KeBugCheck是一个核函数。这意味着您不能从用户模式代码中调用它,例如您正在尝试编写的应用程序。

也没有为此函数提供用户模式包装器,因为用户模式代码不应该能够关闭整个系统。

您必须编写自己的内核模式驱动程序来执行此操作。要开始使用,请下载Windows 驱动程序开发工具包 (DDK)。在这种情况下,就不需要整体LoadLibraryGetProcAddress跳舞了,因为函数声明在公共头文件中,并且会从文件Ntddk.h中自动链接。Ntoskrnl.lib


至于您在这里遇到的问题,与LoadLibrary返回ERROR_MOD_NOT_FOUND无关。LPCWSTR您拥有的代码是错误的,从显式转换到为了关闭编译器而必须执行的代码非常明显。

您正在编译一个 Unicode 应用程序,因此对 的调用LoadLibrary会自动解析为LoadLibraryW,它接受类型为 的宽 (Unicode) 字符串LPCWSTR。您正在尝试向它传递一个字符串文字,这会产生类型不匹配错误。除了你已经插入了演员表,这有效地告诉编译器闭嘴,因为你比它更清楚。除了你没有。你应该听编译器的;它可以使您免于许多错误。

解决方法很简单:从代码中删除所有多余的强制转换并改用字符串文字。(GetProcAddress然而,这个函数是独一无二的:它总是需要一个窄字符串,不管你是否为 Unicode 编译。)

HMODULE bcLib = LoadLibrary(L"ntoskrnl.exe");
void* fnc = (void*)GetProcAddress(bcLib, "KeBugCheck");

当然,一旦你解决了这个问题,你就会想看看我回答的第一部分。

于 2013-08-04T11:36:57.253 回答
0

尝试使用 ntdll.dll NtRaiseHardError 函数。ntdll 函数是您可以在用户模式中获得的最接近内核模式函数的函数,并且 NtRaiseHardError 最终会在内核中调用 KeBugCheck。

于 2019-08-05T15:25:28.083 回答