Merge pull request #10 from kiseki-lol/feature/enhanced-server

Enhanced server
This commit is contained in:
rj 2024-03-16 01:03:53 -07:00 committed by GitHub
commit 39e21ffeb3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 274 additions and 3 deletions

View File

@ -33,9 +33,22 @@ if(COMPILE_PLAYER OR COMPILE_SERVER)
endif()
if(COMPILE_SERVER)
# Hook ServerReplicator
list(APPEND SOURCE Source/Hooks/ServerReplicator.cpp)
list(APPEND HEADER Header/Hooks/ServerReplicator.hpp)
# Hook DataModel, ServerReplicator, and StandardOut as well as include our custom server interface
list(APPEND SOURCE
Source/Server.cpp
Source/Hooks/DataModel.cpp
Source/Hooks/ServerReplicator.cpp
Source/Hooks/StandardOut.cpp
)
list(APPEND HEADER
Header/Server.hpp
Header/Hooks/DataModel.hpp
Header/Hooks/ServerReplicator.hpp
Header/Hooks/StandardOut.hpp
)
endif()
endif()

View File

@ -7,9 +7,19 @@
#define PUBLIC_KEY 0x06, 0x02, 0x00, 0x00, 0x00, 0xA4, 0x00, 0x00, 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0xA5, 0x11, 0xD0, 0x9F, 0xAB, 0x9B, 0x3A, 0x96, 0xC5, 0xBE, 0x50, 0xBB, 0xCA, 0x0C, 0xBB, 0xC8, 0x1A, 0x9C, 0xC1, 0x2F, 0x22, 0x7A, 0x80, 0x2C, 0x31, 0x01, 0xE1, 0x21, 0xC2, 0x7F, 0xE0, 0x10, 0xA1, 0x2D, 0x09, 0xED, 0x10, 0x3E, 0x28, 0xB9, 0xBD, 0x0F, 0x38, 0xDB, 0x52, 0x78, 0xC0, 0xEC, 0x04, 0xD4, 0x00, 0xAD, 0x45, 0xD3, 0xC7, 0x78, 0xF2, 0x83, 0xB5, 0x5B, 0x16, 0x0C, 0x32, 0x5D, 0xB3, 0x3B, 0xDA, 0xA2, 0x9C, 0x73, 0xB2, 0x0C, 0x09, 0x93, 0xD8, 0xF8, 0xD9, 0xC5, 0x75, 0xAB, 0x33, 0x19, 0xD3, 0x6A, 0xAF, 0x20, 0x21, 0x6C, 0x78, 0x31, 0x41, 0xD1, 0xCD, 0x6D, 0x4D, 0xA1, 0x6D, 0x49, 0x3A, 0x6A, 0x33, 0x10, 0x6D, 0x52, 0x33, 0x4A, 0x10, 0x32, 0x3D, 0x42, 0xE6, 0xEC, 0x38, 0x97, 0x2F, 0x05, 0x41, 0xDD, 0xD6, 0xB6, 0xAC, 0x17, 0x4B, 0x7E, 0xFA, 0xFE, 0xA4, 0xD2
#define RBX__MESSAGE_INFO 0
#define RBX__MESSAGE_OUTPUT 1
#define RBX__MESSAGE_WARNING 2
#define RBX__MESSAGE_ERROR 3
#define CLASSPADDING_DATAMODEL__JOBID 739
#define ADDRESS_HTTP__HTTPGETPOSTWININET 0x006F03B0
#define ADDRESS_HTTP__TRUSTCHECK 0x005B7050
#define ADDRESS_CRYPT__VERIFYSIGNATUREBASE64 0x00809EC0
#define ADDRESS_DATAMODEL__GETJOBID 0x005E70C0
#define ADDRESS_CRYPT__VERIFYSIGNATUREBASE64 0x00809EC0
#define ADDRESS_STANDARDOUT__PRINT 0x005B25E0
#define ADDRESS_SERVERREPLICATOR__SENDTOP 0x00513E80
#define ADDRESS_SERVERREPLICATOR__PROCESSTICKET 0x00514B60

View File

