LoadLibrary找不到ntoskrnl

时间:2013-08-04 11:25:37

标签: c++ windows winapi visual-c++ loadlibrary

我正在编写一个调用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。

任何帮助都会非常适合

2 个答案:

答案 0 :(得分:8)

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

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

您必须编写自己的内核模式驱动程序才能执行此操作。要开始使用,请下载Windows Driver Development Kit (DDK)。在这种情况下,不需要整个LoadLibraryGetProcAddress舞蹈,因为函数声明位于公共Ntddk.h标题中,并且将自动链接到Ntoskrnl.lib 1}}文件。


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

您正在编译Unicode应用程序,因此对LoadLibrary的调用会自动解析为LoadLibraryW,它接受​​类型为LPCWSTR的宽(Unicode)字符串。您试图将 narrow 字符串文字传递给它,这会产生类型不匹配错误。除了你已经插入了演员表,这有效地告诉编译器闭嘴,因为你知道比它更好。除非你不这样做。你应该听编译器;它可以帮助你避免许多错误。

修复很简单:从代码中删除所有多余的强制转换,然后使用 wide 字符串文字。 (但GetProcAddress函数是唯一的:它总是需要一个窄字符串,无论您是否正在编译Unicode。)

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

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

答案 1 :(得分:0)

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