我正在尝试从在 Windows 11 上运行的应用程序与 PktmonApi.dll 进行交互。根据 the docs,没有包含函数声明的头文件,而是需要动态加载 DLL(使用
LoadLibrary
),然后提取函数地址(使用 GetProcAddress
)。
GetProcAddress
指定在出现错误时返回NULL
(然后可以使用GetLastError()
检索错误)。
Here 是据称属于 API 一部分的函数列表。我尝试加载
PacketMonitorInitialize
,但是返回了NULL,而GetLastError()
是0x7f
(表示没有找到进程)。看到这个之后,我使用 Dependency Walker 来查看 PktmonApi.dll 包含的内容,它包含一组完全不同的函数
这些函数更符合 Windows 附带的 PktMon 应用程序的可能命令,但据我所知,它们的用法没有在任何地方记录。我尝试加载这个 DLL 中的函数之一,这次它返回了地址
0x1
并且没有错误。 0x1
显然不是一个有效的地址,调用它只会导致程序崩溃。
您可以运行此命令来重现问题:
#include <iostream>
#include <windows.h>
#include <iomanip>
int main() {
HMODULE module = LoadLibrary(TEXT("PktmonApi.dll"));
FARPROC start = GetProcAddress(module, "PktmonStart");
std::cout << "PktmonStart=0x" << std::hex << std::setw(16) << std::setfill('0') << start << ", err=0x" << std::setw(8) << GetLastError() << std::endl;
FARPROC init = GetProcAddress(module, "PacketMonitorInitialize");
std::cout << "PacketMonitorInitialize=0x" << std::hex << std::setw(16) << std::setfill('0') << init << ", err=0x" << std::setw(8) << GetLastError() << std::endl;
return 0;
}
对我来说这个程序输出
PktmonStart=0x0000000000000001, err=0x00000000
PacketMonitorInitialize=0x0000000000000000, err=0x0000007f
我已经接受了这样一个事实:微软刚刚完全改变了他们的 Pktmon API,而没有在任何地方记录它,但我不明白为什么在加载明显位于 DLL 内部的函数时我得到一个地址
0x1
。我错过了什么?
解决方案很简单:您无法使用正常的
<<
语法打印函数指针。它们显然在打印之前被转换为 bool 。为了正确打印函数指针,我需要事先将其reinterpret_cast为void*。
至于为什么调用函数会崩溃:很可能是因为提供的参数不正确,因为如果没有微软的文档,我无法找出函数签名应该是什么