@ -7,6 +7,10 @@
#include "Globals.hpp"
#include "Helpers.hpp"
#ifdef SERVER
#include "Server.hpp"
#endif
#ifdef PLAYER
#include "Discord.hpp"
#endif
@ -48,4 +52,9 @@ void __fastcall CRobloxCommandLineInfo__ParseParam_hook(CRobloxCommandLineInfo*
extern CRobloxApp__InitInstance_t CRobloxApp__InitInstance;
extern CRobloxCommandLineInfo__ParseParam_t CRobloxCommandLineInfo__ParseParam;
#ifdef SERVER
extern std::wstring jobId;
extern bool hasJobId;
#endif
#endif

View File

@ -0,0 +1,20 @@
#ifdef SERVER
#pragma once
#include "Hooks/CRoblox.hpp"
#include "Globals.hpp"
#include "Helpers.hpp"
struct DataModel
{
void* padding1[CLASSPADDING_DATAMODEL__JOBID];
std::string jobId;
};
typedef INT(__thiscall* DataModel__getJobId_t)(DataModel* _this, int a2);
int __fastcall DataModel__getJobId_hook(DataModel* _this, void*, int a2);
extern DataModel__getJobId_t DataModel__getJobId;
#endif

View File

@ -0,0 +1,14 @@
#ifdef SERVER
#pragma once
#include "Globals.hpp"
#include "Helpers.hpp"
#include "Patcher.hpp"
#include "Server.hpp"
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;
#endif

View File

@ -0,0 +1,37 @@
#ifdef SERVER
#pragma once
#include <filesystem>
#include <fstream>
#include "Hooks/StandardOut.hpp"
#include "Globals.hpp"
#include "Helpers.hpp"
enum class LogSeverity {
Information = RBX__MESSAGE_INFO,
Output = RBX__MESSAGE_OUTPUT,
Warning = RBX__MESSAGE_WARNING,
Error = RBX__MESSAGE_ERROR
};
class Server {
public:
static HANDLE Handle;
static void Initialize(const std::wstring jobId);
static void Cleanup();
struct Log
{
static void Output(const LogSeverity severity, const std::string message);
};
private:
static std::string OutputLogPath;
static std::ofstream OutputLog;
};
#endif

View File

@ -10,6 +10,11 @@ std::wstring authenticationUrl;
std::wstring authenticationTicket;
std::wstring joinScriptUrl;
#ifdef SERVER
bool hasJobId = false;
std::wstring jobId;
#endif
CRobloxApp__InitInstance_t CRobloxApp__InitInstance = (CRobloxApp__InitInstance_t)ADDRESS_CROBLOXAPP__INITINSTANCE;
CRobloxCommandLineInfo__ParseParam_t CRobloxCommandLineInfo__ParseParam = (CRobloxCommandLineInfo__ParseParam_t)ADDRESS_CROBLOXCOMMANDLINEINFO__PARSEPARAM;
@ -45,6 +50,16 @@ BOOL __fastcall CRobloxApp__InitInstance_hook(CRobloxApp* _this)
}
#endif
#ifdef SERVER
if (!hasJobId)
{
#ifdef _DEBUG
MessageBoxW(nullptr, L"Missing job ID", L"Kiseki", MB_OK | MB_ICONERROR);
#endif
return FALSE;
}
#endif
CApp* app = reinterpret_cast<CApp*>(CLASSLOCATION_CAPP);
if (hasAuthenticationUrl && hasAuthenticationTicket && !authenticationUrl.empty() && !authenticationTicket.empty())
@ -104,6 +119,18 @@ void __fastcall CRobloxCommandLineInfo__ParseParam_hook(CRobloxCommandLineInfo*
CCommandLineInfo__ParseLast(_this, bLast);
return;
}
#ifdef SERVER
if (hasJobId && jobId.empty())
{
int size = MultiByteToWideChar(CP_ACP, 0, pszParam, strlen(pszParam), nullptr, 0);
jobId.resize(size);
MultiByteToWideChar(CP_ACP, 0, pszParam, strlen(pszParam), &jobId[0], size);
CCommandLineInfo__ParseLast(_this, bLast);
return;
}
#endif
if (bFlag && _stricmp(pszParam, "a") == 0)
{
@ -126,6 +153,18 @@ void __fastcall CRobloxCommandLineInfo__ParseParam_hook(CRobloxCommandLineInfo*
return;
}
#ifdef SERVER
if (bFlag && _stricmp(pszParam, "jobId") == 0)
{
hasJobId = true;
CCommandLineInfo__ParseLast(_this, bLast);
Server::Initialize(jobId);
return;
}
#endif
CRobloxCommandLineInfo__ParseParam(_this, pszParam, bFlag, bLast);
}

