diff --git a/PolygonClientUtilities/RobloxMFCClasses.h b/PolygonClientUtilities/Classes.h similarity index 99% rename from PolygonClientUtilities/RobloxMFCClasses.h rename to PolygonClientUtilities/Classes.h index c87a7d6..2264537 100644 --- a/PolygonClientUtilities/RobloxMFCClasses.h +++ b/PolygonClientUtilities/Classes.h @@ -1,7 +1,6 @@ #pragma once #include "Config.h" - #include #ifdef ARBITERBUILD diff --git a/PolygonClientUtilities/Config.h b/PolygonClientUtilities/Config.h index 46584b6..b7e2ca7 100644 --- a/PolygonClientUtilities/Config.h +++ b/PolygonClientUtilities/Config.h @@ -1,6 +1,6 @@ #pragma once -#define MFC2011 +#define MFC2010 #define PLAYERBUILD #define ARBITERBUILD @@ -28,6 +28,7 @@ #define ADDRESS_CRYPT__VERIFYSIGNATUREBASE64 0x0079ECF0 #define ADDRESS_SERVERREPLICATOR__SENDTOP 0x00506910 #define ADDRESS_SERVERREPLICATOR__PROCESSPACKET 0x00507420 +#define ADDRESS_SERVERREPLICATOR__PROCESSTICKET 0x0 // MFC specific definitions #define CLASSLOCATION_CROBLOXAPP 0x00BFF898 @@ -43,6 +44,9 @@ #define ADDRESS_CROBLOXCOMMANDLINEINFO__PARSEPARAM 0x00450AC0 #define ADDRESS_CCOMMANDLINEINFO__PARSELAST 0x007A80A0 +// Player specific definitions +#define ADDRESS_APPLICATION__PARSEARGUMENTS 0x0 + // RakNet packet definitions #define ID_TIMESTAMP 25 #define ID_SET_GLOBALS 95 diff --git a/PolygonClientUtilities/Hooks.cpp b/PolygonClientUtilities/Hooks.cpp new file mode 100644 index 0000000..c98db72 --- /dev/null +++ b/PolygonClientUtilities/Hooks.cpp @@ -0,0 +1,125 @@ +#include "pch.h" +#include "Hooks.h" +#include "Patches.h" +#include "Config.h" +#include "Util.h" +#include "LUrlParser.h" +#ifdef ARBITERBUILD +#include "Logger.h" +#endif + +static bool hasJobId = false; +static bool setJobId = false; + +static std::string jobId; + +// Functions // + +#ifdef ARBITERBUILD +DataModel__getJobId_t DataModel__getJobId = (DataModel__getJobId_t)ADDRESS_DATAMODEL__GETJOBID; +// Network__RakNetAddressToString_t Network__RakNetAddressToString = (Network__RakNetAddressToString_t)ADDRESS_NETWORK__RAKNETADDRESSTOSTRING; +#ifdef MFC2011 + +#endif +#endif +#if defined(MFC2010) || defined(MFC2011) +// CApp__CreateGame_t CApp__CreateGame = (CApp__CreateGame_t)ADDRESS_CAPP__CREATEGAME; +#endif +#ifdef DEBUG_SERVERREPLICATOR__PROCESSPACKET +ServerReplicator__processPacket_t ServerReplicator__processPacket = (ServerReplicator__processPacket_t)ADDRESS_SERVERREPLICATOR__PROCESSPACKET; +#endif + +// Hook Definitions // + +#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); +} + +// std::string __fastcall Network__RakNetAddressToString_hook(const int raknetAddress, char portDelineator) +// { +// return Network__RakNetAddressToString(raknetAddress, portDelineator); +// } +#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; +} */ +#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 diff --git a/PolygonClientUtilities/Hooks.h b/PolygonClientUtilities/Hooks.h new file mode 100644 index 0000000..6333d09 --- /dev/null +++ b/PolygonClientUtilities/Hooks.h @@ -0,0 +1,57 @@ +#pragma once + +#include "Classes.h" + +// Type Definitions // + +#ifdef ARBITERBUILD +typedef INT(__thiscall* DataModel__getJobId_t)(DataModel* _this, int a2); +// typedef std::string(__thiscall* Network__RakNetAddressToString_t)(const int raknetAddress, char portDelineator); +#ifdef MFC2011 + +#endif +#ifdef PLAYER2012 +#endif +#endif +#if defined(MFC2010) || defined(MFC2011) +// typedef INT(__thiscall* CApp__CreateGame_t)(CApp* _this, int *a2, LPCWSTR a3); +#endif +#ifdef DEBUG_SERVERREPLICATOR__PROCESSPACKET +typedef int(__thiscall* ServerReplicator__processPacket_t)(int _this, Packet* packet); +#endif + +// Hook Declarations // + +#ifdef ARBITERBUILD +INT __fastcall DataModel__getJobId_hook(DataModel* _this, void*, int a2); +// std::string __fastcall Network__RakNetAddressToString_hook(const int raknetAddress, char portDelineator); +#ifdef MFC2011 + +#endif +#ifdef PLAYER2012 +#endif +#endif +#if defined(MFC2010) || defined(MFC2011) +// INT __fastcall CApp__CreateGame_hook(CApp* _this, void*, int *a2, LPCWSTR a3); +#endif +#ifdef DEBUG_SERVERREPLICATOR__PROCESSPACKET +INT __fastcall ServerReplicator__processPacket_hook(int _this, void*, Packet* packet); +#endif + +// Externals // + +#ifdef ARBITERBUILD +extern DataModel__getJobId_t DataModel__getJobId; +// extern Network__RakNetAddressToString_t Network__RakNetAddressToString; +#ifdef MFC2011 + +#endif +#ifdef PLAYER2012 +#endif +#endif +#if defined(MFC2010) || defined(MFC2011) +// extern CApp__CreateGame_t CApp__CreateGame; +#endif +#ifdef DEBUG_SERVERREPLICATOR__PROCESSPACKET +extern ServerReplicator__processPacket_t ServerReplicator__processPacket; +#endif \ No newline at end of file diff --git a/PolygonClientUtilities/Logger.cpp b/PolygonClientUtilities/Logger.cpp index 38f6819..bad31e2 100644 --- a/PolygonClientUtilities/Logger.cpp +++ b/PolygonClientUtilities/Logger.cpp @@ -75,6 +75,6 @@ std::string Logger::UtcTime() { std::stringstream time; std::time_t now = std::time(NULL); - time << std::put_time(std::localtime(&now), "%F %T"); + // time << std::put_time(std::localtime(&now), "%F %T"); return time.str(); } \ No newline at end of file diff --git a/PolygonClientUtilities/MFCCommandLine.cpp b/PolygonClientUtilities/MFCCommandLine.cpp new file mode 100644 index 0000000..a8c2389 --- /dev/null +++ b/PolygonClientUtilities/MFCCommandLine.cpp @@ -0,0 +1,112 @@ +#include "pch.h" +#include "MFCCommandLine.h" + +static bool hasAuthUrlArg = false; +static bool hasAuthTicketArg = false; +static bool hasJoinArg = false; + +static std::wstring authenticationUrl; +static std::wstring authenticationTicket; +static std::wstring joinScriptUrl; + +CRobloxApp__InitInstance_t CRobloxApp__InitInstance = (CRobloxApp__InitInstance_t)ADDRESS_CROBLOXAPP__INITINSTANCE; +CRobloxCommandLineInfo__ParseParam_t CRobloxCommandLineInfo__ParseParam = (CRobloxCommandLineInfo__ParseParam_t)ADDRESS_CROBLOXCOMMANDLINEINFO__PARSEPARAM; + +BOOL __fastcall CRobloxApp__InitInstance_hook(CRobloxApp* _this) +{ + if (!CRobloxApp__InitInstance(_this)) + return FALSE; + + CApp* app = reinterpret_cast(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 + { + // 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; + } + } +#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; + } + + 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 + + CRobloxCommandLineInfo__ParseParam(_this, pszParam, bFlag, bLast); +} \ No newline at end of file diff --git a/PolygonClientUtilities/MFCCommandLine.h b/PolygonClientUtilities/MFCCommandLine.h new file mode 100644 index 0000000..5435934 --- /dev/null +++ b/PolygonClientUtilities/MFCCommandLine.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Classes.h" + +typedef BOOL(__thiscall* CRobloxApp__InitInstance_t)(CRobloxApp* _this); +typedef void(__thiscall* CRobloxCommandLineInfo__ParseParam_t)(CRobloxCommandLineInfo* _this, const char* pszParam, BOOL bFlag, BOOL bLast); + +BOOL __fastcall CRobloxApp__InitInstance_hook(CRobloxApp* _this); +void __fastcall CRobloxCommandLineInfo__ParseParam_hook(CRobloxCommandLineInfo* _this, void*, const char* pszParam, BOOL bFlag, BOOL bLast); + +extern CRobloxApp__InitInstance_t CRobloxApp__InitInstance; +extern CRobloxCommandLineInfo__ParseParam_t CRobloxCommandLineInfo__ParseParam; \ No newline at end of file diff --git a/PolygonClientUtilities/PlayerCommandLine.cpp b/PolygonClientUtilities/PlayerCommandLine.cpp new file mode 100644 index 0000000..0f8e641 --- /dev/null +++ b/PolygonClientUtilities/PlayerCommandLine.cpp @@ -0,0 +1,25 @@ +#include "pch.h" +#include "PlayerCommandLine.h" +#include "Util.h" + +Application__ParseArguments_t Application__ParseArguments = (Application__ParseArguments_t)ADDRESS_APPLICATION__PARSEARGUMENTS; + +BOOL __fastcall Application__ParseArguments_hook(int _this, void*, int a2, const char* argv) +{ + std::map argslist = Util::parseArgs(argv); + + if (argslist.count("-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); +} \ No newline at end of file diff --git a/PolygonClientUtilities/PlayerCommandLine.h b/PolygonClientUtilities/PlayerCommandLine.h new file mode 100644 index 0000000..14d963d --- /dev/null +++ b/PolygonClientUtilities/PlayerCommandLine.h @@ -0,0 +1,7 @@ +#pragma once + +#include "Classes.h" + +typedef BOOL(__thiscall* Application__ParseArguments_t)(int _this, int a2, const char* argv); +BOOL __fastcall Application__ParseArguments_hook(int _this, void*, int a2, const char* argv); +extern Application__ParseArguments_t Application__ParseArguments; \ No newline at end of file diff --git a/PolygonClientUtilities/PolygonClientUtilities.vcxproj b/PolygonClientUtilities/PolygonClientUtilities.vcxproj index 24c8515..10e8042 100644 --- a/PolygonClientUtilities/PolygonClientUtilities.vcxproj +++ b/PolygonClientUtilities/PolygonClientUtilities.vcxproj @@ -161,16 +161,23 @@ + + + + + - - + + + + NotUsing @@ -183,8 +190,13 @@ Create Create - + + + + + + diff --git a/PolygonClientUtilities/PolygonClientUtilities.vcxproj.filters b/PolygonClientUtilities/PolygonClientUtilities.vcxproj.filters index 1d43609..695bb0d 100644 --- a/PolygonClientUtilities/PolygonClientUtilities.vcxproj.filters +++ b/PolygonClientUtilities/PolygonClientUtilities.vcxproj.filters @@ -13,15 +13,21 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + {e1630ddd-f689-40cc-9f7b-506bcf8aca31} + + + {51130969-bcf1-4ae5-b838-7f4fb658856e} + Header Files - + Header Files - + Header Files @@ -39,6 +45,24 @@ Header Files + + Header Files\Hooks + + + Header Files\Hooks + + + Header Files\Hooks + + + Header Files\Hooks + + + Header Files\Hooks + + + Header Files\Hooks + @@ -47,7 +71,7 @@ Source Files - + Source Files @@ -62,5 +86,23 @@ Source Files + + Source Files\Hooks + + + Source Files\Hooks + + + Source Files\Hooks + + + Source Files\Hooks + + + Source Files\Hooks + + + Source Files\Hooks + \ No newline at end of file diff --git a/PolygonClientUtilities/RCCOutput.cpp b/PolygonClientUtilities/RCCOutput.cpp new file mode 100644 index 0000000..b533aad --- /dev/null +++ b/PolygonClientUtilities/RCCOutput.cpp @@ -0,0 +1,21 @@ +#include "pch.h" +#include "RCCOutput.h" +#include "Logger.h" + +StandardOut__print_t StandardOut__print = (StandardOut__print_t)ADDRESS_STANDARDOUT__PRINT; + +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(messagePtr); +#endif + + Logger::Print(type, *message); + } +} \ No newline at end of file diff --git a/PolygonClientUtilities/RCCOutput.h b/PolygonClientUtilities/RCCOutput.h new file mode 100644 index 0000000..a6a2d29 --- /dev/null +++ b/PolygonClientUtilities/RCCOutput.h @@ -0,0 +1,7 @@ +#pragma once + +#include "Classes.h" + +typedef void(__thiscall* StandardOut__print_t)(int _this, int type, std::string* message); +void __fastcall StandardOut__print_hook(int _this, void*, int type, std::string* message); +extern StandardOut__print_t StandardOut__print; \ No newline at end of file diff --git a/PolygonClientUtilities/ReplicatorSecurity.cpp b/PolygonClientUtilities/ReplicatorSecurity.cpp new file mode 100644 index 0000000..cd8bd69 --- /dev/null +++ b/PolygonClientUtilities/ReplicatorSecurity.cpp @@ -0,0 +1,46 @@ +#include "pch.h" +#include "ReplicatorSecurity.h" + +static std::map rakPeers; + +ServerReplicator__sendTop_t ServerReplicator__sendTop = (ServerReplicator__sendTop_t)ADDRESS_SERVERREPLICATOR__SENDTOP; +ServerReplicator__processTicket_t ServerReplicator__processTicket = (ServerReplicator__processTicket_t)ADDRESS_SERVERREPLICATOR__PROCESSTICKET; + +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(_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"); + } +} \ No newline at end of file diff --git a/PolygonClientUtilities/ReplicatorSecurity.h b/PolygonClientUtilities/ReplicatorSecurity.h new file mode 100644 index 0000000..d5f655b --- /dev/null +++ b/PolygonClientUtilities/ReplicatorSecurity.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Classes.h" + +typedef void(__thiscall* ServerReplicator__sendTop_t)(ServerReplicator* _this, RakPeerInterface* peer); +typedef void(__thiscall* ServerReplicator__processTicket_t)(ServerReplicator* _this, Packet* packet); + +void __fastcall ServerReplicator__sendTop_hook(ServerReplicator* _this, void*, RakPeerInterface* peer); +void __fastcall ServerReplicator__processTicket_hook(ServerReplicator* _this, void*, Packet* packet); + +extern ServerReplicator__sendTop_t ServerReplicator__sendTop; +extern ServerReplicator__processTicket_t ServerReplicator__processTicket; \ No newline at end of file diff --git a/PolygonClientUtilities/RobloxMFCHooks.cpp b/PolygonClientUtilities/RobloxMFCHooks.cpp deleted file mode 100644 index 3994299..0000000 --- a/PolygonClientUtilities/RobloxMFCHooks.cpp +++ /dev/null @@ -1,396 +0,0 @@ -#include "pch.h" -#include "RobloxMFCHooks.h" -#include "Patches.h" -#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 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; -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) -{ - 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; - - if (std::find(Util::allowedSchemes.begin(), Util::allowedSchemes.end(), parsedUrl.scheme_) != Util::allowedSchemes.end()) - return std::find(Util::allowedHosts.begin(), Util::allowedHosts.end(), parsedUrl.host_) != Util::allowedHosts.end(); - - if (std::find(Util::allowedEmbeddedSchemes.begin(), Util::allowedEmbeddedSchemes.end(), parsedUrl.scheme_) != Util::allowedEmbeddedSchemes.end()) - return true; - - 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); -} - -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(messagePtr); -#endif - - 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(_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 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(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 - { - // 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; - } - } -#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 diff --git a/PolygonClientUtilities/RobloxMFCHooks.h b/PolygonClientUtilities/RobloxMFCHooks.h deleted file mode 100644 index 1abe760..0000000 --- a/PolygonClientUtilities/RobloxMFCHooks.h +++ /dev/null @@ -1,78 +0,0 @@ -#pragma once - -#include "RobloxMFCClasses.h" - -// 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 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); -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; -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 \ No newline at end of file diff --git a/PolygonClientUtilities/TrustCheck.cpp b/PolygonClientUtilities/TrustCheck.cpp new file mode 100644 index 0000000..91dfb15 --- /dev/null +++ b/PolygonClientUtilities/TrustCheck.cpp @@ -0,0 +1,35 @@ +#include "pch.h" +#include "TrustCheck.h" +#include "Util.h" +#include "LUrlParser.h" + +Http__trustCheck_t Http__trustCheck = (Http__trustCheck_t)ADDRESS_HTTP__TRUSTCHECK; + +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 + + url = *(char**)url; + } + + LUrlParser::ParseURL parsedUrl = LUrlParser::ParseURL::parseURL(url); + + if (!parsedUrl.isValid()) + return false; + + if (std::string("about:blank") == url) + return true; + + if (std::find(Util::allowedSchemes.begin(), Util::allowedSchemes.end(), parsedUrl.scheme_) != Util::allowedSchemes.end()) + return std::find(Util::allowedHosts.begin(), Util::allowedHosts.end(), parsedUrl.host_) != Util::allowedHosts.end(); + + if (std::find(Util::allowedEmbeddedSchemes.begin(), Util::allowedEmbeddedSchemes.end(), parsedUrl.scheme_) != Util::allowedEmbeddedSchemes.end()) + return true; + + return false; +} diff --git a/PolygonClientUtilities/TrustCheck.h b/PolygonClientUtilities/TrustCheck.h new file mode 100644 index 0000000..e56aef3 --- /dev/null +++ b/PolygonClientUtilities/TrustCheck.h @@ -0,0 +1,7 @@ +#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/VerifySignatureBase64.cpp b/PolygonClientUtilities/VerifySignatureBase64.cpp new file mode 100644 index 0000000..8c262ed --- /dev/null +++ b/PolygonClientUtilities/VerifySignatureBase64.cpp @@ -0,0 +1,21 @@ +#include "pch.h" +#include "VerifySignatureBase64.h" + +Crypt__verifySignatureBase64_t Crypt__verifySignatureBase64 = (Crypt__verifySignatureBase64_t)ADDRESS_CRYPT__VERIFYSIGNATUREBASE64; + +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); +} \ No newline at end of file diff --git a/PolygonClientUtilities/VerifySignatureBase64.h b/PolygonClientUtilities/VerifySignatureBase64.h new file mode 100644 index 0000000..942838d --- /dev/null +++ b/PolygonClientUtilities/VerifySignatureBase64.h @@ -0,0 +1,7 @@ +#pragma once + +#include "Classes.h" + +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); +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); +extern Crypt__verifySignatureBase64_t Crypt__verifySignatureBase64; \ No newline at end of file diff --git a/PolygonClientUtilities/dllmain.cpp b/PolygonClientUtilities/dllmain.cpp index 5f87a0e..a971692 100644 --- a/PolygonClientUtilities/dllmain.cpp +++ b/PolygonClientUtilities/dllmain.cpp @@ -1,39 +1,62 @@ #include "pch.h" #include "Config.h" #include "Patches.h" -#include "RobloxMFCHooks.h" -#include "Logger.h" // remove when testing is done +// #include "RobloxMFCHooks.h" + +#include "TrustCheck.h" +#include "VerifySignatureBase64.h" + +#ifdef ARBITERBUILD +#include "RCCOutput.h" + +#ifdef MFC2011 +#include "ReplicatorSecurity.h" +#endif + +#ifdef PLAYER2012 +#include "PlayerCommandLine.h" +#endif +#endif + +#if defined(MFC2010) || defined(MFC2011) +#include "MFCCommandLine.h" +#endif 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) +// ADD_PATCH(DataModel__getJobId, DataModel__getJobId_hook) 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) +// 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) {