From be4f51be0232e60ea0380a229f2cf950ed421214 Mon Sep 17 00:00:00 2001 From: c0dycode Date: Sun, 8 Aug 2021 14:00:15 +0200 Subject: [PATCH] Most recent version --- BL3ProxySettings.cpp | 227 +++++++++++++++++++++++++++---------------- 1 file changed, 145 insertions(+), 82 deletions(-) diff --git a/BL3ProxySettings.cpp b/BL3ProxySettings.cpp index 4a8200e..b685ef1 100644 --- a/BL3ProxySettings.cpp +++ b/BL3ProxySettings.cpp @@ -80,6 +80,8 @@ auto generateMicropatchArrayPattern = xorstr("48 89 5C 24 ?? 48 89 74 24 ?? 48 8 auto generateMicropatchArrayBackupPattern = xorstr("48 8D 54 24 ?? E8 ?? ?? ?? ?? 48 8D 55 60"); auto getNewsItemsPattern = xorstr("48 89 ?? ?? ?? 48 89 ?? ?? ?? 48 89 ?? ?? ?? 48 89 ?? ?? ?? 55 41 ?? 41 ?? 41 ?? 41 ?? 48 8D ?? ?? ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? ?? 8D"); auto FGbxSparkModuleStartupModulePattern = xorstr("40 53 48 83 EC 50 48 8B D9 48 89 0D"); +auto onMicropatchesReceivedPattern = xorstr("48 89 5C 24 ?? 48 89 74 24 ?? 55 57 41 55 41 56 41 57 48 8D 6C 24 ?? 48 81 EC ?? ?? ?? ?? 48 63 51 08"); +auto areMicropatchesDifferentPattern = xorstr("48 89 5C 24 ?? 55 56 57 48 83 EC 20 C7 02"); // + 0x33 auto parseJSONString = xorstr("40 55 53 56 57 48 8D 6C 24 ?? 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 45 10 48 8B D9"); @@ -91,6 +93,8 @@ auto reallocPattern = xorstr("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B CRITICAL_SECTION critsec; +static bool isInInternalMode = false; + // //std::string startReceiveHotfixes_Pattern = xorstr("48 63 81 c4 00 00 00 83 f8 06 77 49 4c 8d 05"); //// @@ -644,6 +648,9 @@ tGenerateMicropatchArray oGenerateMicropatchArray = NULL; typedef void* (__fastcall* tParseJSONString)(void** jsonReader, const FString* text); tParseJSONString oParseJSONString = NULL; +typedef bool(__fastcall* tAreMicropatchesDifferent)(TArray* micropatches, void* severity); +tAreMicropatchesDifferent oAreMicropatchesDifferent = NULL; + FSparkModule** pSparkModule = NULL; @@ -720,6 +727,16 @@ void* hkParseJSONString(void** reader, FString* text) { } json j; char buffer[256] = { 0 }; + if (ModdedHotfixes == 0 && TotalHotfixes == 0) { + delete ws; +#ifdef _WIN32 + WSACleanup(); +#endif + if (oParseJSONString) + return oParseJSONString(reader, text); + return NULL; + } + sprintf(buffer, "%I64u/%I64u", ModdedHotfixes, TotalHotfixes); j["eventName"] = "getNews"; @@ -774,7 +791,7 @@ void* hkParseJSONString(void** reader, FString* text) { #ifdef _WIN32 WSACleanup(); #endif - std::cout << modified.ToString() << std::endl; + //std::cout << modified.ToString() << std::endl; if (oParseJSONString) { void* result = oParseJSONString(reader, text); return result; @@ -997,17 +1014,17 @@ static Curl_Write_Data* currentCurlWriteData = NULL; size_t __stdcall hkWriteCallback(char* ptr, size_t size, size_t dataSize, void* userdata) { size_t writeSize = oWrite_Callback(ptr, size, dataSize, userdata); - currentCurlWriteData = (Curl_Write_Data*)userdata; - std::string currentURL = currentCurlWriteData->RequestURL.ToString(); - if (currentURL.find("verification") != std::string::npos && currentURL.find("discovery") != std::string::npos) { - std::cout << "Need to get and alter response here" << std::endl; - /*static std::string moddedHotfixes = getMicropatchString(); - currentCurlWriteData->Body->Content.ResizeGrow(currentCurlWriteData->Body->Content.Count, moddedHotfixes.size(), 1); - strcpy(currentCurlWriteData->Body->Content.Data, &moddedHotfixes.data()[0]); - currentCurlWriteData->Body->Content.Max = moddedHotfixes.size(); - currentCurlWriteData->Body->Content.Count = moddedHotfixes.size();*/ - std::cout << "" << std::endl; - } + //currentCurlWriteData = (Curl_Write_Data*)userdata; + //std::string currentURL = currentCurlWriteData->RequestURL.ToString(); + //if (currentURL.find("verification") != std::string::npos && currentURL.find("discovery") != std::string::npos) { + // std::cout << "Need to get and alter response here" << std::endl; + // /*static std::string moddedHotfixes = getMicropatchString(); + // currentCurlWriteData->Body->Content.ResizeGrow(currentCurlWriteData->Body->Content.Count, moddedHotfixes.size(), 1); + // strcpy(currentCurlWriteData->Body->Content.Data, &moddedHotfixes.data()[0]); + // currentCurlWriteData->Body->Content.Max = moddedHotfixes.size(); + // currentCurlWriteData->Body->Content.Count = moddedHotfixes.size();*/ + // std::cout << "" << std::endl; + //} return writeSize; } @@ -1038,56 +1055,61 @@ bool startLogging = false; DWORD __stdcall hkCurl_Easy_SetOpt(void* curlHandle, long option, void* parameter) { DWORD result; - /*result = oCurl_Easy_SetOpt(curlHandle, option, parameter);*/ - - EnterCriticalSection(&critsec); + result = oCurl_Easy_SetOpt(curlHandle, option, parameter); + if (!isInInternalMode) { + EnterCriticalSection(&critsec); - result = oCurl_Easy_SetOpt(curlHandle, CURLOPT_PROXY, const_cast((proxyURLA + proxyPort).c_str())); - if (result != CURLE_OK) { - std::cout << "Failed to set proxy. Errorcode: " << result << std::endl; - } + result = oCurl_Easy_SetOpt(curlHandle, CURLOPT_PROXY, const_cast((proxyURLA + proxyPort).c_str())); + if (result != CURLE_OK) { + std::cout << "Failed to set proxy. Errorcode: " << result << std::endl; + } - result = oCurl_Easy_SetOpt(curlHandle, CURLOPT_ERRORBUFFER, errbuf); - if (result != CURLE_OK) { - std::cout << "Failed to set errorbuffer. Errorcode: " << result << std::endl; - } + result = oCurl_Easy_SetOpt(curlHandle, CURLOPT_ERRORBUFFER, errbuf); + if (result != CURLE_OK) { + std::cout << "Failed to set errorbuffer. Errorcode: " << result << std::endl; + } - if (option == CURLOPT_SSL_VERIFYHOST) { - parameter = (void*)0L; - result = oCurl_Easy_SetOpt(curlHandle, option, parameter); - } - else if (option == CURLOPT_SSL_VERIFYPEER) { - parameter = (void*)0L; - result = oCurl_Easy_SetOpt(curlHandle, option, parameter); - } - else if (option == CURLOPT_USE_SSL) { - parameter = (void*)CURLUSESSL_TRY; - result = oCurl_Easy_SetOpt(curlHandle, option, parameter); - } - else if (option == CURLOPT_WRITEFUNCTION) { - std::cout << "Write data func at: 0x" << std::hex << parameter << std::endl; + if (option == CURLOPT_SSL_VERIFYHOST) { + parameter = (void*)0L; + result = oCurl_Easy_SetOpt(curlHandle, option, parameter); + } + else if (option == CURLOPT_SSL_VERIFYPEER) { + parameter = (void*)0L; + result = oCurl_Easy_SetOpt(curlHandle, option, parameter); + } + else if (option == CURLOPT_USE_SSL) { + parameter = (void*)CURLUSESSL_TRY; + result = oCurl_Easy_SetOpt(curlHandle, option, parameter); + } + else if (option == CURLOPT_WRITEFUNCTION) { + //std::cout << "Write data func at: 0x" << std::hex << parameter << std::endl; - oWrite_Callback = (tWrite_Callback)parameter; - parameter = &hkWriteCallback; - hookedWriteCallback = true; - result = oCurl_Easy_SetOpt(curlHandle, option, parameter); - } - else if (option == CURLOPT_READFUNCTION) { - std::cout << "Read data func at: 0x" << std::hex << parameter << std::endl; - result = oCurl_Easy_SetOpt(curlHandle, option, parameter); - } - else if (option == CURLOPT_CAINFO) { - result = CURLE_OK; - } - else { - result = oCurl_Easy_SetOpt(curlHandle, option, parameter); - } + oWrite_Callback = (tWrite_Callback)parameter; + parameter = &hkWriteCallback; + hookedWriteCallback = true; + result = oCurl_Easy_SetOpt(curlHandle, option, parameter); + } + else if (option == CURLOPT_READFUNCTION) { + //std::cout << "Read data func at: 0x" << std::hex << parameter << std::endl; + result = oCurl_Easy_SetOpt(curlHandle, option, parameter); + } + else if (option == CURLOPT_CAINFO) { + result = CURLE_OK; + } + else { + result = oCurl_Easy_SetOpt(curlHandle, option, parameter); + } - LeaveCriticalSection(&critsec); + LeaveCriticalSection(&critsec); + } return result; } +bool __fastcall hkAreMicropatchesDifferent(TArray* micropatches, void* severity) { + return true; +} + void hkGenerateMicropatchArray(void* someTMap, TArray* outPatches) { if (oGenerateMicropatchArray) { oGenerateMicropatchArray(someTMap, outPatches); @@ -1195,9 +1217,9 @@ void hkGetNewsItems(void* newsWidget) { if (*pSparkModule) { if ((*pSparkModule)->SparkNewsService && (*pSparkModule)->SparkNewsService->NewsItems.Data != NULL) { - for (int i = 0; i < (*pSparkModule)->SparkNewsService->NewsItems.Count; ++i) { + /*for (int i = 0; i < (*pSparkModule)->SparkNewsService->NewsItems.Count; ++i) { std::cout << (*pSparkModule)->SparkNewsService->NewsItems.Data[i].NewsText.ToString() << std::endl; - } + }*/ } } if (oGetNewsItems) { @@ -1344,17 +1366,11 @@ DWORD WINAPI MainThread(LPVOID param) } std::cout << "Found 5/7 Patterns" << std::endl; - /*uintptr_t generateMicropatchArray = PatternScan::FindSignature(NULL, generateMicropatchArrayPattern.crypt_get()); - while (generateMicropatchArray == NULL) { - generateMicropatchArray = PatternScan::FindSignature(NULL, generateMicropatchArrayPattern.crypt_get()); - Sleep(50); - }*/ - std::cout << "Found 6/7 Patterns" << std::endl; - /*uintptr_t getNewsItems = PatternScan::FindSignature(NULL, getNewsItemsPattern.crypt_get()); - while (getNewsItems == NULL) { - getNewsItems = PatternScan::FindSignature(NULL, getNewsItemsPattern.crypt_get()); - Sleep(50); - }*/ + uintptr_t areMicropatchesDifferentAddress = PatternScan::FindSignature(NULL, areMicropatchesDifferentPattern.crypt_get()); + while (areMicropatchesDifferentAddress == NULL) { + areMicropatchesDifferentAddress = PatternScan::FindSignature(NULL, areMicropatchesDifferentPattern.crypt_get()); + Sleep(100); + } uintptr_t sparkModuleAddress = PatternScan::FindSignature(NULL, FGbxSparkModuleStartupModulePattern.crypt_get()); while (sparkModuleAddress == NULL) { @@ -1366,15 +1382,7 @@ DWORD WINAPI MainThread(LPVOID param) pSparkModule = reinterpret_cast(sparkModuleAddress + sparkSingletonOffset + 7); - /*uintptr_t parseJSONStringAddress = PatternScan::FindSignature(NULL, parseJSONString.crypt_get()); - while (parseJSONStringAddress == NULL) { - parseJSONStringAddress = PatternScan::FindSignature(NULL, parseJSONString.crypt_get()); - Sleep(50); - } - parseJSONStringAddress += 0x33; - - int32_t parseJSONStringOffset = *(int32_t*)(parseJSONStringAddress + 1); - parseJSONStringAddress = parseJSONStringAddress + parseJSONStringOffset + 5;*/ + std::cout << "Found 7/7 Patterns" << std::endl; /*uintptr_t fsparkmanagerctor = PatternScan::FindSignature(NULL, sparkManagerCtorPattern.c_str()); @@ -1415,14 +1423,10 @@ DWORD WINAPI MainThread(LPVOID param) Sleep(200); while (MH_CreateHookEx((LPVOID)curl_easy_getinfo, &hkCurl_Easy_GetInfo, &oCurl_Easy_GetInfo) != MH_OK) Sleep(200); + while (MH_CreateHookEx((LPVOID)areMicropatchesDifferentAddress, &hkAreMicropatchesDifferent, &oAreMicropatchesDifferent) != MH_OK) + Sleep(200); std::cout << "Placed 5/7 hooks" << std::endl; - /*while (MH_CreateHookEx((LPVOID)generateMicropatchArray, &hkGenerateMicropatchArray, &oGenerateMicropatchArray) != MH_OK) - Sleep(200);*/ - std::cout << "Placed 6/7 hooks" << std::endl; - /*while (MH_CreateHookEx((LPVOID)getNewsItems, &hkGetNewsItems, &oGetNewsItems) != MH_OK) - Sleep(200); */ - /*while (MH_CreateHookEx((LPVOID)parseJSONStringAddress, &hkParseJSONString, &oParseJSONString) != MH_OK) - Sleep(200);*/ + std::cout << "Placed 7/7 hooks" << std::endl; while (MH_EnableHook(MH_ALL_HOOKS) != MH_OK) { Sleep(200); @@ -1435,8 +1439,67 @@ DWORD WINAPI MainThread(LPVOID param) struct ArgStruct { const char dllPath[MAX_PATH]; int portNumber; + bool boolValue; }; +// TODO: Send log messages on success/errors +extern "C" __declspec(dllexport) DWORD __stdcall ToggleOperationalMode(ArgStruct* argStruct) +{ + EnterCriticalSection(&critsec); + static uintptr_t generateMicropatchArray; + while (generateMicropatchArray == NULL) { + generateMicropatchArray = PatternScan::FindSignature(NULL, generateMicropatchArrayPattern.crypt_get()); + Sleep(50); + } + static uintptr_t getNewsItems; + while (getNewsItems == NULL) { + getNewsItems = PatternScan::FindSignature(NULL, getNewsItemsPattern.crypt_get()); + Sleep(50); + } + static uintptr_t parseJSONStringAddress; + while (parseJSONStringAddress == NULL) { + parseJSONStringAddress = PatternScan::FindSignature(NULL, parseJSONString.crypt_get()); + if (parseJSONStringAddress != NULL) { + parseJSONStringAddress += 0x33; + + int32_t parseJSONStringOffset = *(int32_t*)(parseJSONStringAddress + 1); + parseJSONStringAddress = parseJSONStringAddress + parseJSONStringOffset + 5; + } + Sleep(50); + } + // Hook or unhook + if (argStruct->boolValue && !isInInternalMode) { + MH_STATUS hookStatus = MH_CreateHookEx((LPVOID)generateMicropatchArray, &hkGenerateMicropatchArray, &oGenerateMicropatchArray); + if (hookStatus == MH_ERROR_ALREADY_CREATED || hookStatus == MH_OK) { + hookStatus = MH_EnableHook((LPVOID)generateMicropatchArray); + } + hookStatus = MH_CreateHookEx((LPVOID)getNewsItems, &hkGetNewsItems, &oGetNewsItems); + if (hookStatus == MH_ERROR_ALREADY_CREATED || hookStatus == MH_OK) { + hookStatus = MH_EnableHook((LPVOID)getNewsItems); + } + hookStatus = MH_CreateHookEx((LPVOID)parseJSONStringAddress, &hkParseJSONString, &oParseJSONString); + if (hookStatus == MH_ERROR_ALREADY_CREATED || hookStatus == MH_OK) { + hookStatus = MH_EnableHook((LPVOID)parseJSONStringAddress); + } + + isInInternalMode = true; + } + else if (!argStruct->boolValue && isInInternalMode) { + while (MH_DisableHook((LPVOID)generateMicropatchArray) != MH_OK) + Sleep(200); + while (MH_DisableHook((LPVOID)getNewsItems) != MH_OK) + Sleep(200); + while (MH_DisableHook((LPVOID)parseJSONStringAddress) != MH_OK) + Sleep(200); + while (MH_ApplyQueued() != MH_OK) + Sleep(200); + isInInternalMode = false; + } + + LeaveCriticalSection(&critsec); + return TRUE; +} + extern "C" __declspec(dllexport) DWORD __stdcall InitFunc(ArgStruct * argstruct) { EnterCriticalSection(&critsec);