I am creating an x64 DLL library for Windows in C/C++ to send a POST request to a given URL and get the response.
I am using WinHttp to send the request, sporadically (not always, about 1 time out of 5) my DLL crashes for STATUS_HEAP_CORRUPTION.
I have tried running a check with ApplicationVerifier and starting my dll via the rundll32.exe proxy to debug and without any explanation, when run in these two ways, STATUS_HEAP_CORRUPTION never occurs.
It only happens if I start my dll from my application or via rundll32.exe in Release mode.
The exception is reported by the Visual Studio debugger at this line:
HINTERNET hSession = WinHttpOpen(L"Mozilla/5.0 MyAgentTest", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, NULL);
I do not use or execute the function in different threads, everything is executed in the main dll thread.
I also attach two screenshots of the visual studio debugger report:
- [Callstack screenshot] https://imgur.com/a/vRMYAbN
- [Exception Thrown] https://imgur.com/a/4AWhf9u
Can anyone explain why?
EDIT:
Full function code:
LPSTR SendPostRequest(LPCWSTR domain, LPCWSTR url, LPCSTR data, BOOL ssl)
{
HINTERNET hSession = WinHttpOpen(L"Mozilla/5.0 MyAgentTest", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, NULL);
if (hSession == NULL) return NULL;
HINTERNET hConnect = WinHttpConnect(hSession, domain, INTERNET_DEFAULT_PORT, NULL);
if (hConnect == NULL)
{
WinHttpCloseHandle(hSession);
return NULL;
}
HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"POST", url, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, (ssl ? WINHTTP_FLAG_SECURE : 0) | WINHTTP_FLAG_REFRESH);
if (hRequest == NULL)
{
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return NULL;
}
if (data == NULL) data = "";
CONST DWORD length = strlen(data);
BOOL requestSuccess = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, -1, (LPVOID)data, length, length, 0);
if (requestSuccess == FALSE)
{
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return NULL;
}
requestSuccess = WinHttpReceiveResponse(hRequest, NULL);
if (requestSuccess == FALSE)
{
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return NULL;
}
DWORD dataSize = 0, dwDownloaded = 0;
CHAR* pszOutBuffer = NULL;
string response;
do
{
dataSize = 0;
if (WinHttpQueryDataAvailable(hRequest, &dataSize) == FALSE)
{
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return NULL;
}
pszOutBuffer = new CHAR[dataSize + 1]{};
if (pszOutBuffer == NULL) continue;
if (WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dataSize, &dwDownloaded))
{
response = response + string(pszOutBuffer);
}
delete[] pszOutBuffer;
} while (dataSize > 0);
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
if (!response.empty())
{
CONST SIZE_T responseLength = response.length() + 1;
CHAR* result = new CHAR[responseLength]{};
strcpy_s(result, responseLength, response.c_str());
response.clear();
return result;
}
return NULL;
}