Как определить местоположение записи нарушения прав доступа при вызове метода dll

Я использую GetProcAddress, чтобы получить доступ к стандартному методу DLL Isapi Filter — методу GetFilterVersion, который принимает указатель на структуру HTTP_FILTER_VERSION.

https://msdn.microsoft.com/en-us/library/ms525822(v=vs.90).aspx

https://msdn.microsoft.com/en-us/library/ms525465(v=vs.90).aspx

Я проверил код на работающем фильтре Isapi, который я написал, и он отлично работает. Я отлаживаю код против фильтра Isapi от поставщика (у меня нет доступа к исходному коду или чему-либо кроме самой dll), и я получаю исключение, «место записи нарушения доступа». В чем может быть проблема? (Оба фильтра Isapi работают в IIS.)

//Attempted to define function ptr several ways
typedef BOOL(__cdecl * TRIRIGAISAPIV)(PHTTP_FILTER_VERSION);
//typedef BOOL( * TRIRIGAISAPIV)(PHTTP_FILTER_VERSION);
//typedef BOOL(WINAPI * TRIRIGAISAPIV)(PHTTP_FILTER_VERSION);

void arbitraryMethod()
{
HINSTANCE hDLL;               // Handle to DLL
TRIRIGAISAPIV lpfnDllFunc2;    // Function pointer

DWORD lastError;
BOOL  uReturnVal2;

hDLL = LoadLibrary(L"iisWASPlugin_http.dll");  //vendor's dll
//hDLL = LoadLibrary(L"KLTWebIsapi.dll   //my dll

if (hDLL != NULL)
{
lpfnDllFunc2 = (TRIRIGAISAPIV)GetProcAddress(hDLL, "GetFilterVersion");

if (!lpfnDllFunc2)
{
lastError = GetLastError();
// handle the error
FreeLibrary(hDLL);
//return 1;
}
else
{
HTTP_FILTER_VERSION pVer = { 6 };

//Call the function via pointer; Works with my dll, fails with vendor's
uReturnVal2 = lpfnDllFunc2(&pVer);

//................  HELP!!!!!!!!!!!!!
}
}
}

2

Решение

Одна проблема, которую я вижу, заключается в том, что ваше объявление указателя на функцию неверно.

Согласно документации Microsoft, GetFilterVersion прототипируется как:

BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer);

WINAPI это макрос Windows, который на самом деле определяется как __stdcallтаким образом вы неправильно объявляете указатель на функцию при использовании __cdecl,

Что означает WINAPI?

Таким образом, ваша декларация должна быть:

typedef BOOL(__stdcall * TRIRIGAISAPIV)(PHTTP_FILTER_VERSION);
2

Другие решения

Возможно, на самом деле есть некоторые дополнительные поля структуры, заполненные пользовательским фильтром.

Вы можете попытаться увеличить размер структуры, чтобы увидеть, будет ли это работать, например:

struct HTTP_FILTER_VERSION_EXTRA {
HTTP_FILTER_VERSION v;
char[1024] extra;
};

HTTP_FILTER_VERSION_EXTRA ver;
ver.v.dwServerFilterVersion = 6;
uReturnVal2 = lpfnDllFunc2(&ver.v);

Иногда в случае структур WinAPI они допускают управление версиями, поэтому добавление полей возможно. Если функция затем не проверяет (или не знает) фактическую версию структуры, она может попытаться использовать расширенную версию, которая может отличаться от предоставленной — если размер предоставленной структуры будет меньше структуры версия, которую пытается использовать func, могут случиться плохие вещи.

Также проверьте, является ли DLL 64-битной или 32-битной. Вы не можете использовать 64-битную DLL 32-битным приложением и наоборот (но я ожидаю, что это уже не получится во время вызова LoadLibrary).

1

По вопросам рекламы [email protected]