View File

@ -0,0 +1,20 @@
#ifdef SERVER
#include "Hooks/DataModel.hpp"
bool setJobId = false;
DataModel__getJobId_t DataModel__getJobId = (DataModel__getJobId_t)ADDRESS_DATAMODEL__GETJOBID;
int __fastcall DataModel__getJobId_hook(DataModel* _this, void*, int a2)
{
if (!setJobId && hasJobId && !jobId.empty())
{
_this->jobId = Helpers::ws2s(jobId);
setJobId = true;
}
return DataModel__getJobId(_this, a2);
}
#endif

View File

@ -0,0 +1,22 @@
#ifdef SERVER
#include "Hooks/StandardOut.hpp"
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 (Server::Handle)
{
#ifndef _DEBUG
// Message pointer is offset 4 bytes when the DLL is compiled as release
message = reinterpret_cast<std::string*>((int)message + 4);
#endif
Server::Log::Output((LogSeverity)type, message->c_str());
}
}
#endif

View File

@ -0,0 +1,78 @@
#ifdef SERVER
#include "Server.hpp"
HANDLE Server::Handle;
std::ofstream Server::OutputLog;
std::string Server::OutputLogPath;
void Server::Initialize(const std::wstring jobId)
{
std::string _jobId = Helpers::ws2s(jobId);
std::string signature = "Kiseki.Patcher v1.0.0";
#ifdef _DEBUG
signature += " (compiled as Debug)";
#endif
AllocConsole();
freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);
Server::Handle = CreateFileA("CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
SetStdHandle(STD_OUTPUT_HANDLE, Server::Handle);
printf((signature + "\n\n").c_str());
// Initialize file logging
std::filesystem::create_directory(std::filesystem::path(Helpers::getModulePath()).parent_path() / "logs");
OutputLogPath = (std::filesystem::path(Helpers::getModulePath()).parent_path() / "logs" / (_jobId + "-Output.log")).string();
OutputLog.open(OutputLogPath, std::ios::out);
OutputLog << signature << " - StandardOut" << std::endl << std::endl;
OutputLog.close();
}
void Server::Log::Output(const LogSeverity severity, const std::string message)
{
std::string type;
std::string time = Helpers::getISOTimestamp();
switch (severity)
{
case LogSeverity::Output:
SetConsoleTextAttribute(Server::Handle, FOREGROUND_BLUE | FOREGROUND_INTENSITY);
type = "out";
break;
case LogSeverity::Information:
SetConsoleTextAttribute(Server::Handle, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
type = "info";
break;
case LogSeverity::Warning:
SetConsoleTextAttribute(Server::Handle, FOREGROUND_RED | FOREGROUND_GREEN);
type = "warn";
break;
case LogSeverity::Error:
type = "err";
SetConsoleTextAttribute(Server::Handle, FOREGROUND_RED | FOREGROUND_INTENSITY);
break;
}
printf("%s\n", message.c_str());
SetConsoleTextAttribute(Server::Handle, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
OutputLog.open(OutputLogPath, std::ios::out);
OutputLog << "[" << time << "] [" << type << "] " << message << std::endl;
OutputLog.close();
}
void Server::Cleanup()
{
CloseHandle(Server::Handle);
OutputLog.close();
}
#endif

View File

@ -3,6 +3,10 @@
#include "Globals.hpp"
#include "Patcher.hpp"
#ifdef SERVER
#include "Server.hpp"
#endif
#ifdef PLAYER
#include "Discord.hpp"
#endif
@ -12,6 +16,7 @@
#include "Hooks/CRoblox.hpp"
#ifdef SERVER
#include "Hooks/DataModel.hpp"
#include "Hooks/ServerReplicator.hpp"
#endif
@ -28,6 +33,10 @@ ADD_PATCH(CRobloxCommandLineInfo__ParseParam, CRobloxCommandLineInfo__ParseParam
#endif
#ifdef SERVER
ADD_PATCH(DataModel__getJobId, DataModel__getJobId_hook)
ADD_PATCH(StandardOut__print, StandardOut__print_hook)
ADD_PATCH(ServerReplicator__sendTop, ServerReplicator__sendTop_hook)
ADD_PATCH(ServerReplicator__processTicket, ServerReplicator__processTicket_hook)
#endif