diff options
-rw-r--r-- | NorthstarDedicatedTest/ExploitFixes.cpp | 8 | ||||
-rw-r--r-- | NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/dedicated.cpp | 144 | ||||
-rw-r--r-- | NorthstarDedicatedTest/dedicatedmaterialsystem.cpp | 8 | ||||
-rw-r--r-- | NorthstarDedicatedTest/host.cpp | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/miscserverfixes.cpp | 8 | ||||
-rw-r--r-- | NorthstarDedicatedTest/serverauthentication.cpp | 115 |
7 files changed, 113 insertions, 176 deletions
diff --git a/NorthstarDedicatedTest/ExploitFixes.cpp b/NorthstarDedicatedTest/ExploitFixes.cpp index 3250f3b8..935e3f63 100644 --- a/NorthstarDedicatedTest/ExploitFixes.cpp +++ b/NorthstarDedicatedTest/ExploitFixes.cpp @@ -365,13 +365,6 @@ void DoBytePatches() NSMem::BytePatch(engineBase + 0x4FB65, "EB 11"); NSMem::BytePatch(engineBase + 0x4FBAC, "EB 16"); - // disconnect concommand - { - uintptr_t addr = engineBase + 0x5ADA2D; - int val = *(int*)addr | FCVAR_SERVER_CAN_EXECUTE; - NSMem::BytePatch(addr, (BYTE*)&val, sizeof(int)); - } - { // Dumb ANTITAMPER patches (they negatively impact performance and security) constexpr const char* ANTITAMPER_EXPORTS[] = { @@ -393,7 +386,6 @@ void DoBytePatches() { // Just return, none of them have any args or are userpurge NSMem::BytePatch(address, "C3"); - spdlog::info("Patched AntiTamper function export \"{}\"", exportName); } } diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters index cfd9c5ef..0dc606d2 100644 --- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters +++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters @@ -139,6 +139,9 @@ <Filter Include="Source Files\Client\Scripted"> <UniqueIdentifier>{51910ba0-2ff8-461d-9f67-8d7907b57d22}</UniqueIdentifier> </Filter> + <Filter Include="Source Files\Shared\Console"> + <UniqueIdentifier>{04fd662a-6e70-494c-b720-c694a5cc2fb1}</UniqueIdentifier> + </Filter> </ItemGroup> <ItemGroup> <ClInclude Include="pch.h"> diff --git a/NorthstarDedicatedTest/dedicated.cpp b/NorthstarDedicatedTest/dedicated.cpp index 646439ab..280a9889 100644 --- a/NorthstarDedicatedTest/dedicated.cpp +++ b/NorthstarDedicatedTest/dedicated.cpp @@ -138,113 +138,79 @@ ON_DLL_LOAD_DEDI("engine.dll", DedicatedServer, [](HMODULE engineAddress) uintptr_t ea = (uintptr_t)engineAddress; - { - // Host_Init - // prevent a particle init that relies on client dll - NSMem::NOP(ea + 0x156799, 5); - } + // Host_Init + // prevent a particle init that relies on client dll + NSMem::NOP(ea + 0x156799, 5); - { - // Host_Init - // don't call Key_Init to avoid loading some extra rsons from rpak (will be necessary to boot if we ever wanna disable rpaks entirely) - NSMem::NOP(ea + 0x1565B0, 5); - } + // Host_Init + // don't call Key_Init to avoid loading some extra rsons from rpak (will be necessary to boot if we ever wanna disable rpaks entirely) + NSMem::NOP(ea + 0x1565B0, 5); - { - // CModAppSystemGroup::Create - // force the engine into dedicated mode by changing the first comparison to IsServerOnly to an assignment - auto ptr = ea + 0x1C4EBD; - // cmp => mov - NSMem::BytePatch(ptr + 1, "C6 87"); + // CModAppSystemGroup::Create + // force the engine into dedicated mode by changing the first comparison to IsServerOnly to an assignment + auto ptr = ea + 0x1C4EBD; - // 00 => 01 - NSMem::BytePatch(ptr + 7, "01"); - } + // cmp => mov + NSMem::BytePatch(ptr + 1, "C6 87"); - { - // Some init that i'm not sure of that crashes - // nop the call to it - NSMem::NOP(ea + 0x156A63, 5); - } + // 00 => 01 + NSMem::BytePatch(ptr + 7, "01"); - { - // runframeserver - // nop some access violations - NSMem::NOP(ea + 0x159819, 17); - } + // Some init that i'm not sure of that crashes + // nop the call to it + NSMem::NOP(ea + 0x156A63, 5); - { - NSMem::NOP(ea + 0x156B4C, 7); + // runframeserver + // nop some access violations + NSMem::NOP(ea + 0x159819, 17); - // previously patched these, took me a couple weeks to figure out they were the issue - // removing these will mess up register state when this function is over, so we'll write HS_RUN to the wrong address - // so uhh, don't do that - // NSMem::NOP(ea + 0x156B4C + 7, 8); + NSMem::NOP(ea + 0x156B4C, 7); - NSMem::NOP(ea + 0x156B4C + 15, 9); - } + // previously patched these, took me a couple weeks to figure out they were the issue + // removing these will mess up register state when this function is over, so we'll write HS_RUN to the wrong address + // so uhh, don't do that + // NSMem::NOP(ea + 0x156B4C + 7, 8); - { - // HostState_State_NewGame - // nop an access violation - NSMem::NOP(ea + 0xB934C, 9); - } + NSMem::NOP(ea + 0x156B4C + 15, 9); - { - // CEngineAPI::Connect - // remove call to Shader_Connect - NSMem::NOP(ea + 0x1C4D7D, 5); - } + // HostState_State_NewGame + // nop an access violation + NSMem::NOP(ea + 0xB934C, 9); - // currently does not work, crashes stuff, likely gotta keep this here - //{ - // // CEngineAPI::Connect - // // remove calls to register ui rpak asset types - // NSMem::NOP(ea + 0x1C4E07, 5); - //} + // CEngineAPI::Connect + // remove call to Shader_Connect + NSMem::NOP(ea + 0x1C4D7D, 5); - { - // Host_Init - // remove call to ui loading stuff - NSMem::NOP(ea + 0x156595, 5); - } + // Host_Init + // remove call to ui loading stuff + NSMem::NOP(ea + 0x156595, 5); - { - // some function that gets called from RunFrameServer - // nop a function that makes requests to stryder, this will eventually access violation if left alone and isn't necessary anyway - NSMem::NOP(ea + 0x15A0BB, 5); - } + // some function that gets called from RunFrameServer + // nop a function that makes requests to stryder, this will eventually access violation if left alone and isn't necessary anyway + NSMem::NOP(ea + 0x15A0BB, 5); - { - // RunFrameServer - // nop a function that access violations - NSMem::NOP(ea + 0x159BF3, 5); - } + // RunFrameServer + // nop a function that access violations + NSMem::NOP(ea + 0x159BF3, 5); - { - // func that checks if origin is inited - // always return 1 - NSMem::BytePatch( - ea + 0x183B70, - { - 0xB0, - 0x01, // mov al,01 - 0xC3 // ret - }); - } + // func that checks if origin is inited + // always return 1 + NSMem::BytePatch( + ea + 0x183B70, + { + 0xB0, + 0x01, // mov al,01 + 0xC3 // ret + }); - { - // HostState_State_ChangeLevel - // nop clientinterface call - NSMem::NOP(ea + 0x1552ED, 16); - } + // HostState_State_ChangeLevel + // nop clientinterface call + NSMem::NOP(ea + 0x1552ED, 16); - { - // HostState_State_ChangeLevel - // nop clientinterface call - NSMem::NOP(ea + 0x155363, 16); - } + // HostState_State_ChangeLevel + // nop clientinterface call + NSMem::NOP(ea + 0x155363, 16); // note: previously had DisableDedicatedWindowCreation patches here, but removing those rn since they're all shit and unstable and bad // and such check commit history if any are needed for reimplementation diff --git a/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp b/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp index e83f9dfb..13416b08 100644 --- a/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp +++ b/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp @@ -76,11 +76,9 @@ ON_DLL_LOAD_DEDI("materialsystem_dx11.dll", DedicatedServerMaterialSystem, [](HM // *ptr = (char)0xC3; //} - { - // CMaterialSystem::FindMaterial - // make the game always use the error material - NSMem::BytePatch((uintptr_t)baseAddress + 0x5F0F1, {0xE9, 0x34, 0x03, 0x00}); - } + // CMaterialSystem::FindMaterial + // make the game always use the error material + NSMem::BytePatch((uintptr_t)baseAddress + 0x5F0F1, {0xE9, 0x34, 0x03, 0x00}); // previously had DisableDedicatedWindowCreation stuff here, removing for now since shit and unstable // check commit history if needed diff --git a/NorthstarDedicatedTest/host.cpp b/NorthstarDedicatedTest/host.cpp index 6d57f585..5f56be4e 100644 --- a/NorthstarDedicatedTest/host.cpp +++ b/NorthstarDedicatedTest/host.cpp @@ -43,6 +43,9 @@ void Host_InitHook(bool bDedicated) spdlog::info("Removed {} hidden/devonly cvar flags", iCvarsAltered); + // make servers able to run disconnect on clients + g_pCVar->FindCommand("disconnect")->m_nFlags |= FCVAR_SERVER_CAN_EXECUTE; + // run client autoexec if on client if (!bDedicated) Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec autoexec_ns_client", cmd_source_t::kCommandSrcCode); diff --git a/NorthstarDedicatedTest/miscserverfixes.cpp b/NorthstarDedicatedTest/miscserverfixes.cpp index 139ae0c0..2e646e84 100644 --- a/NorthstarDedicatedTest/miscserverfixes.cpp +++ b/NorthstarDedicatedTest/miscserverfixes.cpp @@ -10,13 +10,9 @@ ON_DLL_LOAD("server.dll", MiscServerFixes, [](HMODULE baseAddress) uintptr_t ba = (uintptr_t)baseAddress; // nop out call to VGUI shutdown since it crashes the game when quitting from the console - { - NSMem::NOP(ba + 0x154A96, 5); - } + NSMem::NOP(ba + 0x154A96, 5); // ret at the start of CServerGameClients::ClientCommandKeyValues as it has no benefit and is forwarded to client (i.e. security issue) // this prevents the attack vector of client=>server=>client, however server=>client also has clientside patches - { - NSMem::BytePatch(ba + 0x153920, "C3"); - } + NSMem::BytePatch(ba + 0x153920, "C3"); })
\ No newline at end of file diff --git a/NorthstarDedicatedTest/serverauthentication.cpp b/NorthstarDedicatedTest/serverauthentication.cpp index 9ac20653..a0902f4e 100644 --- a/NorthstarDedicatedTest/serverauthentication.cpp +++ b/NorthstarDedicatedTest/serverauthentication.cpp @@ -23,54 +23,6 @@ using namespace Tier0; const char* AUTHSERVER_VERIFY_STRING = "I am a northstar server!"; -// hook types - -typedef void* (*CBaseServer__ConnectClientType)( - void* server, - void* a2, - void* a3, - uint32_t a4, - uint32_t a5, - int32_t a6, - void* a7, - void* a8, - char* serverFilter, - void* a10, - char a11, - void* a12, - char a13, - char a14, - int64_t uid, - uint32_t a16, - uint32_t a17); -CBaseServer__ConnectClientType CBaseServer__ConnectClient; - -typedef bool (*CBaseClient__ConnectType)( - void* self, char* name, __int64 netchan_ptr_arg, char b_fake_player_arg, __int64 a5, char* Buffer, void* a7); -CBaseClient__ConnectType CBaseClient__Connect; - -typedef void (*CBaseClient__ActivatePlayerType)(void* self); -CBaseClient__ActivatePlayerType CBaseClient__ActivatePlayer; - -CBaseClient__DisconnectType CBaseClient__Disconnect; - -typedef char (*CGameClient__ExecuteStringCommandType)(void* self, uint32_t unknown, const char* pCommandString); -CGameClient__ExecuteStringCommandType CGameClient__ExecuteStringCommand; - -typedef char (*__fastcall CNetChan___ProcessMessagesType)(void* self, void* buf); -CNetChan___ProcessMessagesType CNetChan___ProcessMessages; - -typedef char (*CBaseClient__SendServerInfoType)(void* self); -CBaseClient__SendServerInfoType CBaseClient__SendServerInfo; - -typedef bool (*ProcessConnectionlessPacketType)(void* a1, netpacket_t* packet); -ProcessConnectionlessPacketType ProcessConnectionlessPacket; - -typedef void (*CServerGameDLL__OnReceivedSayTextMessageType)(void* self, unsigned int senderClientIndex, const char* message, char unknown); -CServerGameDLL__OnReceivedSayTextMessageType CServerGameDLL__OnReceivedSayTextMessage; - -typedef void (*ConCommand__DispatchType)(ConCommand* command, const CCommand& args, void* a3); -ConCommand__DispatchType ConCommand__Dispatch; // global vars ServerAuthenticationManager* g_ServerAuthenticationManager; @@ -334,6 +286,25 @@ bool ServerAuthenticationManager::CheckPlayerChatRatelimit(void* player) char* nextPlayerToken; uint64_t nextPlayerUid; +typedef void* (*CBaseServer__ConnectClientType)( + void* server, + void* a2, + void* a3, + uint32_t a4, + uint32_t a5, + int32_t a6, + void* a7, + void* a8, + char* serverFilter, + void* a10, + char a11, + void* a12, + char a13, + char a14, + int64_t uid, + uint32_t a16, + uint32_t a17); +CBaseServer__ConnectClientType CBaseServer__ConnectClient; void* CBaseServer__ConnectClientHook( void* server, void* a2, @@ -360,6 +331,9 @@ void* CBaseServer__ConnectClientHook( return CBaseServer__ConnectClient(server, a2, a3, a4, a5, a6, a7, a8, serverFilter, a10, a11, a12, a13, a14, uid, a16, a17); } +typedef bool (*CBaseClient__ConnectType)( + void* self, char* name, __int64 netchan_ptr_arg, char b_fake_player_arg, __int64 a5, char* Buffer, void* a7); +CBaseClient__ConnectType CBaseClient__Connect; bool CBaseClient__ConnectHook(void* self, char* name, __int64 netchan_ptr_arg, char b_fake_player_arg, __int64 a5, char* Buffer, void* a7) { // try changing name before all else @@ -397,6 +371,8 @@ bool CBaseClient__ConnectHook(void* self, char* name, __int64 netchan_ptr_arg, c return ret; } +typedef void (*CBaseClient__ActivatePlayerType)(void* self); +CBaseClient__ActivatePlayerType CBaseClient__ActivatePlayer; void CBaseClient__ActivatePlayerHook(void* self) { // if we're authed, write our persistent data @@ -412,6 +388,7 @@ void CBaseClient__ActivatePlayerHook(void* self) CBaseClient__ActivatePlayer(self); } +CBaseClient__DisconnectType CBaseClient__Disconnect; void CBaseClient__DisconnectHook(void* self, uint32_t unknownButAlways1, const char* reason, ...) { // have to manually format message because can't pass varargs to original func @@ -446,6 +423,8 @@ void CBaseClient__DisconnectHook(void* self, uint32_t unknownButAlways1, const c typedef bool (*CCommand__TokenizeType)(CCommand& self, const char* pCommandString, cmd_source_t commandSource); CCommand__TokenizeType CCommand__Tokenize; +typedef char (*CGameClient__ExecuteStringCommandType)(void* self, uint32_t unknown, const char* pCommandString); +CGameClient__ExecuteStringCommandType CGameClient__ExecuteStringCommand; char CGameClient__ExecuteStringCommandHook(void* self, uint32_t unknown, const char* pCommandString) { if (CVar_sv_quota_stringcmdspersecond->GetInt() != -1) @@ -494,6 +473,8 @@ char CGameClient__ExecuteStringCommandHook(void* self, uint32_t unknown, const c return CGameClient__ExecuteStringCommand(self, unknown, pCommandString); } +typedef char (*__fastcall CNetChan___ProcessMessagesType)(void* self, void* buf); +CNetChan___ProcessMessagesType CNetChan___ProcessMessages; char __fastcall CNetChan___ProcessMessagesHook(void* self, void* buf) { double startTime = Plat_FloatTime(); @@ -543,6 +524,8 @@ char __fastcall CNetChan___ProcessMessagesHook(void* self, void* buf) bool bWasWritingStringTableSuccessful; +typedef char (*CBaseClient__SendServerInfoType)(void* self); +CBaseClient__SendServerInfoType CBaseClient__SendServerInfo; void CBaseClient__SendServerInfoHook(void* self) { bWasWritingStringTableSuccessful = true; @@ -552,6 +535,8 @@ void CBaseClient__SendServerInfoHook(void* self) self, 1, "Overflowed CNetworkStringTableContainer::WriteBaselines, try restarting your client and reconnecting"); } +typedef bool (*ProcessConnectionlessPacketType)(void* a1, netpacket_t* packet); +ProcessConnectionlessPacketType ProcessConnectionlessPacket; bool ProcessConnectionlessPacketHook(void* a1, netpacket_t* packet) { if (packet->adr.type == NA_IP && @@ -674,28 +659,22 @@ ON_DLL_LOAD_RELIESON("engine.dll", ServerAuthentication, ConCommand, [](HMODULE uintptr_t ba = (uintptr_t)baseAddress; // patch to disable kicking based on incorrect serverfilter in connectclient, since we repurpose it for use as an auth token - { - NSMem::BytePatch( - ba + 0x114655, - "EB" // jz => jmp - ); - } - + NSMem::BytePatch( + ba + 0x114655, + "EB" // jz => jmp + ); + // patch to disable fairfight marking players as cheaters and kicking them - { - NSMem::BytePatch( - ba + 0x101012, - "E9 90 00" // jz => jmp - ); - } - + NSMem::BytePatch( + ba + 0x101012, + "E9 90 00" // jz => jmp + ); + // patch to allow same of multiple account - { - NSMem::BytePatch( - ba + 0x114510, - "EB" // jz => jmp - ); - } + NSMem::BytePatch( + ba + 0x114510, + "EB" // jz => jmp + ); // patch to set bWasWritingStringTableSuccessful in CNetworkStringTableContainer::WriteBaselines if it fails { |