我正在编写一个调用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 Driver Development Kit (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");


当然,解决此问题后,您将希望看到我答案的第一部分。

关于c++ - LoadLibrary找不到ntoskrnl,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18042390/

10-15 17:58