diff --git a/PolygonClientUtilities/Classes.h b/PolygonClientUtilities/Classes.h index af38489..2d819fc 100644 --- a/PolygonClientUtilities/Classes.h +++ b/PolygonClientUtilities/Classes.h @@ -5,23 +5,23 @@ struct Tuple { - void* padding1[4]; - bool padding2; - bool padding3; + void* padding1[4]; + bool padding2; + bool padding3; }; struct DataModel { - void* padding1[CLASSPADDING_DATAMODEL__JOBID + PADDING_STRUCT]; - std::string jobId; + void* padding1[CLASSPADDING_DATAMODEL__JOBID + PADDING_STRUCT]; + std::string jobId; }; struct Game { - // 2010 has a class size of 104 bytes - void* padding1[8]; - std::shared_ptr dataModel; - void* padding2[9]; + // 2010 has a class size of 104 bytes + void* padding1[8]; + std::shared_ptr dataModel; + void* padding2[9]; }; const auto Game__initializeClass = (Game * (__thiscall*)(Game* _this, int a2))0x455D40; @@ -34,21 +34,21 @@ const auto ScriptContext__execute = (void (__thiscall*)(void* _this, int identit struct Http { #if PADDING_STRUCT != 0 - void* padding1[1]; + void* padding1[1]; #endif - std::string alternateUrl; - void* padding2[3 + PADDING_STRUCT]; - std::string url; + std::string alternateUrl; + void* padding2[3 + PADDING_STRUCT]; + std::string url; }; // const auto DataModel__createDataModel = (std::shared_ptr(__thiscall*)(bool startHeartbeat))ADDRESS_DATAMODEL__CREATEDATAMODEL; struct Packet { - void* padding1[7]; - unsigned int length; - void* padding2[1]; - unsigned char* data; + void* padding1[7]; + unsigned int length; + void* padding2[1]; + unsigned char* data; }; struct ConcurrentRakPeer {}; @@ -56,9 +56,9 @@ struct RakPeerInterface {}; struct ServerReplicator { - void* padding1[1869]; // offset of 0 -> 7476 - bool padding2; // offset of 7476 -> 7477 - bool isAuthenticated; // offset of 7477 -> 7478 + void* padding1[1869]; // offset of 0 -> 7476 + bool padding2; // offset of 7476 -> 7477 + bool isAuthenticated; // offset of 7477 -> 7478 }; // 2010 struct definitions: @@ -71,8 +71,8 @@ const auto CWorkspace__ExecUrlScript = (HRESULT(__stdcall*)(CWorkspace * workspa struct CRobloxDoc { - void* padding1[CLASSPADDING_CROBLOXDOC__WORKSPACE]; - CWorkspace* workspace; + void* padding1[CLASSPADDING_CROBLOXDOC__WORKSPACE]; + CWorkspace* workspace; }; struct CApp; @@ -91,8 +91,8 @@ const auto CRobloxApp__CreateDocument = (CRobloxDoc * (__thiscall*)(CRobloxApp * struct CCommandLineInfo { - void* padding1[3]; - BOOL m_bRunAutomated; + void* padding1[3]; + BOOL m_bRunAutomated; }; class CRobloxCommandLineInfo : public CCommandLineInfo {}; diff --git a/PolygonClientUtilities/Config.h b/PolygonClientUtilities/Config.h index 5ee2880..b2082d5 100644 --- a/PolygonClientUtilities/Config.h +++ b/PolygonClientUtilities/Config.h @@ -110,18 +110,18 @@ // RobloxPlayerBeta (2012) #ifdef PLAYER2012 /* - 2012 is a bit different in that the player executable is protected with - VMProtect. VMProtect offsets the memory locations randomly on startup. - This causes address definitions (such as the ones below) to look a bit off. + 2012 is a bit different in that the player executable is protected with + VMProtect. VMProtect offsets the memory locations randomly on startup. + This causes address definitions (such as the ones below) to look a bit off. - For example, if the beginning of the program is located at 0x00BF1000 and - you have a TrustCheck hook that is at 0x00DF20A0, VMProtect will offset the - memory location from 0x00000000 - 0x00FF0000. Thus, the 0x00BF0000 in - 0x00BF1000 is actually an offset. + For example, if the beginning of the program is located at 0x00BF1000 and + you have a TrustCheck hook that is at 0x00DF20A0, VMProtect will offset the + memory location from 0x00000000 - 0x00FF0000. Thus, the 0x00BF0000 in + 0x00BF1000 is actually an offset. - With that offset, the address you'd have to put for your TrustCheck hook will - be (0x00DF20A0 - 0x00BF0000) = 0x002020A0. Then, you just put that address - into the function. + With that offset, the address you'd have to put for your TrustCheck hook will + be (0x00DF20A0 - 0x00BF0000) = 0x002020A0. Then, you just put that address + into the function. */ // MFC specific definitions diff --git a/PolygonClientUtilities/Crypt.h b/PolygonClientUtilities/Crypt.h index 92dee27..1cf5552 100644 --- a/PolygonClientUtilities/Crypt.h +++ b/PolygonClientUtilities/Crypt.h @@ -9,11 +9,11 @@ extern Crypt__verifySignatureBase64_t Crypt__verifySignatureBase64; class Crypt { - HCRYPTPROV context; - HCRYPTKEY key; + HCRYPTPROV context; + HCRYPTKEY key; public: - Crypt(); - ~Crypt(); - bool verifySignatureBase64(std::string message, std::string signatureBase64, ALG_ID algorithm); + Crypt(); + ~Crypt(); + bool verifySignatureBase64(std::string message, std::string signatureBase64, ALG_ID algorithm); }; \ No newline at end of file diff --git a/PolygonClientUtilities/Http.cpp b/PolygonClientUtilities/Http.cpp index 0fc0983..4e644b3 100644 --- a/PolygonClientUtilities/Http.cpp +++ b/PolygonClientUtilities/Http.cpp @@ -3,194 +3,194 @@ #include "Util.h" #define CHECK(condition, code) \ - if(!error) { \ - if ((condition)) { \ - error = code; \ - } \ - } + if(!error) { \ + if ((condition)) { \ + error = code; \ + } \ + } Http__httpGetPostWinInet_t Http__httpGetPostWinInet = (Http__httpGetPostWinInet_t)ADDRESS_HTTP__HTTPGETPOSTWININET; Http__trustCheck_t Http__trustCheck = (Http__trustCheck_t)ADDRESS_HTTP__TRUSTCHECK; size_t write(char* contents, size_t size, size_t memory, void* pointer) { - ((std::string*)pointer)->append((char*)contents, size * memory); - return size * memory; + ((std::string*)pointer)->append((char*)contents, size * memory); + return size * memory; } void __fastcall Http__httpGetPostWinInet_hook(Http* _this, void*, bool isPost, int a3, bool compressData, LPCSTR additionalHeaders, int a6) { - CURLU* curl = curl_url(); - CURLUcode result = curl_url_set(curl, CURLUPART_URL, _this->url.c_str(), 0); + CURLU* curl = curl_url(); + CURLUcode result = curl_url_set(curl, CURLUPART_URL, _this->url.c_str(), 0); - Http _changed = *_this; + Http _changed = *_this; - if (!result) - { - char* path; - char* host; - char* query; + if (!result) + { + char* path; + char* host; + char* query; - curl_url_get(curl, CURLUPART_PATH, &path, 0); - curl_url_get(curl, CURLUPART_HOST, &host, 0); - curl_url_get(curl, CURLUPART_QUERY, &query, 0); - curl_url_cleanup(curl); + curl_url_get(curl, CURLUPART_PATH, &path, 0); + curl_url_get(curl, CURLUPART_HOST, &host, 0); + curl_url_get(curl, CURLUPART_QUERY, &query, 0); + curl_url_cleanup(curl); - if (path != NULL && host != NULL && query != NULL) - { - std::string _path = Util::toLower(std::string(path)); - std::string _host = std::string(host); - std::string _query = std::string(query); + if (path != NULL && host != NULL && query != NULL) + { + std::string _path = Util::toLower(std::string(path)); + std::string _host = std::string(host); + std::string _query = std::string(query); - if (_host == "roblox.com" || _host == "www.roblox.com") - { - if (_path == "/asset" || _path == "/asset/" || _path == "/asset/default.ashx") - { - _changed.url = "https://assetdelivery.roblox.com/v1/asset/?" + _query; - _this = &_changed; - } - else if (_path == "/thumbs/asset.ashx" || _path == "/thumbs/avatar.ashx") - { - /* - Both Roblox endpoints require thumbnailFormatId to be set. We will make the default value for it as 0. + if (_host == "roblox.com" || _host == "www.roblox.com") + { + if (_path == "/asset" || _path == "/asset/" || _path == "/asset/default.ashx") + { + _changed.url = "https://assetdelivery.roblox.com/v1/asset/?" + _query; + _this = &_changed; + } + else if (_path == "/thumbs/asset.ashx" || _path == "/thumbs/avatar.ashx") + { + /* + Both Roblox endpoints require thumbnailFormatId to be set. We will make the default value for it as 0. - Asset.ashx -> requires overrideModeration (default false) -> /asset/request-thumbnail-fix - Avatar.ashx -> requires dummy (default false) -> /avatar/request-thumbnail-fix + Asset.ashx -> requires overrideModeration (default false) -> /asset/request-thumbnail-fix + Avatar.ashx -> requires dummy (default false) -> /avatar/request-thumbnail-fix - 1. Parse query - 2. Construct a brand new blank query with thumbnailFormatId as 0 and dummy/overrideModeration as false (if Avatar.ashx or Asset.ashx) - 3. Merge the old query with priority over the old query so that if they declared any of the special variables, ours gets overwritten - 4. Rename id (if found) to assetId or userId (specific to the endpoint) - 5. Append to the Roblox url (specific to the endpoint) - 6. Fetch Roblox API - 7. Parse JSON - 8. Set the URL as the given url - */ + 1. Parse query + 2. Construct a brand new blank query with thumbnailFormatId as 0 and dummy/overrideModeration as false (if Avatar.ashx or Asset.ashx) + 3. Merge the old query with priority over the old query so that if they declared any of the special variables, ours gets overwritten + 4. Rename id (if found) to assetId or userId (specific to the endpoint) + 5. Append to the Roblox url (specific to the endpoint) + 6. Fetch Roblox API + 7. Parse JSON + 8. Set the URL as the given url + */ - std::string api = "https://www.roblox.com/" + std::string(_path == "/thumbs/asset.ashx" ? "asset" : "avatar") + "/request-thumbnail-fix"; + std::string api = "https://www.roblox.com/" + std::string(_path == "/thumbs/asset.ashx" ? "asset" : "avatar") + "/request-thumbnail-fix"; - std::map source = Util::parseQueryString(query); - std::map fixed = { - { _path == "/thumbs/asset.ashx" ? "overrideModeration" : "dummy", "false" }, - { "thumbnailFormatId", "0" } - }; - - for (auto& pair : source) - { - fixed[Util::toLower(pair.first)] = pair.second; - } + std::map source = Util::parseQueryString(query); + std::map fixed = { + { _path == "/thumbs/asset.ashx" ? "overrideModeration" : "dummy", "false" }, + { "thumbnailFormatId", "0" } + }; + + for (auto& pair : source) + { + fixed[Util::toLower(pair.first)] = pair.second; + } - if (fixed.find("id") != fixed.end()) - { - auto handler = fixed.extract("id"); - handler.key() = _path == "/thumbs/asset.ashx" ? "assetId" : "userId"; - - fixed.insert(std::move(handler)); - } + if (fixed.find("id") != fixed.end()) + { + auto handler = fixed.extract("id"); + handler.key() = _path == "/thumbs/asset.ashx" ? "assetId" : "userId"; + + fixed.insert(std::move(handler)); + } - api += Util::joinQueryString(fixed); - - // get the api response - CURL* curl = curl_easy_init(); - CURLcode result; - long response = 0; - std::string data; + api += Util::joinQueryString(fixed); + + // get the api response + CURL* curl = curl_easy_init(); + CURLcode result; + long response = 0; + std::string data; - if (!curl) - { - throw std::runtime_error("Failed to initialize cURL"); - } + if (!curl) + { + throw std::runtime_error("Failed to initialize cURL"); + } - curl_easy_setopt(curl, CURLOPT_URL, api); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data); + curl_easy_setopt(curl, CURLOPT_URL, api); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data); - result = curl_easy_perform(curl); - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response); + result = curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response); - curl_easy_cleanup(curl); + curl_easy_cleanup(curl); - if (result != CURLE_OK || response != 200) - { - throw std::runtime_error("Unexpected error occurred when fetching Roblox API: 0x1"); - } + if (result != CURLE_OK || response != 200) + { + throw std::runtime_error("Unexpected error occurred when fetching Roblox API: 0x1"); + } - rapidjson::Document document; - document.Parse(data.c_str()); + rapidjson::Document document; + document.Parse(data.c_str()); - // Ryelow should fucking kill herself - int error = 0; + // Ryelow should fucking kill herself + int error = 0; - CHECK(document.HasParseError(), 0x02); - CHECK(!document.HasMember("d"), 0x03); - CHECK(!document["d"].IsObject(), 0x04); - CHECK(!document["d"].HasMember("url"), 0x04); - CHECK(!document["d"]["url"].IsString(), 0x04); + CHECK(document.HasParseError(), 0x02); + CHECK(!document.HasMember("d"), 0x03); + CHECK(!document["d"].IsObject(), 0x04); + CHECK(!document["d"].HasMember("url"), 0x04); + CHECK(!document["d"]["url"].IsString(), 0x04); - if (error != 0) - { - throw std::runtime_error("Unexpected error occurred when fetching Roblox API: 0x0" + std::to_string(error)); - } + if (error != 0) + { + throw std::runtime_error("Unexpected error occurred when fetching Roblox API: 0x0" + std::to_string(error)); + } - _changed.url = document["d"]["url"].GetString(); - _this = &_changed; - } - } - } - } + _changed.url = document["d"]["url"].GetString(); + _this = &_changed; + } + } + } + } - Http__httpGetPostWinInet(_this, isPost, a3, compressData, additionalHeaders, a6); + Http__httpGetPostWinInet(_this, isPost, a3, compressData, additionalHeaders, a6); } BOOL __fastcall Http__trustCheck_hook(const char* url) { - if (strlen(url) == 7 && !Util::isASCII(url)) - { - // so the client does this really fucking stupid thing where if it opens an ie window, - // it passes a char**, and not a char* - // no idea if thats a detours quirk (i doubt it) or if thats how its just actually handled - // practically no url is ever going to be seven characters long so it doesn't really matter + if (strlen(url) == 7 && !Util::isASCII(url)) + { + // so the client does this really fucking stupid thing where if it opens an ie window, + // it passes a char**, and not a char* + // no idea if thats a detours quirk (i doubt it) or if thats how its just actually handled + // practically no url is ever going to be seven characters long so it doesn't really matter - url = *(char**)url; // wHOEVER DID THIS FUCKING CAST NEEDS TO GET RAPED BY 10 GORILLION GRIGRGERS - } + url = *(char**)url; // wHOEVER DID THIS FUCKING CAST NEEDS TO GET RAPED BY 10 GORILLION GRIGRGERS + } - std::string _url = std::string(url); + std::string _url = std::string(url); - // checking for embedded schemes must come BEFORE checking if it's valid - // cURL does not treat embedded resources as URLs + // checking for embedded schemes must come BEFORE checking if it's valid + // cURL does not treat embedded resources as URLs - if (_url == "about:blank") - { - return true; - } + if (_url == "about:blank") + { + return true; + } - for (std::string allowedEmbeddedScheme : Util::allowedEmbeddedSchemes) - { - if (_url.rfind(allowedEmbeddedScheme + ":", 0) == 0) - { - return true; - } - } + for (std::string allowedEmbeddedScheme : Util::allowedEmbeddedSchemes) + { + if (_url.rfind(allowedEmbeddedScheme + ":", 0) == 0) + { + return true; + } + } - CURLU* curl = curl_url(); - CURLUcode result = curl_url_set(curl, CURLUPART_URL, url, 0); + CURLU* curl = curl_url(); + CURLUcode result = curl_url_set(curl, CURLUPART_URL, url, 0); - if (result != CURLE_OK) - { - return false; - } + if (result != CURLE_OK) + { + return false; + } - char* scheme; - char* host; + char* scheme; + char* host; - curl_url_get(curl, CURLUPART_SCHEME, &scheme, 0); - curl_url_get(curl, CURLUPART_HOST, &host, 0); - curl_url_cleanup(curl); + curl_url_get(curl, CURLUPART_SCHEME, &scheme, 0); + curl_url_get(curl, CURLUPART_HOST, &host, 0); + curl_url_cleanup(curl); - if (std::find(Util::allowedSchemes.begin(), Util::allowedSchemes.end(), std::string(scheme)) != Util::allowedSchemes.end()) - { - return std::find(Util::allowedHosts.begin(), Util::allowedHosts.end(), std::string(host)) != Util::allowedHosts.end(); - } + if (std::find(Util::allowedSchemes.begin(), Util::allowedSchemes.end(), std::string(scheme)) != Util::allowedSchemes.end()) + { + return std::find(Util::allowedHosts.begin(), Util::allowedHosts.end(), std::string(host)) != Util::allowedHosts.end(); + } - return false; + return false; } \ No newline at end of file diff --git a/PolygonClientUtilities/Patches.h b/PolygonClientUtilities/Patches.h index 2792cd2..adaf491 100644 --- a/PolygonClientUtilities/Patches.h +++ b/PolygonClientUtilities/Patches.h @@ -2,13 +2,13 @@ namespace Patches { - typedef std::pair Patch; + typedef std::pair Patch; - extern std::vector patchList; + extern std::vector patchList; - LONG Apply(); - VOID ResolveOffset(); - INT GetAddressByOffset(int address); + LONG Apply(); + VOID ResolveOffset(); + INT GetAddressByOffset(int address); } #define START_PATCH_LIST() std::vector Patches::patchList = { diff --git a/PolygonClientUtilities/dllmain.cpp b/PolygonClientUtilities/dllmain.cpp index a6879e0..d8d778f 100644 --- a/PolygonClientUtilities/dllmain.cpp +++ b/PolygonClientUtilities/dllmain.cpp @@ -80,7 +80,11 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv ExitProcess(EXIT_FAILURE); } - curl_global_init(CURL_GLOBAL_DEFAULT); + CURLcode result = curl_global_init(CURL_GLOBAL_DEFAULT); + if (result != CURLE_OK) + { + ExitProcess(EXIT_FAILURE); + } } if (ul_reason_for_call == DLL_PROCESS_DETACH)