diff --git a/.gitignore b/.gitignore index 18dd56c..6532415 100644 --- a/.gitignore +++ b/.gitignore @@ -397,4 +397,5 @@ FodyWeavers.xsd # JetBrains Rider *.sln.iml -vcpkg_installed/ \ No newline at end of file +vcpkg_installed/ +vcpkg/ diff --git a/PolygonClientUtilities/Config.h b/PolygonClientUtilities/Config.h index c7408e8..5ee2880 100644 --- a/PolygonClientUtilities/Config.h +++ b/PolygonClientUtilities/Config.h @@ -32,7 +32,7 @@ #define ADDRESS_DATAMODEL__CREATEDATAMODEL 0x005DC150 #define ADDRESS_GAME__CONSTRUCT 0x0047DBF0 #define ADDRESS_HTTP__HTTPGETPOSTWININET 0x006A9210 -#define ADDRESS_HTTP__TRUSTCHECK 0x005A2680 +#define ADDRESS_HTTP__TRUSTCHECK 0x005A2680 // MFC specific definitions #define CLASSLOCATION_CROBLOXAPP 0x00BFF898 diff --git a/PolygonClientUtilities/Hooks.cpp b/PolygonClientUtilities/Hooks.cpp index c4cd7f5..1589a54 100644 --- a/PolygonClientUtilities/Hooks.cpp +++ b/PolygonClientUtilities/Hooks.cpp @@ -3,7 +3,6 @@ #include "Patches.h" #include "Config.h" #include "Util.h" -#include "LUrlParser.h" static bool hasJobId = false; static bool setJobId = false; diff --git a/PolygonClientUtilities/Http.cpp b/PolygonClientUtilities/Http.cpp index d34e25f..fdf65f9 100644 --- a/PolygonClientUtilities/Http.cpp +++ b/PolygonClientUtilities/Http.cpp @@ -7,10 +7,10 @@ Http__trustCheck_t Http__trustCheck = (Http__trustCheck_t)ADDRESS_HTTP__TRUSTCHE void __fastcall Http__httpGetPostWinInet_hook(Http* _this, void*, bool isPost, int a3, bool compressData, LPCSTR additionalHeaders, int a6) { - Http _changed = *_this; - CURLU* curl = curl_url(); - CURLUcode result = curl_url_set(curl, CURLUPART_URL, _this->url.c_str(), 0); + CURLUcode result = curl_url_set(curl, CURLUPART_URL, _this->url.c_str(), CURLU_NON_SUPPORT_SCHEME); + + Http _changed = *_this; if (!result) { @@ -24,24 +24,31 @@ void __fastcall Http__httpGetPostWinInet_hook(Http* _this, void*, bool isPost, i if (path != NULL && host != NULL && query != NULL) { - std::string _path = std::string(path); + std::string _path = Util::toLower(std::string(path)); std::string _host = std::string(host); - std::string _query = Util::toLower(std::string(query)); - - _path.erase(_path.begin()); + std::string _query = std::string(query); if (_host == "roblox.com" || _host == "www.roblox.com") { - if (_path == "asset" || _path == "asset/" || _path == "asset/default.ashx") + 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") + { + // hmmm + // https://www.roblox.com/asset/request-thumbnail-fix?assetId=1818&assetVersionId=0&width=420&height=420&imageFormat=Png&thumbnailFormatId=296&overrideModeration=false + // instead of proxying requests through the webserver, can we fetch this response in the client and parse the json? + // we can do the same thing for /avatar/request/thumbnail-fix (https://www.roblox.com/avatar/request-thumbnail-fix?userId=86890093&width=100&height=100&imageFormat=Png&thumbnailFormatId=41&dummy=false) + + _changed.url = "http://polygon.pizzaboxer.xyz/Thumbs/Asset.ashx?" + _query + "&roblox=true"; + _this = &_changed; } } } } - _this = &_changed; - Http__httpGetPostWinInet(_this, isPost, a3, compressData, additionalHeaders, a6); } @@ -57,19 +64,34 @@ BOOL __fastcall Http__trustCheck_hook(const char* url) url = *(char**)url; } + printf("Http::trustCheck() %s\n", url); + CURLU* curl = curl_url(); CURLUcode result = curl_url_set(curl, CURLUPART_URL, url, 0); + 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 + + if (_url == "about:blank") + { + return true; + } + + for (std::string allowedEmbeddedScheme : Util::allowedEmbeddedSchemes) + { + if (_url.find(allowedEmbeddedScheme + ":") == 0) + { + return true; + } + } + if (result != 0) { return false; } - if (url == std::string("about:blank")) - { - return true; - } - char* scheme; char* host; @@ -81,10 +103,5 @@ BOOL __fastcall Http__trustCheck_hook(const char* url) return std::find(Util::allowedHosts.begin(), Util::allowedHosts.end(), std::string(host)) != Util::allowedHosts.end(); } - if (std::find(Util::allowedEmbeddedSchemes.begin(), Util::allowedEmbeddedSchemes.end(), std::string(scheme)) != Util::allowedEmbeddedSchemes.end()) - { - return true; - } - return false; } diff --git a/PolygonClientUtilities/LUrlParser.cpp b/PolygonClientUtilities/LUrlParser.cpp deleted file mode 100644 index f8bb998..0000000 --- a/PolygonClientUtilities/LUrlParser.cpp +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Lightweight URL & URI parser (RFC 1738, RFC 3986) - * https://github.com/corporateshark/LUrlParser - * - * The MIT License (MIT) - * - * Copyright (C) 2015-2020 Sergey Kosarevsky (sk@linderdaum.com) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "LUrlParser.h" - -#include -#include -#include - -namespace -{ - // check if the scheme name is valid - bool isSchemeValid(const std::string& schemeName) - { - for (auto c : schemeName) - { - if (!isalpha(c) && c != '+' && c != '-' && c != '.') return false; - } - - return true; - } -} - -bool LUrlParser::ParseURL::getPort(int* outPort) const -{ - if (!isValid()) { return false; } - - const int port = atoi(port_.c_str()); - - if (port <= 0 || port > 65535) { return false; } - - if (outPort) { *outPort = port; } - - return true; -} - -// based on RFC 1738 and RFC 3986 -LUrlParser::ParseURL LUrlParser::ParseURL::parseURL(const std::string& URL) -{ - LUrlParser::ParseURL result; - - const char* currentString = URL.c_str(); - - /* - * : - * := [a-z\+\-\.]+ - * For resiliency, programs interpreting URLs should treat upper case letters as equivalent to lower case in scheme names - */ - - // try to read scheme - { - const char* localString = strchr(currentString, ':'); - - if (!localString) - { - return ParseURL(LUrlParserError_NoUrlCharacter); - } - - // save the scheme name - result.scheme_ = std::string(currentString, localString - currentString); - - if (!isSchemeValid(result.scheme_)) - { - return ParseURL(LUrlParserError_InvalidSchemeName); - } - - // scheme should be lowercase - std::transform(result.scheme_.begin(), result.scheme_.end(), result.scheme_.begin(), ::tolower); - - // skip ':' - currentString = localString + 1; - } - - /* - * //:@:/ - * any ":", "@" and "/" must be normalized - */ - - // skip "//" - if (*currentString++ != '/') return ParseURL(LUrlParserError_NoDoubleSlash); - if (*currentString++ != '/') return ParseURL(LUrlParserError_NoDoubleSlash); - - // check if the user name and password are specified - bool bHasUserName = false; - - const char* localString = currentString; - - while (*localString) - { - if (*localString == '@') - { - // user name and password are specified - bHasUserName = true; - break; - } - else if (*localString == '/') - { - // end of : specification - bHasUserName = false; - break; - } - - localString++; - } - - // user name and password - localString = currentString; - - if (bHasUserName) - { - // read user name - while (*localString && *localString != ':' && *localString != '@') localString++; - - result.userName_ = std::string(currentString, localString - currentString); - - // proceed with the current pointer - currentString = localString; - - if (*currentString == ':') - { - // skip ':' - currentString++; - - // read password - localString = currentString; - - while (*localString && *localString != '@') localString++; - - result.password_ = std::string(currentString, localString - currentString); - - currentString = localString; - } - - // skip '@' - if (*currentString != '@') - { - return ParseURL(LUrlParserError_NoAtSign); - } - - currentString++; - } - - const bool bHasBracket = (*currentString == '['); - - // go ahead, read the host name - localString = currentString; - - while (*localString) - { - if (bHasBracket && *localString == ']') - { - // end of IPv6 address - localString++; - break; - } - else if (!bHasBracket && (*localString == ':' || *localString == '/')) - { - // port number is specified - break; - } - - localString++; - } - - result.host_ = std::string(currentString, localString - currentString); - - currentString = localString; - - // is port number specified? - if (*currentString == ':') - { - currentString++; - - // read port number - localString = currentString; - - while (*localString && *localString != '/') localString++; - - result.port_ = std::string(currentString, localString - currentString); - - currentString = localString; - } - - // end of string - if (!*currentString) - { - result.errorCode_ = LUrlParserError_Ok; - - return result; - } - - // skip '/' - if (*currentString != '/') - { - return ParseURL(LUrlParserError_NoSlash); - } - - currentString++; - - // parse the path - localString = currentString; - - while (*localString && *localString != '#' && *localString != '?') localString++; - - result.path_ = std::string(currentString, localString - currentString); - - currentString = localString; - - // check for query - if (*currentString == '?') - { - // skip '?' - currentString++; - - // read query - localString = currentString; - - while (*localString&&* localString != '#') localString++; - - result.query_ = std::string(currentString, localString - currentString); - - currentString = localString; - } - - // check for fragment - if (*currentString == '#') - { - // skip '#' - currentString++; - - // read fragment - localString = currentString; - - while (*localString) localString++; - - result.fragment_ = std::string(currentString, localString - currentString); - - currentString = localString; - } - - result.errorCode_ = LUrlParserError_Ok; - - return result; -} diff --git a/PolygonClientUtilities/LUrlParser.h b/PolygonClientUtilities/LUrlParser.h deleted file mode 100644 index f434092..0000000 --- a/PolygonClientUtilities/LUrlParser.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Lightweight URL & URI parser (RFC 1738, RFC 3986) - * https://github.com/corporateshark/LUrlParser - * - * The MIT License (MIT) - * - * Copyright (C) 2015-2020 Sergey Kosarevsky (sk@linderdaum.com) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#pragma once - -#include - -namespace LUrlParser -{ - enum LUrlParserError - { - LUrlParserError_Ok = 0, - LUrlParserError_Uninitialized = 1, - LUrlParserError_NoUrlCharacter = 2, - LUrlParserError_InvalidSchemeName = 3, - LUrlParserError_NoDoubleSlash = 4, - LUrlParserError_NoAtSign = 5, - LUrlParserError_UnexpectedEndOfLine = 6, - LUrlParserError_NoSlash = 7, - }; - - class ParseURL - { - public: - LUrlParserError errorCode_ = LUrlParserError_Uninitialized; - std::string scheme_; - std::string host_; - std::string port_; - std::string path_; - std::string query_; - std::string fragment_; - std::string userName_; - std::string password_; - - /// return 'true' if the parsing was successful - bool isValid() const { return errorCode_ == LUrlParserError_Ok; } - - /// helper to convert the port number to int, return 'true' if the port is valid (within the 0..65535 range) - bool getPort(int* outPort) const; - - /// parse the URL - static ParseURL parseURL(const std::string& url); - - private: - ParseURL() = default; - explicit ParseURL(LUrlParserError errorCode) - : errorCode_(errorCode) - {} - }; -} // namespace LUrlParser diff --git a/PolygonClientUtilities/TrustCheck.cpp b/PolygonClientUtilities/TrustCheck.cpp deleted file mode 100644 index 4cac1ce..0000000 --- a/PolygonClientUtilities/TrustCheck.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "pch.h" -#include "TrustCheck.h" -#include "Patches.h" -#include "Util.h" - diff --git a/PolygonClientUtilities/TrustCheck.h b/PolygonClientUtilities/TrustCheck.h deleted file mode 100644 index e56aef3..0000000 --- a/PolygonClientUtilities/TrustCheck.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "Classes.h" - -typedef BOOL(__thiscall* Http__trustCheck_t)(const char* url); -BOOL __fastcall Http__trustCheck_hook(const char* url); -extern Http__trustCheck_t Http__trustCheck; diff --git a/PolygonClientUtilities/dllmain.cpp b/PolygonClientUtilities/dllmain.cpp index ec11cf8..7d940a9 100644 --- a/PolygonClientUtilities/dllmain.cpp +++ b/PolygonClientUtilities/dllmain.cpp @@ -4,7 +4,6 @@ #include "ScriptContext.h" #include "Http.h" -#include "TrustCheck.h" #include "Crypt.h" #ifdef ARBITERBUILD