Created
March 24, 2025 15:12
-
-
Save justaguywhocodes/7f9ec3e6f9f8a30470c280d0cc787dcb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Here's the modified DLL that makes the download call when a thread attaches to the DLL. I've moved the download logic into a separate function and added the call in DllMain during DLL_THREAD_ATTACH: | |
```cpp | |
#include <windows.h> | |
#include <winhttp.h> | |
#pragma comment(lib, "winhttp.lib") | |
// Define default parameters as constants | |
const wchar_t* DEFAULT_PROXY_ADDRESS = L"proxy.example.com"; | |
const DWORD DEFAULT_PROXY_PORT = 8080; | |
const wchar_t* DEFAULT_PROXY_USERNAME = L"username"; | |
const wchar_t* DEFAULT_PROXY_PASSWORD = L"password"; | |
const wchar_t* DEFAULT_OUTPUT_PATH = L"C:\\downloaded_file.txt"; | |
BOOL PerformDownload( | |
LPCWSTR proxyAddress, | |
DWORD proxyPort, | |
LPCWSTR proxyUsername, | |
LPCWSTR proxyPassword, | |
LPCWSTR outputFilePath | |
) { | |
BOOL bResult = FALSE; | |
HINTERNET hSession = NULL; | |
HINTERNET hConnect = NULL; | |
HINTERNET hRequest = NULL; | |
HANDLE hFile = INVALID_HANDLE_VALUE; | |
// Initialize WinHTTP session | |
hSession = WinHttpOpen( | |
L"FileDownloader/1.0", | |
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, | |
WINHTTP_NO_PROXY_NAME, | |
WINHTTP_NO_PROXY_BYPASS, | |
0 | |
); | |
if (!hSession) goto cleanup; | |
// Set up proxy information | |
WINHTTP_PROXY_INFO proxyInfo = {0}; | |
proxyInfo.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY; | |
proxyInfo.lpszProxy = (LPWSTR)proxyAddress; | |
proxyInfo.lpszProxyBypass = NULL; | |
if (!WinHttpSetOption( | |
hSession, | |
WINHTTP_OPTION_PROXY, | |
&proxyInfo, | |
sizeof(proxyInfo) | |
)) goto cleanup; | |
// Set proxy credentials if provided | |
if (proxyUsername && proxyPassword) { | |
WinHttpSetCredentials( | |
hSession, | |
WINHTTP_AUTH_TARGET_PROXY, | |
WINHTTP_AUTH_SCHEME_BASIC, | |
proxyUsername, | |
proxyPassword, | |
NULL | |
); | |
} | |
// Connect to the server | |
hConnect = WinHttpConnect( | |
hSession, | |
L"test.com", | |
INTERNET_DEFAULT_HTTPS_PORT, | |
0 | |
); | |
if (!hConnect) goto cleanup; | |
// Create HTTP request | |
hRequest = WinHttpOpenRequest( | |
hConnect, | |
L"GET", | |
L"/file.txt", | |
NULL, | |
WINHTTP_NO_REFERER, | |
WINHTTP_DEFAULT_ACCEPT_TYPES, | |
WINHTTP_FLAG_SECURE | |
); | |
if (!hRequest) goto cleanup; | |
// Send request | |
if (!WinHttpSendRequest( | |
hRequest, | |
WINHTTP_NO_ADDITIONAL_HEADERS, | |
0, | |
WINHTTP_NO_REQUEST_DATA, | |
0, | |
0, | |
0 | |
)) goto cleanup; | |
// Receive response | |
if (!WinHttpReceiveResponse(hRequest, NULL)) goto cleanup; | |
// Check status code | |
DWORD statusCode = 0; | |
DWORD statusCodeSize = sizeof(statusCode); | |
WinHttpQueryHeaders( | |
hRequest, | |
WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, | |
NULL, | |
&statusCode, | |
&statusCodeSize, | |
NULL | |
); | |
if (statusCode != 200) goto cleanup; | |
// Create output file | |
hFile = CreateFileW( | |
outputFilePath, | |
GENERIC_WRITE, | |
0, | |
NULL, | |
CREATE_ALWAYS, | |
FILE_ATTRIBUTE_NORMAL, | |
NULL | |
); | |
if (hFile == INVALID_HANDLE_VALUE) goto cleanup; | |
// Download and write file | |
DWORD bytesRead = 0; | |
BYTE buffer[4096]; | |
while (WinHttpReadData(hRequest, buffer, sizeof(buffer), &bytesRead)) { | |
if (bytesRead == 0) break; | |
DWORD bytesWritten; | |
WriteFile(hFile, buffer, bytesRead, &bytesWritten, NULL); | |
} | |
bResult = TRUE; | |
cleanup: | |
if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); | |
if (hRequest) WinHttpCloseHandle(hRequest); | |
if (hConnect) WinHttpCloseHandle(hConnect); | |
if (hSession) WinHttpCloseHandle(hSession); | |
return bResult; | |
} | |
// Still exporting the function for manual calls if needed | |
extern "C" { | |
__declspec(dllexport) BOOL DownloadFile( | |
LPCWSTR proxyAddress, | |
DWORD proxyPort, | |
LPCWSTR proxyUsername, | |
LPCWSTR proxyPassword, | |
LPCWSTR outputFilePath | |
) { | |
return PerformDownload(proxyAddress, proxyPort, proxyUsername, proxyPassword, outputFilePath); | |
} | |
} | |
// DLL entry point with thread attach handling | |
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { | |
switch (ul_reason_for_call) { | |
case DLL_PROCESS_ATTACH: | |
// Initialize any process-wide resources if needed | |
break; | |
case DLL_THREAD_ATTACH: | |
// Perform download when a thread attaches | |
PerformDownload( | |
DEFAULT_PROXY_ADDRESS, | |
DEFAULT_PROXY_PORT, | |
DEFAULT_PROXY_USERNAME, | |
DEFAULT_PROXY_PASSWORD, | |
DEFAULT_OUTPUT_PATH | |
); | |
break; | |
case DLL_THREAD_DETACH: | |
// Clean up thread-specific resources if needed | |
break; | |
case DLL_PROCESS_DETACH: | |
// Clean up process-wide resources if needed | |
break; | |
} | |
return TRUE; | |
} | |
``` | |
Key changes made: | |
1. Moved the download logic into a separate `PerformDownload` function | |
2. Added default constants for proxy settings and output path | |
3. Implemented the download call in `DLL_THREAD_ATTACH` case of DllMain | |
4. Kept the exported `DownloadFile` function for manual calls | |
5. Maintained proper resource cleanup | |
Important notes: | |
1. Be cautious with operations in DllMain: | |
- Windows imposes restrictions on what can be safely done in DllMain | |
- Network operations like this might be problematic in some scenarios | |
- Consider using a separate thread or initialization function instead if you encounter issues | |
2. The default parameters are hardcoded as constants | |
- You should replace them with your actual proxy details | |
- Consider making them configurable if needed | |
3. Error handling: | |
- The function returns BOOL but doesn't provide detailed error information | |
- You might want to add logging or error reporting if needed | |
To use this DLL: | |
- When any thread attaches to the DLL, it will automatically attempt to download the file | |
- You can still call DownloadFile manually if needed | |
- Make sure to update the DEFAULT_ constants with your actual proxy settings | |
If you need a different approach (like moving the download to a separate thread or adding configuration options), let me know! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment