Я пытаюсь взаимодействовать с PktmonApi.dll из моего приложения, работающего в Windows 11. Согласно документации, нет заголовочного файла, содержащего объявления функций, вместо этого вам нужно динамически загружать DLL (с помощью LoadLibrary
), а затем извлечь адрес функции (используя GetProcAddress
).
GetProcAddress
указывается для возврата NULL
в случае возникновения ошибки (и ошибку можно затем получить с помощью GetLastError()
).
Здесь список функций, которые предположительно являются частью API. Я попробовал загрузить PacketMonitorInitialize
, но он вернул NULL, а GetLastError()
было 0x7f
(что указывает на то, что процесс не найден). Увидев это, я использовал Dependency Walker, чтобы посмотреть, что содержит PktmonApi.dll, а он содержит совершенно другой набор функций
Эти функции больше соответствуют возможным командам приложения PktMon, поставляемым с Windows, но, насколько я могу судить, их использование нигде не документировано. Я попробовал загрузить одну из функций в этой 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
Я уже смирился с тем фактом, что Microsoft только что полностью изменила свой Pktmon API, нигде это не задокументировав, но я не понимаю, почему я получаю адрес 0x1
при загрузке функции, которая явно находится внутри DLL. Что мне не хватает?
🤔 А знаете ли вы, что...
C++ поддерживает объектно-ориентированное, процедурное и обобщенное программирование.
Решение простое: вы не можете печатать указатели функций, используя обычный синтаксис <<
. Очевидно, перед печатью они преобразуются в bool
. Чтобы правильно напечатать указатель на функцию, мне нужно заранее reinterpret_cast
его void*
.
Что касается того, почему вызов функции завершается сбоем: скорее всего, потому, что предоставленные аргументы неверны, поскольку я не могу узнать, какой должна быть сигнатура функции без документации Microsoft.
Я переписывался с некоторыми людьми в Microsoft, которые участвовали в написании этой документации, и ответ заключался в том, что текущая документация (сентябрь 2024 г.) документирует функции SDK, которые еще не были развернуты.