如何在调用dll方法时解决访问冲突写入位置

时间:2016-01-20 22:52:56

标签: c++ dll getprocaddress

我正在使用GetProcAddress来访问标准的Isapi Filter DLL方法 - 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 个答案:

答案 0 :(得分:2)

我看到的一个问题是你的函数指针声明不正确。

根据Microsoft文档,GetFilterVersion原型为:

BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer);

WINAPI是一个实际定义为__stdcall的Windows宏,因此当您使用__cdecl时,您将错误地声明函数指针。

What does WINAPI mean?

因此,您的声明应该是:

typedef BOOL(__stdcall * TRIRIGAISAPIV)(PHTTP_FILTER_VERSION);

答案 1 :(得分:1)

实际上可能有一些额外的结构字段由自定义过滤器填充。

您可以尝试增加结构的大小以查看它是否有效,例如:

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位。您不能使用32位应用程序使用64位DLL,反之亦然(但我希望在LoadLibrary调用期间已经失败)。