This commit is contained in:
lightbulblighter 2022-06-05 03:13:14 -07:00
commit f12a0646e0
No known key found for this signature in database
GPG Key ID: 0B2452F9DE0E2D01
9 changed files with 40 additions and 378 deletions

3
.gitignore vendored
View File

@ -397,4 +397,5 @@ FodyWeavers.xsd
# JetBrains Rider
*.sln.iml
vcpkg_installed/
vcpkg_installed/
vcpkg/

View File

@ -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

View File

@ -3,7 +3,6 @@
#include "Patches.h"
#include "Config.h"
#include "Util.h"
#include "LUrlParser.h"
static bool hasJobId = false;
static bool setJobId = false;

View File

@ -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;
}

View File

@ -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 <algorithm>
#include <cstring>
#include <stdlib.h>
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();
/*
* <scheme>:<scheme-specific-part>
* <scheme> := [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;
}
/*
* //<user>:<password>@<host>:<port>/<url-path>
* 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 <host>:<port> 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;
}

View File

@ -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 <string>
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

View File

@ -1,5 +0,0 @@
#include "pch.h"
#include "TrustCheck.h"
#include "Patches.h"
#include "Util.h"

View File

@ -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;

View File

@ -4,7 +4,6 @@
#include "ScriptContext.h"
#include "Http.h"
#include "TrustCheck.h"
#include "Crypt.h"
#ifdef ARBITERBUILD