LoadLibrary cannot find ntoskrnl

LoadLibrary cannot find ntoskrnl

本文关键字:ntoskrnl find cannot LoadLibrary      更新时间:2023-10-16

我正在编写一个小应用程序,它调用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时发生访问冲突。

任何帮助都将非常感谢

KeBugCheck是一个内核函数。这意味着你不能从用户模式代码中调用它,就像你试图编写的应用程序一样。

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

要做到这一点,您必须编写自己的内核模式驱动程序。要开始,请下载Windows驱动程序开发工具包(DDK)。在这种情况下,将不需要整个LoadLibraryGetProcAddress舞蹈,因为函数声明在公共Ntddk.h头中,并且将从Ntoskrnl.lib文件自动链接进来。


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

您正在编译一个Unicode应用程序,因此对LoadLibrary的调用会自动解析为LoadLibraryW,它接受类型为LPCWSTR的宽(Unicode)字符串。您正试图向它传递一个字符串文字,这会产生类型不匹配错误。除了你已经插入了强制转换,这有效地告诉编译器关闭,因为你比它知道得更好。你应该听编译器的;它可以把你从很多错误中拯救出来。

修复方法很简单:从代码中删除所有多余的强制转换,并使用宽的字符串文字。(然而,GetProcAddress函数是唯一的:它总是需要一个窄字符串,无论你是否为Unicode编译。)

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

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

尝试使用ntdll.dll NtRaiseHardError函数。ntdll函数是在用户模式下最接近内核模式的函数,NtRaiseHardError最终会在内核中调用KeBugCheck。