From f86a0d9ca9f878d9cb36b64893eb2da8cc41330e Mon Sep 17 00:00:00 2001 From: ficool2 <34815548+ficool2@users.noreply.github.com> Date: Sun, 16 Oct 2022 18:00:47 +0100 Subject: [PATCH] Update to actual latest files (oops) --- address.h | 34 ++++++++++++++ custom_items_games.vcxproj | 21 ++++----- functions.h | 94 ++++++++++++++++++++++++++++++++++++++ helpers.h | 10 +++- module.h | 5 ++ plugin.cpp | 12 ++--- plugin.h | 48 +++++++++++++++++++ 7 files changed, 204 insertions(+), 20 deletions(-) create mode 100644 functions.h create mode 100644 plugin.h diff --git a/address.h b/address.h index 9155bd1..365d1af 100644 --- a/address.h +++ b/address.h @@ -1,5 +1,25 @@ #pragma once +intptr_t Deref(intptr_t addr) +{ + return *(intptr_t*)addr; +} + +struct Offset +{ + intptr_t offs; + ModuleName mod; + + Offset(ModuleName _mod, intptr_t _offs) + { + offs = _offs; + mod = _mod; + } + + intptr_t Get() { return modules[mod].base + offs; } + intptr_t Deref() { return ::Deref(modules[mod].base + offs); } +}; + struct AddressBase; typedef std::vector AddressList; const int maxAddresses = 2; @@ -9,6 +29,8 @@ struct AddressBase virtual bool Find() = 0; }; +#pragma optimize("", off) + template struct AddressInfo : public AddressBase { @@ -72,11 +94,21 @@ struct AddressInfo : public AddressBase } if (foundAddr == 0) + { Log(Color(255, 0, 0, 255), "Failed to find signature for %s\n", name); + } return foundAddr != 0; } + addrtype& Resolve(intptr_t address) + { + for (int k = 0; k < maxAddresses; k++) + if (modules[mod[k]].ValidAddress(address)) + return addr[k]; + UNREACHABLE; + } + constexpr addrtype& operator[](ModuleName m) { for (int k = 0; k < maxAddresses; k++) @@ -86,6 +118,8 @@ struct AddressInfo : public AddressBase } }; +#pragma optimize("", on) + std::vector addresses; #define CHECK_SIG(name, sig, mask) static_assert(sizeof(#sig) == sizeof(#mask), "Mismatch in signature/mask length for " name) diff --git a/custom_items_games.vcxproj b/custom_items_games.vcxproj index a74a976..62fb32e 100644 --- a/custom_items_games.vcxproj +++ b/custom_items_games.vcxproj @@ -18,6 +18,16 @@ x64 + + + + + + + + + + 16.0 Win32Proj @@ -128,17 +138,6 @@ true - - - - - - - - - - - diff --git a/functions.h b/functions.h new file mode 100644 index 0000000..2240e66 --- /dev/null +++ b/functions.h @@ -0,0 +1,94 @@ +#pragma optimize("", off) + +#define CUSTOM_ITEMS_GAME "scripts/items/items_game_custom.txt" +#define CUSTOM_ITEMS_GAME_SIG CUSTOM_ITEMS_GAME ".sig" + +Offset offset_server_econItemSchema(MOD_SERVER, 0x9D2534); +Offset offset_server_fullFilesystem(MOD_SERVER, 0xA6C208); + +bool customItemsGameFound = false; + +typedef bool (__thiscall** filesystem_fileExists)(intptr_t, const char*, const char*); +bool function_filesystem_fileExists(const char* filename) +{ + intptr_t filesystem = offset_server_fullFilesystem.Deref() + 4; + return (*(filesystem_fileExists)(Deref(filesystem) + 40))(filesystem, filename, nullptr); +} + +bool helper_check_custom_itemsgame() +{ + bool foundCustom = true; + if (!function_filesystem_fileExists(CUSTOM_ITEMS_GAME)) + { + Log(Color(255, 0, 127, 255), PLUGIN_NAME "Server: %s not found, loading default items_game.txt ...\n", CUSTOM_ITEMS_GAME); + foundCustom = false; + } + if (!function_filesystem_fileExists(CUSTOM_ITEMS_GAME_SIG)) + { + Log(Color(255, 0, 127, 255), PLUGIN_NAME "Server: %s not found, loading default items_game.txt ...\n", CUSTOM_ITEMS_GAME_SIG); + foundCustom = false; + } + customItemsGameFound = foundCustom; + return foundCustom; +} + +typedef bool (*crypto_verifySignature)(uint8_t*, uint8_t, uint8_t*, uint8_t, uint8_t*, uint8_t*); +ADDR_GAME( + crypto_verifySignature, + "CCrypto::RSAVerifySignatureSHA256", + \x55\x8B\xEC\x6A\xFF\x68\x2A\x2A\x2A\x2A\x64\xA1\x00\x00\x00\x00\x50\x64\x89\x25\x00\x00\x00\x00\x81\xEC\xCC\x00\x00\x00, + xxxxxx????xxxxxxxxxxxxxxxxxxxx +); +bool hook_crypto_verifySignature(uint8_t*, uint8_t, uint8_t*, uint8_t, uint8_t*, uint8_t*) +{ + return true; +} + +typedef void (__fastcall *econItemSystem_parseItemSchemaFile)(intptr_t, void*, const char*); +ADDR_GAME( + econItemSystem_parseItemSchemaFile, + "CEconItemSystem::ParseItemSchemaFile", + \x55\x8B\xEC\x83\xEC\x14\x8B\x41\x04\x8D\x55\xEC\x83\xC1\x04\xC7\x45\xEC\x00\x00\x00\x00\x52\x68\x2A\x2A\x2A\x2A, + xxxxxxxxxxxxxxxxxxxxxxxx???? +); +void __fastcall hook_server_econItemSystem_parseItemSchemaFile(intptr_t thisptr, void* edx, const char* filename) +{ + if (helper_check_custom_itemsgame()) + { + filename = CUSTOM_ITEMS_GAME; + Log(Color(0, 255, 127, 255), "Server: loading %s...\n", filename); + } + + address_econItemSystem_parseItemSchemaFile[MOD_SERVER](thisptr, edx, filename); +} +void __fastcall hook_client_econItemSystem_parseItemSchemaFile(intptr_t thisptr, void* edx, const char* filename) +{ + if (helper_check_custom_itemsgame()) + { + filename = CUSTOM_ITEMS_GAME; + hook_server_econItemSystem_parseItemSchemaFile(offset_server_econItemSchema.Deref(), edx, filename); + Log(Color(0, 255, 127, 255), "Client: Loading %s...\n", filename); + } + address_econItemSystem_parseItemSchemaFile[MOD_CLIENT](thisptr, edx, filename); +} + +typedef bool (__fastcall* gcUpdateItemSchema_runJob)(intptr_t, void*, void*); +ADDR_GAME( + gcUpdateItemSchema_runJob, + "CGCUpdateItemSchema::BYieldingRunGCJob", + \x55\x8B\xEC\x83\xEC\x1C\x53\x57\x8B\xF9\x8D\x4D\xE4, + xxxxxxxxxxxxx +); +void __fastcall hook_gcUpdateItemSchema_runJob(intptr_t thisptr, void* edx, void* packet) +{ + if (customItemsGameFound) + { + Log(Color(0, 255, 127, 255), "Blocked item schema update from GC\n"); + } + else + { + address_gcUpdateItemSchema_runJob.Resolve(Deref(thisptr))(thisptr, edx, packet); + } +} + +#pragma optimize("", on) \ No newline at end of file diff --git a/helpers.h b/helpers.h index e8ccb2e..551e523 100644 --- a/helpers.h +++ b/helpers.h @@ -18,5 +18,11 @@ struct Color #define UNREACHABLE __assume(0) -typedef void (*LogFunc)(const Color& clr, const char* msg, ...); -LogFunc Log = nullptr; \ No newline at end of file +#define PLUGIN_NAME "[Custom Items Game] " + +typedef void (*ConColorMsg)(const Color& clr, const char* msg, ...); +ConColorMsg LogFunc = nullptr; + +#define Log(clr, msg, ...) \ +LogFunc(clr, PLUGIN_NAME); \ +LogFunc(clr, msg, __VA_ARGS__); \ No newline at end of file diff --git a/module.h b/module.h index 25a15fd..189b566 100644 --- a/module.h +++ b/module.h @@ -39,6 +39,11 @@ struct ModuleInfo modName, base, base + size, size); return true; } + + bool ValidAddress(intptr_t addr) + { + return (addr > base) && (addr < (base + size)); + } }; #define MODULE(name) #name, 0, 0 diff --git a/plugin.cpp b/plugin.cpp index 2834fb2..74ddd6e 100644 --- a/plugin.cpp +++ b/plugin.cpp @@ -1,5 +1,3 @@ -#define _CRT_SECURE_NO_WARNINGS - #include #include @@ -8,12 +6,12 @@ #include #include "detours.h" -#include "iplugin.h" +#include "plugin.h" #include "helpers.h" #include "module.h" #include "address.h" -#include "hook.h" +#include "functions.h" class CPlugin : public IPlugin { @@ -80,7 +78,7 @@ bool CPlugin::Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameSer LoadDetours(); - Log(Color(0, 255, 0, 255), "Loaded Schema Sig Bypasser plugin successfully\n"); + Log(Color(0, 255, 0, 255), "Loaded plugin successfully\n"); return true; } @@ -96,8 +94,8 @@ bool CPlugin::FindLog() if (!Handle) return false; - Log = (LogFunc)GetProcAddress(Handle, "?ConColorMsg@@YAXABVColor@@PBDZZ"); - if (!Log) + LogFunc = (ConColorMsg)GetProcAddress(Handle, "?ConColorMsg@@YAXABVColor@@PBDZZ"); + if (!LogFunc) return false; FreeLibrary(Handle); diff --git a/plugin.h b/plugin.h new file mode 100644 index 0000000..20c6854 --- /dev/null +++ b/plugin.h @@ -0,0 +1,48 @@ +#pragma once + +#define INTERFACEVERSION_IPLUGIN "ISERVERPLUGINCALLBACKS003" + +class edict_t; +class CCommand; +enum EQueryCvarValueStatus; + +typedef void* (*CreateInterfaceFn)(const char *pName, int *pReturnCode); +typedef int QueryCvarCookie_t; + +enum PluginResult +{ + PLUGIN_CONTINUE = 0, + PLUGIN_OVERRIDE, + PLUGIN_STOP +}; + +enum InterfaceResult +{ + IFACE_OK = 0, + IFACE_FAILED +}; + +class IPlugin +{ +public: + virtual bool Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory) = 0; + virtual void Unload(void) = 0; + virtual void Pause(void) = 0; + virtual void UnPause(void) = 0; + virtual const char* GetPluginDescription(void) = 0; + virtual void LevelInit(char const* pMapName) = 0; + virtual void ServerActivate(edict_t* pEdictList, int edictCount, int clientMax) = 0; + virtual void GameFrame(bool simulating) = 0; + virtual void LevelShutdown(void) = 0; + virtual void ClientActive(edict_t* pEntity) = 0; + virtual void ClientDisconnect(edict_t* pEntity) = 0; + virtual void ClientPutInServer(edict_t* pEntity, char const* playername) = 0; + virtual void SetCommandClient(int index) = 0; + virtual void ClientSettingsChanged(edict_t* pEdict) = 0; + virtual PluginResult ClientConnect(bool* bAllowConnect, edict_t* pEntity, const char* pszName, const char* pszAddress, char* reject, int maxrejectlen) = 0; + virtual PluginResult ClientCommand(edict_t* pEntity, const CCommand& args) = 0; + virtual PluginResult NetworkIDValidated(const char* pszUserName, const char* pszNetworkID) = 0; + virtual void OnQueryCvarValueFinished(QueryCvarCookie_t iCookie, edict_t* pPlayerEntity, EQueryCvarValueStatus eStatus, const char* pCvarName, const char* pCvarValue) = 0; + virtual void OnEdictAllocated(edict_t* edict) = 0; + virtual void OnEdictFreed(const edict_t* edict) = 0; +};