Make trust check only patch for Tadah 2014
Only the trust check patch is needed for this branch, and I'm also retaining the Output patch for easy debugging in case we need it. Some minor tweaks have been made to the two patches that have been kept to remove anything that's now unneeded and also any tweaks needed to make it work with 2014.
This commit is contained in:
parent
0653224cf9
commit
ea84438423
|
|
@ -1,103 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#define MFC2011
|
||||
#define PLAYERBUILD
|
||||
#define ARBITERBUILD
|
||||
#define OUTPUT
|
||||
|
||||
// #define DEBUG_SERVERREPLICATOR__PROCESSPACKET
|
||||
|
||||
// when PLAYERBUILD is defined, the following changes occur for 2010 and 2012 only:
|
||||
// the -jobId arg is parsed
|
||||
|
||||
// when ARBITERBUILD is defined, the following changes occur:
|
||||
// DataModel::getJobId is hooked
|
||||
// DataModel::~DataModel is hooked
|
||||
// StandardOut::print is hooked
|
||||
// Network::RakNetAddressToString is hooked
|
||||
// -jobId arg becomes available
|
||||
// HTTP requests and output messages are logged to a file
|
||||
|
||||
// RobloxApp (2010)
|
||||
#ifdef MFC2010
|
||||
#define CLASSPADDING_DATAMODEL__JOBID 729 // when compiled as debug, this must be 728
|
||||
|
||||
#define ADDRESS_DATAMODEL__GETJOBID 0x005CACC0
|
||||
#define ADDRESS_STANDARDOUT__PRINT 0x0059F340
|
||||
#define ADDRESS_NETWORK__RAKNETADDRESSTOSTRING 0x004FC1A0
|
||||
#define ADDRESS_HTTP__TRUSTCHECK 0x005A2680
|
||||
#define ADDRESS_CRYPT__VERIFYSIGNATUREBASE64 0x0079ECF0
|
||||
#define ADDRESS_SERVERREPLICATOR__SENDTOP 0x00506910
|
||||
#define ADDRESS_SERVERREPLICATOR__PROCESSPACKET 0x00507420
|
||||
|
||||
// MFC specific definitions
|
||||
#define CLASSLOCATION_CROBLOXAPP 0x00BFF898
|
||||
#define CLASSLOCATION_CAPP 0x00405D20
|
||||
|
||||
#define CLASSPADDING_CROBLOXDOC__WORKSPACE 40
|
||||
|
||||
#define ADDRESS_CAPP__CREATEGAME 0x00405D20
|
||||
#define ADDRESS_CAPP__ROBLOXAUTHENTICATE 0x00408060
|
||||
#define ADDRESS_CROBLOXAPP__INITINSTANCE 0x00452900
|
||||
#define ADDRESS_CROBLOXAPP__CREATEDOCUMENT 0x0044F6E0
|
||||
#define ADDRESS_CWORKSPACE__EXECURLSCRIPT 0x0047EC10
|
||||
#define ADDRESS_CROBLOXCOMMANDLINEINFO__PARSEPARAM 0x00450AC0
|
||||
#define ADDRESS_CCOMMANDLINEINFO__PARSELAST 0x007A80A0
|
||||
|
||||
// RakNet packet definitions
|
||||
#define ID_TIMESTAMP 25
|
||||
#define ID_SET_GLOBALS 95
|
||||
#define ID_REQUEST_CHARACTER 96
|
||||
#define ID_DATA 98
|
||||
#define ID_SUBMIT_TICKET 104
|
||||
#endif
|
||||
|
||||
// RobloxApp (2011)
|
||||
#ifdef MFC2011
|
||||
#define CLASSPADDING_DATAMODEL__JOBID 740 // when compiled as debug, this must be 739
|
||||
|
||||
#define ADDRESS_DATAMODEL__GETJOBID 0x005E70C0
|
||||
#define ADDRESS_DATAMODEL__DESTRUCT 0x006002A0
|
||||
#define ADDRESS_STANDARDOUT__PRINT 0x005B25E0
|
||||
#define ADDRESS_NETWORK__RAKNETADDRESSTOSTRING 0x0
|
||||
#define ADDRESS_HTTP__TRUSTCHECK 0x005B7050
|
||||
#define ADDRESS_CRYPT__VERIFYSIGNATUREBASE64 0x00809EC0
|
||||
#define ADDRESS_SERVERREPLICATOR__SENDTOP 0x00513E80
|
||||
#define ADDRESS_SERVERREPLICATOR__PROCESSTICKET 0x00514B60
|
||||
|
||||
// MFC specific definitions
|
||||
#define CLASSLOCATION_CROBLOXAPP 0x00CBA8A0
|
||||
#define CLASSLOCATION_CAPP 0x00406D80
|
||||
|
||||
#define CLASSPADDING_CROBLOXDOC__WORKSPACE 45
|
||||
|
||||
#define ADDRESS_CAPP__CREATEGAME 0x00406D80
|
||||
#define ADDRESS_CAPP__ROBLOXAUTHENTICATE 0x00409050
|
||||
#define ADDRESS_CROBLOXAPP__INITINSTANCE 0x004613C0
|
||||
#define ADDRESS_CROBLOXAPP__CREATEDOCUMENT 0x0045D030
|
||||
#define ADDRESS_CWORKSPACE__EXECURLSCRIPT 0x0049FC90
|
||||
#define ADDRESS_CROBLOXCOMMANDLINEINFO__PARSEPARAM 0x0045EE50
|
||||
#define ADDRESS_CCOMMANDLINEINFO__PARSELAST 0x0081354A
|
||||
|
||||
// RakNet definitions
|
||||
#define ID_SET_GLOBALS 127
|
||||
#define ID_DATA 129
|
||||
#define ID_REQUEST_MARKER 130
|
||||
#define ID_PHYSICS 131
|
||||
#define ID_CHAT_ALL 132
|
||||
#define ID_CHAT_TEAM 133
|
||||
#define ID_REPORT_ABUSE 134
|
||||
#define ID_SUBMIT_TICKET 135
|
||||
#define ID_CHAT_GAME 136
|
||||
#endif
|
||||
|
||||
// RobloxApp/RobloxPlayer (2012)
|
||||
#ifdef MFC2012
|
||||
#define ADDRESS_HTTP__TRUSTCHECK 0x006D5D20
|
||||
#define ADDRESS_CRYPT__VERIFYSIGNATUREBASE64 0x009B1D20
|
||||
#endif
|
||||
|
||||
// RobloxPlayerBeta (2012)
|
||||
#ifdef PLAYER2012
|
||||
// so 2012's a bit different
|
||||
// VMProtect likes to offset the memory locations randomly on startup
|
||||
// so defining the addresses here are a bit weird
|
||||
|
|
@ -111,24 +15,6 @@
|
|||
// with that offset, the address you'd have to put for your trust check hook will be 0x00DF20A0 - 0x00BF0000 = 0x002020A0
|
||||
// and you just put that address into the function
|
||||
|
||||
#define CLASSPADDING_DATAMODEL__JOBID 763 // when compiled as debug, this must be 762
|
||||
|
||||
#define ADDRESS_DATAMODEL__GETJOBID Patches::GetAddressByOffset(0x002079A0)
|
||||
#define ADDRESS_STANDARDOUT__PRINT Patches::GetAddressByOffset(0x0023A8C0)
|
||||
#define ADDRESS_NETWORK__RAKNETADDRESSTOSTRING 0x0
|
||||
#define ADDRESS_HTTP__TRUSTCHECK Patches::GetAddressByOffset(0x002020A0)
|
||||
#define ADDRESS_CRYPT__VERIFYSIGNATUREBASE64 Patches::GetAddressByOffset(0x00526330)
|
||||
|
||||
// Player specific definitions
|
||||
#define ADDRESS_APPLICATION__PARSEARGUMENTS Patches::GetAddressByOffset(0x00004E60)
|
||||
#endif
|
||||
|
||||
// RobloxStudioBeta (2012)
|
||||
#ifdef STUDIO2012
|
||||
#define ADDRESS_HTTP__TRUSTCHECK Patches::GetAddressByOffset(0x001931A0)
|
||||
#define ADDRESS_CRYPT__VERIFYSIGNATUREBASE64 Patches::GetAddressByOffset(0x004CD250)
|
||||
#endif
|
||||
|
||||
#define RR_STOP_PROCESSING_AND_DEALLOCATE 0
|
||||
#define RR_CONTINUE_PROCESSING 1
|
||||
#define RR_STOP_PROCESSING 2
|
||||
#define ADDRESS_HTTP__TRUSTCHECK 0x005CD760 //Patches::GetAddressByOffset(0x002020A0)
|
||||
#define ADDRESS_CRYPT__VERIFYSIGNATUREBASE64 0x00B6C9E0 //Patches::GetAddressByOffset(0x00526330)
|
||||
#define ADDRESS_STANDARDOUT__PRINT 0x005E3330
|
||||
Binary file not shown.
|
|
@ -4,8 +4,6 @@
|
|||
//#pragma warning(disable : 4996)
|
||||
|
||||
HANDLE Logger::handle;
|
||||
std::ofstream Logger::outputLog;
|
||||
std::ofstream Logger::httpLog;
|
||||
|
||||
void Logger::Initialize(const std::string jobId)
|
||||
{
|
||||
|
|
@ -24,57 +22,4 @@ void Logger::Initialize(const std::string jobId)
|
|||
// printf("Service starting...\n");
|
||||
// printf("Intializing Roblox Web Service\n");
|
||||
// printf("Service Started on port 64989\n");
|
||||
|
||||
Logger::outputLog = std::ofstream(jobId + std::string("-Output.txt"));
|
||||
Logger::httpLog = std::ofstream(jobId + std::string("-Http.txt"));
|
||||
}
|
||||
|
||||
void Logger::Log(LogType type, const std::string message)
|
||||
{
|
||||
if (!handle) return;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case LogType::Output:
|
||||
outputLog << "[" << Logger::UtcTime() << "] " << message.c_str() << std::endl;
|
||||
break;
|
||||
case LogType::Http:
|
||||
httpLog << "[" << Logger::UtcTime() << "] " << message.c_str() << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::Print(int type, const std::string message)
|
||||
{
|
||||
if (!Logger::handle) return;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case 1: // RBX::MESSAGE_OUTPUT:
|
||||
Logger::Log(LogType::Output, std::string("[MESSAGE_OUTPUT] ") + message);
|
||||
SetConsoleTextAttribute(Logger::handle, FOREGROUND_BLUE | FOREGROUND_INTENSITY);
|
||||
break;
|
||||
case 0: // RBX::MESSAGE_INFO:
|
||||
Logger::Log(LogType::Output, std::string("[MESSAGE_INFO] ") + message);
|
||||
SetConsoleTextAttribute(Logger::handle, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
break;
|
||||
case 2: // RBX::MESSAGE_WARNING:
|
||||
Logger::Log(LogType::Output, std::string("[MESSAGE_WARNING] ") + message);
|
||||
SetConsoleTextAttribute(Logger::handle, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
break;
|
||||
case 3: // RBX::MESSAGE_ERROR:
|
||||
Logger::Log(LogType::Output, std::string("[MESSAGE_ERROR] ") + message);
|
||||
SetConsoleTextAttribute(Logger::handle, FOREGROUND_RED | FOREGROUND_INTENSITY);
|
||||
break;
|
||||
}
|
||||
printf("%s\n", message.c_str());
|
||||
SetConsoleTextAttribute(Logger::handle, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
}
|
||||
|
||||
std::string Logger::UtcTime()
|
||||
{
|
||||
std::stringstream time;
|
||||
std::time_t now = std::time(NULL);
|
||||
time << std::put_time(std::localtime(&now), "%F %T");
|
||||
return time.str();
|
||||
}
|
||||
|
|
@ -6,13 +6,7 @@ enum class LogType { Output, Http };
|
|||
|
||||
class Logger
|
||||
{
|
||||
private:
|
||||
static std::ofstream outputLog;
|
||||
static std::ofstream httpLog;
|
||||
public:
|
||||
static HANDLE handle;
|
||||
static void Initialize(const std::string jobId);
|
||||
static void Log(LogType type, const std::string message);
|
||||
static void Print(int type, const std::string message);
|
||||
static std::string UtcTime();
|
||||
};
|
||||
|
|
@ -33,10 +33,10 @@
|
|||
<ClInclude Include="LUrlParser.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Logger.h">
|
||||
<ClInclude Include="Util.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Util.h">
|
||||
<ClInclude Include="Logger.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
|
|
@ -56,10 +56,10 @@
|
|||
<ClCompile Include="LUrlParser.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Logger.cpp">
|
||||
<ClCompile Include="Util.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Util.cpp">
|
||||
<ClCompile Include="Logger.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,71 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
#include <oaidl.h>
|
||||
|
||||
#ifdef ARBITERBUILD
|
||||
struct DataModel
|
||||
{
|
||||
void* padding1[CLASSPADDING_DATAMODEL__JOBID];
|
||||
std::string jobId;
|
||||
};
|
||||
|
||||
struct Packet
|
||||
{
|
||||
void* padding1[7];
|
||||
unsigned int length;
|
||||
void* padding2[1];
|
||||
unsigned char* data;
|
||||
};
|
||||
|
||||
struct ConcurrentRakPeer {};
|
||||
struct RakPeerInterface {};
|
||||
|
||||
struct ServerReplicator
|
||||
{
|
||||
void* padding1[1869]; // offset of 0 -> 7476
|
||||
bool padding2; // offset of 7476 -> 7477
|
||||
bool isAuthenticated; // offset of 7477 -> 7478
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(MFC2010) || defined(MFC2011)
|
||||
// 2010 struct definitions:
|
||||
// 0x47E010: CWorkspace->DoExecScript()
|
||||
// 0x47EC10: CWorkspace->ExecUrlScript()
|
||||
|
||||
class CWorkspace;
|
||||
|
||||
const auto CWorkspace__ExecUrlScript = (HRESULT(__stdcall*)(CWorkspace * workspace, LPCWSTR, VARIANTARG, VARIANTARG, VARIANTARG, VARIANTARG, LPVOID))ADDRESS_CWORKSPACE__EXECURLSCRIPT;
|
||||
|
||||
struct CRobloxDoc
|
||||
{
|
||||
void* padding1[CLASSPADDING_CROBLOXDOC__WORKSPACE];
|
||||
CWorkspace* workspace;
|
||||
};
|
||||
|
||||
struct CApp;
|
||||
|
||||
// const auto CApp__CreateGame = (CWorkspace * (__thiscall*)(CApp * _this, int, LPCWSTR))ADDRESS_CAPP__CREATEGAME;
|
||||
const auto CApp__RobloxAuthenticate = (void * (__thiscall*)(CApp * _this, LPVOID, LPCWSTR, LPCWSTR))ADDRESS_CAPP__ROBLOXAUTHENTICATE;
|
||||
|
||||
// 2010 struct definitions:
|
||||
// 0x405D20: CRobloxApp->CreateDocument()
|
||||
// 0x44F6F0: CRobloxApp->ExitInstance()
|
||||
// 0x452900: CRobloxApp->InitInstance()
|
||||
|
||||
struct CRobloxApp;
|
||||
|
||||
const auto CRobloxApp__CreateDocument = (CRobloxDoc * (__thiscall*)(CRobloxApp * _this))ADDRESS_CROBLOXAPP__CREATEDOCUMENT;
|
||||
|
||||
struct CCommandLineInfo
|
||||
{
|
||||
void* padding1[3];
|
||||
BOOL m_bRunAutomated;
|
||||
};
|
||||
|
||||
class CRobloxCommandLineInfo : public CCommandLineInfo {};
|
||||
|
||||
const auto CCommandLineInfo__ParseLast = (void(__thiscall*)(CCommandLineInfo * _this, BOOL bLast))ADDRESS_CCOMMANDLINEINFO__PARSELAST;
|
||||
#endif
|
||||
#include "Config.h"
|
||||
|
|
@ -4,71 +4,24 @@
|
|||
#include "Config.h"
|
||||
#include "Util.h"
|
||||
#include "LUrlParser.h"
|
||||
#ifdef ARBITERBUILD
|
||||
#include "Logger.h"
|
||||
#endif
|
||||
|
||||
static bool hasAuthUrlArg = false;
|
||||
static bool hasAuthTicketArg = false;
|
||||
static bool hasJoinArg = false;
|
||||
static bool hasJobId = false;
|
||||
static bool setJobId = false;
|
||||
|
||||
static std::wstring authenticationUrl;
|
||||
static std::wstring authenticationTicket;
|
||||
static std::wstring joinScriptUrl;
|
||||
static std::string jobId;
|
||||
|
||||
static std::map<ServerReplicator*, RakPeerInterface*> rakPeers;
|
||||
|
||||
// Functions //
|
||||
|
||||
Http__trustCheck_t Http__trustCheck = (Http__trustCheck_t)ADDRESS_HTTP__TRUSTCHECK;
|
||||
Crypt__verifySignatureBase64_t Crypt__verifySignatureBase64 = (Crypt__verifySignatureBase64_t)ADDRESS_CRYPT__VERIFYSIGNATUREBASE64;
|
||||
#ifdef ARBITERBUILD
|
||||
DataModel__getJobId_t DataModel__getJobId = (DataModel__getJobId_t)ADDRESS_DATAMODEL__GETJOBID;
|
||||
#ifdef OUTPUT
|
||||
StandardOut__print_t StandardOut__print = (StandardOut__print_t)ADDRESS_STANDARDOUT__PRINT;
|
||||
// Network__RakNetAddressToString_t Network__RakNetAddressToString = (Network__RakNetAddressToString_t)ADDRESS_NETWORK__RAKNETADDRESSTOSTRING;
|
||||
#ifdef MFC2011
|
||||
ServerReplicator__sendTop_t ServerReplicator__sendTop = (ServerReplicator__sendTop_t)ADDRESS_SERVERREPLICATOR__SENDTOP;
|
||||
ServerReplicator__processTicket_t ServerReplicator__processTicket = (ServerReplicator__processTicket_t)ADDRESS_SERVERREPLICATOR__PROCESSTICKET;
|
||||
#endif
|
||||
#ifdef PLAYER2012
|
||||
Application__ParseArguments_t Application__ParseArguments = (Application__ParseArguments_t)ADDRESS_APPLICATION__PARSEARGUMENTS;
|
||||
#endif
|
||||
#endif
|
||||
#if defined(MFC2010) || defined(MFC2011)
|
||||
// CApp__CreateGame_t CApp__CreateGame = (CApp__CreateGame_t)ADDRESS_CAPP__CREATEGAME;
|
||||
CRobloxApp__InitInstance_t CRobloxApp__InitInstance = (CRobloxApp__InitInstance_t)ADDRESS_CROBLOXAPP__INITINSTANCE;
|
||||
CRobloxCommandLineInfo__ParseParam_t CRobloxCommandLineInfo__ParseParam = (CRobloxCommandLineInfo__ParseParam_t)ADDRESS_CROBLOXCOMMANDLINEINFO__PARSEPARAM;
|
||||
#endif
|
||||
#ifdef DEBUG_SERVERREPLICATOR__PROCESSPACKET
|
||||
ServerReplicator__processPacket_t ServerReplicator__processPacket = (ServerReplicator__processPacket_t)ADDRESS_SERVERREPLICATOR__PROCESSPACKET;
|
||||
#endif
|
||||
|
||||
// Hook Definitions //
|
||||
|
||||
BOOL __fastcall Http__trustCheck_hook(const char* url)
|
||||
BOOL __fastcall Http__trustCheck_hook(int _this, void*, 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
|
||||
|
||||
url = *(char**)url;
|
||||
}
|
||||
|
||||
LUrlParser::ParseURL parsedUrl = LUrlParser::ParseURL::parseURL(url);
|
||||
|
||||
if (!parsedUrl.isValid())
|
||||
return false;
|
||||
|
||||
#ifdef ARBITERBUILD
|
||||
Logger::Log(LogType::Http, url);
|
||||
#endif
|
||||
|
||||
if (std::string("about:blank") == url)
|
||||
return true;
|
||||
|
||||
|
|
@ -81,316 +34,32 @@ BOOL __fastcall Http__trustCheck_hook(const char* url)
|
|||
return false;
|
||||
}
|
||||
|
||||
void __fastcall Crypt__verifySignatureBase64_hook(HCRYPTPROV* _this, void*, char a2, int a3, int a4, int a5, int a6, int a7, int a8, char a9, int a10, int a11, int a12, int a13, int a14, int a15)
|
||||
{
|
||||
// the actual function signature is (HCRYPTPROV* _this, std::string message, std::string signatureBase64)
|
||||
// but for some reason it throws a memory access violation when you pass the parameters back into the function, without even modifying them
|
||||
// each char represents the beginning of new std::string (with the int parameters, that totalls to a length of 24 bytes)
|
||||
// the signature length is stored in a14 though so we can just use that
|
||||
|
||||
if (a14 > 1024)
|
||||
{
|
||||
std::ostringstream error;
|
||||
error << "Signature too large. " << a14 << " > 1024";
|
||||
throw std::runtime_error(error.str());
|
||||
}
|
||||
|
||||
Crypt__verifySignatureBase64(_this, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15);
|
||||
}
|
||||
|
||||
#ifdef ARBITERBUILD
|
||||
int __fastcall DataModel__getJobId_hook(DataModel* _this, void*, int a2)
|
||||
{
|
||||
// the actual function signature is (DataModel* _this)
|
||||
// this only sets the job id when game.jobId is called by lua
|
||||
// so the gameserver script must call game.jobId at the beginning for this to take effect
|
||||
// also, this only applies to the first datamodel that is created
|
||||
|
||||
if (!setJobId && hasJobId && !jobId.empty())
|
||||
{
|
||||
_this->jobId = jobId;
|
||||
setJobId = true;
|
||||
}
|
||||
|
||||
return DataModel__getJobId(_this, a2);
|
||||
}
|
||||
|
||||
#ifdef OUTPUT
|
||||
void __fastcall StandardOut__print_hook(int _this, void*, int type, std::string* message)
|
||||
{
|
||||
StandardOut__print(_this, type, message);
|
||||
|
||||
if (Logger::handle)
|
||||
{
|
||||
#ifdef NDEBUG
|
||||
// i have absolutely no clue why but the location of the message pointer is offset 4 bytes when the dll compiled as release
|
||||
int messagePtr = (int)message + 4;
|
||||
std::string* message = reinterpret_cast<std::string*>(messagePtr);
|
||||
#endif
|
||||
if (!Logger::handle) return;
|
||||
|
||||
Logger::Print(type, *message);
|
||||
}
|
||||
}
|
||||
|
||||
// std::string __fastcall Network__RakNetAddressToString_hook(const int raknetAddress, char portDelineator)
|
||||
// {
|
||||
// return Network__RakNetAddressToString(raknetAddress, portDelineator);
|
||||
// }
|
||||
|
||||
#ifdef MFC2011
|
||||
void __fastcall ServerReplicator__sendTop_hook(ServerReplicator* _this, void*, RakPeerInterface* peer)
|
||||
{
|
||||
if (_this->isAuthenticated)
|
||||
{
|
||||
// printf("ServerReplicator::sendTop called: player is authenticated\n");
|
||||
ServerReplicator__sendTop(_this, peer);
|
||||
}
|
||||
else if (rakPeers.find(_this) == rakPeers.end())
|
||||
{
|
||||
// printf("ServerReplicator::sendTop called: player is not authenticated\n");
|
||||
rakPeers.insert(std::pair<ServerReplicator*, RakPeerInterface*>(_this, peer));
|
||||
}
|
||||
}
|
||||
|
||||
void __fastcall ServerReplicator__processTicket_hook(ServerReplicator* _this, void*, Packet* packet)
|
||||
{
|
||||
ServerReplicator__processTicket(_this, packet);
|
||||
|
||||
// THIS IS TEMPORARY
|
||||
// i literally cant find a way to obtain rakpeerinterface from _this, like it's really damn hard
|
||||
// so i'm cheating on doing that by getting rakpeerinterface from the first sendtop call,
|
||||
// throwing that into a lookup table and then using that here
|
||||
|
||||
auto pos = rakPeers.find(_this);
|
||||
if (pos == rakPeers.end())
|
||||
{
|
||||
// printf("ServerReplicator::sendTop called: could not find rakpeer for %08X\n", (int)_this);
|
||||
}
|
||||
else if (_this->isAuthenticated)
|
||||
{
|
||||
// printf("ServerReplicator::sendTop called: Value of peer: %08X - associated with %08X\n", (int)pos->second, (int)_this);
|
||||
ServerReplicator__sendTop_hook(_this, nullptr, pos->second);
|
||||
}
|
||||
else
|
||||
{
|
||||
// printf("ServerReplicator::sendTop called: player is not authenticated\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PLAYER2012
|
||||
BOOL __fastcall Application__ParseArguments_hook(int _this, void*, int a2, const char* argv)
|
||||
{
|
||||
std::map<std::string, std::string> argslist = Util::parseArgs(argv);
|
||||
|
||||
if (argslist.count("-jobId"))
|
||||
{
|
||||
hasJobId = true;
|
||||
jobId = argslist["-jobId"];
|
||||
Logger::Initialize(jobId);
|
||||
|
||||
// now we have to exclude the -jobId arg from argv
|
||||
// i'm being really lazy here, so don't do this
|
||||
// i'm just gonna erase everything that comes after the -jobId arg
|
||||
// thats gonna cause issues if the joinscript params are after the jobId arg,
|
||||
// but really it shouldn't matter because the arbiter always starts it up in the correct order
|
||||
|
||||
char* pch = (char*)strstr(argv, " -jobId");
|
||||
if (pch != NULL)
|
||||
strncpy_s(pch, strlen(pch) + 1, "", 0);
|
||||
}
|
||||
|
||||
return Application__ParseArguments(_this, a2, argv);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(MFC2010) || defined(MFC2011)
|
||||
/* INT __fastcall CApp__CreateGame_hook(CApp* _this, void*, int* a2, LPCWSTR a3)
|
||||
{
|
||||
printf("CApp::CreateGame called\n");
|
||||
// printf("Location of _this: %p\n", _this);
|
||||
// printf("Location of a2: %p\n", a2);
|
||||
// printf("Location of a3: %p\n", a3);
|
||||
|
||||
// int result = (int)CApp__CreateGame(_this, a2, a3);
|
||||
// int result = (int)CApp__CreateGame(_this, a2, L"44340105256");
|
||||
int result = (int)CApp__CreateGame(_this, a2, L"44340105256");
|
||||
|
||||
return result;
|
||||
} */
|
||||
|
||||
BOOL __fastcall CRobloxApp__InitInstance_hook(CRobloxApp* _this)
|
||||
{
|
||||
if (!CRobloxApp__InitInstance(_this))
|
||||
return FALSE;
|
||||
|
||||
CApp* app = reinterpret_cast<CApp*>(CLASSLOCATION_CAPP);
|
||||
|
||||
if (hasAuthUrlArg && hasAuthTicketArg && !authenticationUrl.empty() && !authenticationTicket.empty())
|
||||
{
|
||||
CApp__RobloxAuthenticate(app, nullptr, authenticationUrl.c_str(), authenticationTicket.c_str());
|
||||
}
|
||||
|
||||
#ifdef PLAYERBUILD
|
||||
if (hasJoinArg && !joinScriptUrl.empty())
|
||||
{
|
||||
try
|
||||
switch (type)
|
||||
{
|
||||
// so... i would've wanted to just use CApp::CreateGame instead but there's a few issues
|
||||
// in the typelib, CreateGame is exposed as being IApp::CreateGame(string p) - 'p' is "44340105256"
|
||||
// however internally the function is actually CApp::CreateGame(int something, LPCWSTR p)
|
||||
// it's obvious that 'something' is a pointer to a class but i have no clue what the class is
|
||||
// until i figure out wtf its supposed to be we've gotta stick to doing CRobloxApp::CreateDocument for now
|
||||
|
||||
CRobloxDoc* document = CRobloxApp__CreateDocument(_this);
|
||||
CWorkspace__ExecUrlScript(document->workspace, joinScriptUrl.c_str(), VARIANTARG(), VARIANTARG(), VARIANTARG(), VARIANTARG(), nullptr);
|
||||
}
|
||||
catch (std::runtime_error)// & exception)
|
||||
{
|
||||
// MessageBoxA(nullptr, exception.what(), nullptr, MB_ICONERROR);
|
||||
return FALSE;
|
||||
case 1: // RBX::MESSAGE_OUTPUT:
|
||||
SetConsoleTextAttribute(Logger::handle, FOREGROUND_BLUE | FOREGROUND_INTENSITY);
|
||||
break;
|
||||
case 0: // RBX::MESSAGE_INFO:
|
||||
SetConsoleTextAttribute(Logger::handle, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
break;
|
||||
case 2: // RBX::MESSAGE_WARNING:
|
||||
SetConsoleTextAttribute(Logger::handle, FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
break;
|
||||
case 3: // RBX::MESSAGE_ERROR:
|
||||
SetConsoleTextAttribute(Logger::handle, FOREGROUND_RED | FOREGROUND_INTENSITY);
|
||||
break;
|
||||
}
|
||||
printf("%s\n", message->c_str());
|
||||
SetConsoleTextAttribute(Logger::handle, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void __fastcall CRobloxCommandLineInfo__ParseParam_hook(CRobloxCommandLineInfo* _this, void*, const char* pszParam, BOOL bFlag, BOOL bLast)
|
||||
{
|
||||
#ifdef PLAYERBUILD
|
||||
if (hasJoinArg && joinScriptUrl.empty())
|
||||
{
|
||||
int size = MultiByteToWideChar(CP_ACP, 0, pszParam, strlen(pszParam), nullptr, 0);
|
||||
joinScriptUrl.resize(size);
|
||||
MultiByteToWideChar(CP_ACP, 0, pszParam, strlen(pszParam), &joinScriptUrl[0], size);
|
||||
|
||||
_this->m_bRunAutomated = TRUE;
|
||||
|
||||
CCommandLineInfo__ParseLast(_this, bLast);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (hasAuthUrlArg && authenticationUrl.empty())
|
||||
{
|
||||
int size = MultiByteToWideChar(CP_ACP, 0, pszParam, strlen(pszParam), nullptr, 0);
|
||||
authenticationUrl.resize(size);
|
||||
MultiByteToWideChar(CP_ACP, 0, pszParam, strlen(pszParam), &authenticationUrl[0], size);
|
||||
|
||||
CCommandLineInfo__ParseLast(_this, bLast);
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasAuthTicketArg && authenticationTicket.empty())
|
||||
{
|
||||
int size = MultiByteToWideChar(CP_ACP, 0, pszParam, strlen(pszParam), nullptr, 0);
|
||||
authenticationTicket.resize(size);
|
||||
MultiByteToWideChar(CP_ACP, 0, pszParam, strlen(pszParam), &authenticationTicket[0], size);
|
||||
|
||||
CCommandLineInfo__ParseLast(_this, bLast);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ARBITERBUILD
|
||||
if (hasJobId && jobId.empty())
|
||||
{
|
||||
// command line args are parsed AFTER CRobloxApp::InitInstance is run, so the logger will too be initialized after
|
||||
|
||||
jobId = std::string(pszParam);
|
||||
Logger::Initialize(jobId);
|
||||
|
||||
CCommandLineInfo__ParseLast(_this, bLast);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (bFlag && _stricmp(pszParam, "a") == 0)
|
||||
{
|
||||
hasAuthUrlArg = true;
|
||||
CCommandLineInfo__ParseLast(_this, bLast);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bFlag && _stricmp(pszParam, "t") == 0)
|
||||
{
|
||||
hasAuthTicketArg = true;
|
||||
CCommandLineInfo__ParseLast(_this, bLast);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef PLAYERBUILD
|
||||
if (bFlag && _stricmp(pszParam, "j") == 0)
|
||||
{
|
||||
hasJoinArg = true;
|
||||
CCommandLineInfo__ParseLast(_this, bLast);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ARBITERBUILD
|
||||
if (bFlag && _stricmp(pszParam, "jobId") == 0)
|
||||
{
|
||||
hasJobId = true;
|
||||
CCommandLineInfo__ParseLast(_this, bLast);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
CRobloxCommandLineInfo__ParseParam(_this, pszParam, bFlag, bLast);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_SERVERREPLICATOR__PROCESSPACKET
|
||||
INT __fastcall ServerReplicator__processPacket_hook(int _this, void*, Packet* packet)
|
||||
{
|
||||
switch ((unsigned char)packet->data[0])
|
||||
{
|
||||
case ID_TIMESTAMP:
|
||||
printf("ServerReplicator::processPacket received ID_TIMESTAMP with length %d\n", packet->length);
|
||||
break;
|
||||
|
||||
case ID_REQUEST_CHARACTER:
|
||||
printf("ServerReplicator::processPacket received ID_REQUEST_CHARACTER with length %d\n", packet->length);
|
||||
break;
|
||||
|
||||
case ID_DATA:
|
||||
printf("ServerReplicator::processPacket received ID_DATA with length %d\n", packet->length);
|
||||
break;
|
||||
|
||||
case ID_SUBMIT_TICKET:
|
||||
printf("ServerReplicator::processPacket received ID_SUBMIT_TICKET with length %d\n", packet->length);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("ServerReplicator::processPacket received packet %d with length %d\n", packet->data[0], packet->length);
|
||||
break;
|
||||
}
|
||||
|
||||
/* if ((unsigned char)packet->data[0] == ID_SUBMIT_TICKET)
|
||||
{
|
||||
printf("ServerReplicator::processPacket received ID_SUBMIT_TICKET with length %d\n", packet->length);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("ServerReplicator::processPacket received packet %d with length %d\n", packet->data[0], packet->length);
|
||||
} */
|
||||
|
||||
/* switch ((unsigned char)packet->data[0])
|
||||
{
|
||||
case ID_SUBMIT_TICKET:
|
||||
// printf("ServerReplicator::processPacket called: ID_SUBMIT_TICKET\n");
|
||||
return ServerReplicator__processPacket(_this, packet);
|
||||
|
||||
default:
|
||||
if (true)
|
||||
{
|
||||
Logger::Print(2, "Player not authenticated s");
|
||||
return RR_STOP_PROCESSING_AND_DEALLOCATE;
|
||||
}
|
||||
return ServerReplicator__processPacket(_this, packet);
|
||||
} */
|
||||
|
||||
return ServerReplicator__processPacket(_this, packet);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -4,75 +4,21 @@
|
|||
|
||||
// Type Definitions //
|
||||
|
||||
typedef BOOL(__thiscall* Http__trustCheck_t)(const char* url);
|
||||
typedef void(__thiscall* Crypt__verifySignatureBase64_t)(HCRYPTPROV* _this, char a2, int a3, int a4, int a5, int a6, int a7, int a8, char a9, int a10, int a11, int a12, int a13, int a14, int a15);
|
||||
#ifdef ARBITERBUILD
|
||||
typedef INT(__thiscall* DataModel__getJobId_t)(DataModel* _this, int a2);
|
||||
typedef BOOL(__thiscall* Http__trustCheck_t)(int _this, const char* url);
|
||||
#ifdef OUTPUT
|
||||
typedef void(__thiscall* StandardOut__print_t)(int _this, int type, std::string* message);
|
||||
// typedef std::string(__thiscall* Network__RakNetAddressToString_t)(const int raknetAddress, char portDelineator);
|
||||
#ifdef MFC2011
|
||||
typedef void(__thiscall* ServerReplicator__sendTop_t)(ServerReplicator* _this, RakPeerInterface* peer);
|
||||
typedef void(__thiscall* ServerReplicator__processTicket_t)(ServerReplicator* _this, Packet* packet);
|
||||
#endif
|
||||
#ifdef PLAYER2012
|
||||
typedef BOOL(__thiscall* Application__ParseArguments_t)(int _this, int a2, const char* argv);
|
||||
#endif
|
||||
#endif
|
||||
#if defined(MFC2010) || defined(MFC2011)
|
||||
// typedef INT(__thiscall* CApp__CreateGame_t)(CApp* _this, int *a2, LPCWSTR a3);
|
||||
typedef BOOL(__thiscall* CRobloxApp__InitInstance_t)(CRobloxApp* _this);
|
||||
typedef void(__thiscall* CRobloxCommandLineInfo__ParseParam_t)(CRobloxCommandLineInfo* _this, const char* pszParam, BOOL bFlag, BOOL bLast);
|
||||
#endif
|
||||
#ifdef DEBUG_SERVERREPLICATOR__PROCESSPACKET
|
||||
typedef int(__thiscall* ServerReplicator__processPacket_t)(int _this, Packet* packet);
|
||||
#endif
|
||||
|
||||
// Hook Declarations //
|
||||
|
||||
BOOL __fastcall Http__trustCheck_hook(const char* url);
|
||||
void __fastcall Crypt__verifySignatureBase64_hook(HCRYPTPROV* _this, void*, char a2, int a3, int a4, int a5, int a6, int a7, int a8, char a9, int a10, int a11, int a12, int a13, int a14, int a15);
|
||||
#ifdef ARBITERBUILD
|
||||
INT __fastcall DataModel__getJobId_hook(DataModel* _this, void*, int a2);
|
||||
BOOL __fastcall Http__trustCheck_hook(int _this, void*, const char* url);
|
||||
#ifdef OUTPUT
|
||||
void __fastcall StandardOut__print_hook(int _this, void*, int type, std::string* message);
|
||||
// std::string __fastcall Network__RakNetAddressToString_hook(const int raknetAddress, char portDelineator);
|
||||
#ifdef MFC2011
|
||||
void __fastcall ServerReplicator__sendTop_hook(ServerReplicator* _this, void*, RakPeerInterface* peer);
|
||||
void __fastcall ServerReplicator__processTicket_hook(ServerReplicator* _this, void*, Packet* packet);
|
||||
#endif
|
||||
#ifdef PLAYER2012
|
||||
BOOL __fastcall Application__ParseArguments_hook(int _this, void*, int a2, const char* argv);
|
||||
#endif
|
||||
#endif
|
||||
#if defined(MFC2010) || defined(MFC2011)
|
||||
// INT __fastcall CApp__CreateGame_hook(CApp* _this, void*, int *a2, LPCWSTR a3);
|
||||
BOOL __fastcall CRobloxApp__InitInstance_hook(CRobloxApp* _this);
|
||||
void __fastcall CRobloxCommandLineInfo__ParseParam_hook(CRobloxCommandLineInfo* _this, void*, const char* pszParam, BOOL bFlag, BOOL bLast);
|
||||
#endif
|
||||
#ifdef DEBUG_SERVERREPLICATOR__PROCESSPACKET
|
||||
INT __fastcall ServerReplicator__processPacket_hook(int _this, void*, Packet* packet);
|
||||
#endif
|
||||
|
||||
// Externals //
|
||||
|
||||
extern Http__trustCheck_t Http__trustCheck;
|
||||
extern Crypt__verifySignatureBase64_t Crypt__verifySignatureBase64;
|
||||
#ifdef ARBITERBUILD
|
||||
extern DataModel__getJobId_t DataModel__getJobId;
|
||||
#ifdef OUTPUT
|
||||
extern StandardOut__print_t StandardOut__print;
|
||||
// extern Network__RakNetAddressToString_t Network__RakNetAddressToString;
|
||||
#ifdef MFC2011
|
||||
extern ServerReplicator__sendTop_t ServerReplicator__sendTop;
|
||||
extern ServerReplicator__processTicket_t ServerReplicator__processTicket;
|
||||
#endif
|
||||
#ifdef PLAYER2012
|
||||
extern Application__ParseArguments_t Application__ParseArguments;
|
||||
#endif
|
||||
#endif
|
||||
#if defined(MFC2010) || defined(MFC2011)
|
||||
// extern CApp__CreateGame_t CApp__CreateGame;
|
||||
extern CRobloxApp__InitInstance_t CRobloxApp__InitInstance;
|
||||
extern CRobloxCommandLineInfo__ParseParam_t CRobloxCommandLineInfo__ParseParam;
|
||||
#endif
|
||||
#ifdef DEBUG_SERVERREPLICATOR__PROCESSPACKET
|
||||
extern ServerReplicator__processPacket_t ServerReplicator__processPacket;
|
||||
#endif
|
||||
|
|
@ -13,7 +13,9 @@ const std::vector<std::string> Util::allowedHosts
|
|||
"assetdelivery.roblox.com",
|
||||
|
||||
"tadah.rocks",
|
||||
"www.tadah.rocks"
|
||||
"www.tadah.rocks",
|
||||
"api.tadah.rocks",
|
||||
"clientsettings.tadah.rocks"
|
||||
};
|
||||
|
||||
const std::vector<std::string> Util::allowedSchemes
|
||||
|
|
@ -30,31 +32,6 @@ const std::vector<std::string> Util::allowedEmbeddedSchemes
|
|||
"res"
|
||||
};
|
||||
|
||||
std::map<std::string, std::string> Util::parseArgs(std::string args)
|
||||
{
|
||||
std::map<std::string, std::string> map;
|
||||
|
||||
std::string::size_type key_pos = 0;
|
||||
std::string::size_type key_end;
|
||||
std::string::size_type val_pos;
|
||||
std::string::size_type val_end;
|
||||
|
||||
while ((key_end = args.find(' ', key_pos)) != std::string::npos)
|
||||
{
|
||||
if ((val_pos = args.find_first_not_of(" -", key_end)) == std::string::npos)
|
||||
break;
|
||||
|
||||
val_end = args.find(" -", val_pos);
|
||||
map.emplace(args.substr(key_pos, key_end - key_pos), args.substr(val_pos, val_end - val_pos));
|
||||
|
||||
key_pos = val_end;
|
||||
if (key_pos != std::string::npos)
|
||||
++key_pos;
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/48212992/how-to-find-out-if-there-is-any-non-ascii-character-in-a-string-with-a-file-path
|
||||
bool Util::isASCII(const std::string& s)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,38 +2,20 @@
|
|||
#include "Config.h"
|
||||
#include "Patches.h"
|
||||
#include "RobloxMFCHooks.h"
|
||||
#include "Logger.h" // remove when testing is done
|
||||
#include "Logger.h"
|
||||
|
||||
START_PATCH_LIST()
|
||||
ADD_PATCH(Http__trustCheck, Http__trustCheck_hook)
|
||||
ADD_PATCH(Crypt__verifySignatureBase64, Crypt__verifySignatureBase64_hook)
|
||||
#ifdef ARBITERBUILD
|
||||
ADD_PATCH(DataModel__getJobId, DataModel__getJobId_hook)
|
||||
#ifdef OUTPUT
|
||||
ADD_PATCH(StandardOut__print, StandardOut__print_hook)
|
||||
// ADD_PATCH(Network__RakNetAddressToString, Network__RakNetAddressToString_hook)
|
||||
#ifdef MFC2011
|
||||
ADD_PATCH(ServerReplicator__sendTop, ServerReplicator__sendTop_hook)
|
||||
ADD_PATCH(ServerReplicator__processTicket, ServerReplicator__processTicket_hook)
|
||||
#endif
|
||||
#ifdef PLAYER2012
|
||||
ADD_PATCH(Application__ParseArguments, Application__ParseArguments_hook)
|
||||
#endif
|
||||
#endif
|
||||
#if defined(MFC2010) || defined(MFC2011)
|
||||
// ADD_PATCH(CApp__CreateGame, CApp__CreateGame_hook)
|
||||
ADD_PATCH(CRobloxApp__InitInstance, CRobloxApp__InitInstance_hook)
|
||||
ADD_PATCH(CRobloxCommandLineInfo__ParseParam, CRobloxCommandLineInfo__ParseParam_hook)
|
||||
#endif
|
||||
#ifdef DEBUG_SERVERREPLICATOR__PROCESSPACKET
|
||||
ADD_PATCH(ServerReplicator__processPacket, ServerReplicator__processPacket_hook)
|
||||
#endif
|
||||
END_PATCH_LIST()
|
||||
|
||||
// DLLs for release will be loaded with VMProtect, so this isn't necessary
|
||||
// Arbiter will still use Stud_PE for ease in swapping DLLs however
|
||||
#ifdef ARBITERBUILD
|
||||
// #ifdef ARBITERBUILD
|
||||
void __declspec(dllexport) import() {}
|
||||
#endif
|
||||
// #endif
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
|
|
@ -49,6 +31,9 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
|||
|
||||
ExitProcess(EXIT_FAILURE);
|
||||
}
|
||||
#ifdef OUTPUT
|
||||
Logger::Initialize("output");
|
||||
#endif
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
|||
Loading…
Reference in New Issue