Files
wavestone-cdt-edrsandblast/EDRSandblast/Utils/HttpClient.c
T
2023-10-06 16:12:52 +02:00

123 lines
3.7 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <windef.h>
#include <winhttp.h>
#include "PrintFunctions.h"
#include "HttpClient.h"
BOOL HttpsDownloadFullFile(LPCWSTR domain, LPCWSTR uri, PBYTE* output, SIZE_T* output_size) {
///wprintf_or_not(L"Downloading https://%s%s...\n", domain, uri);
// Get proxy configuration
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxyConfig;
WinHttpGetIEProxyConfigForCurrentUser(&proxyConfig);
BOOL proxySet = !(proxyConfig.fAutoDetect || proxyConfig.lpszAutoConfigUrl != NULL);
DWORD proxyAccessType = proxySet ? ((proxyConfig.lpszProxy == NULL) ?
WINHTTP_ACCESS_TYPE_NO_PROXY : WINHTTP_ACCESS_TYPE_NAMED_PROXY) : WINHTTP_ACCESS_TYPE_NO_PROXY;
LPCWSTR proxyName = proxySet ? proxyConfig.lpszProxy : WINHTTP_NO_PROXY_NAME;
LPCWSTR proxyBypass = proxySet ? proxyConfig.lpszProxyBypass : WINHTTP_NO_PROXY_BYPASS;
// Initialize HTTP session and request
HINTERNET hSession = WinHttpOpen(L"WinHTTP/1.0", proxyAccessType, proxyName, proxyBypass, 0);
if (hSession == NULL) {
printf_or_not("WinHttpOpen failed with error : 0x%x\n", GetLastError());
return FALSE;
}
HINTERNET hConnect = WinHttpConnect(hSession, domain, INTERNET_DEFAULT_HTTPS_PORT, 0);
if (!hConnect) {
printf_or_not("WinHttpConnect failed with error : 0x%x\n", GetLastError());
return FALSE;
}
HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"GET", uri, NULL,
WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);
if (!hRequest) {
return FALSE;
}
// Configure proxy manually
if (!proxySet)
{
WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions;
autoProxyOptions.dwFlags = proxyConfig.lpszAutoConfigUrl != NULL ? WINHTTP_AUTOPROXY_CONFIG_URL : WINHTTP_AUTOPROXY_AUTO_DETECT;
autoProxyOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
autoProxyOptions.fAutoLogonIfChallenged = TRUE;
if (proxyConfig.lpszAutoConfigUrl != NULL)
autoProxyOptions.lpszAutoConfigUrl = proxyConfig.lpszAutoConfigUrl;
WCHAR szUrl[MAX_PATH] = { 0 };
swprintf_s(szUrl, _countof(szUrl), L"https://%ws%ws", domain, uri);
WINHTTP_PROXY_INFO proxyInfo;
WinHttpGetProxyForUrl(
hSession,
szUrl,
&autoProxyOptions,
&proxyInfo);
WinHttpSetOption(hRequest, WINHTTP_OPTION_PROXY, &proxyInfo, sizeof(proxyInfo));
DWORD logonPolicy = WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW;
WinHttpSetOption(hRequest, WINHTTP_OPTION_AUTOLOGON_POLICY, &logonPolicy, sizeof(logonPolicy));
}
// Perform request
BOOL bRequestSent;
do {
bRequestSent = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
} while (!bRequestSent && GetLastError() == ERROR_WINHTTP_RESEND_REQUEST);
if (!bRequestSent) {
return FALSE;
}
BOOL bResponseReceived = WinHttpReceiveResponse(hRequest, NULL);
if (!bResponseReceived) {
return FALSE;
}
// Read response
DWORD dwAvailableSize = 0;
DWORD dwDownloadedSize = 0;
SIZE_T allocatedSize = 4096;
if (!WinHttpQueryDataAvailable(hRequest, &dwAvailableSize))
{
return FALSE;
}
*output = (PBYTE) malloc(allocatedSize);
*output_size = 0;
while (dwAvailableSize)
{
while (*output_size + dwAvailableSize > allocatedSize) {
allocatedSize *= 2;
PBYTE new_output = (PBYTE)realloc(*output, allocatedSize);
if (new_output == NULL)
{
return FALSE;
}
*output = new_output;
}
if (!WinHttpReadData(hRequest, *output + *output_size, dwAvailableSize, &dwDownloadedSize))
{
return FALSE;
}
*output_size += dwDownloadedSize;
WinHttpQueryDataAvailable(hRequest, &dwAvailableSize);
}
PBYTE new_output = (PBYTE)realloc(*output, *output_size);
if (new_output == NULL)
{
return FALSE;
}
*output = new_output;
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return TRUE;
}