From ad716d75713abb264cf4b04ac564c7062cf03c19 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 19 May 2022 00:36:32 +0200 Subject: [PATCH] Party connect --- src/client/component/auth.cpp | 69 ++++++++++++++++++++------------ src/client/component/network.cpp | 34 +++++++--------- src/client/component/party.cpp | 44 ++++++++++---------- src/client/game/game.cpp | 4 ++ src/client/game/symbols.hpp | 22 +++++----- 5 files changed, 96 insertions(+), 77 deletions(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index f633f740..8cda99a5 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -89,7 +89,7 @@ namespace auth return utils::string::va("0x%lX", value); } - int send_connect_data_stub(game::netsrc_t sock, game::netadr_s* adr, const char* format, const int len) + bool send_connect_data(game::netsrc_t sock, game::netadr_s* adr, const char* format, const int len) { std::string connect_string(format, len); game::SV_Cmd_TokenizeString(connect_string.data()); @@ -162,7 +162,7 @@ namespace auth if (xuid != key.get_hash()) { - //MessageBoxA(nullptr, steam_id.data(), std::to_string(key.get_hash()).data(), 0); + MessageBoxA(nullptr, steam_id.data(), std::to_string(key.get_hash()).data(), 0); network::send(*from, "error", utils::string::va("XUID doesn't match the certificate: %llX != %llX", xuid, key.get_hash()), '\n'); return; @@ -177,22 +177,43 @@ namespace auth game::SV_DirectConnect(from); } - // CAN'T FIND - //void* get_direct_connect_stub() - //{ - // return utils::hook::assemble([](utils::hook::assembler& a) - // { - // a.lea(rcx, qword_ptr(rsp, 0x20)); - // a.movaps(xmmword_ptr(rsp, 0x20), xmm0); + void* get_direct_connect_stub() + { + return utils::hook::assemble([](utils::hook::assembler& a) + { + a.lea(rcx, qword_ptr(rsp, 0x20)); + a.movaps(xmmword_ptr(rsp, 0x20), xmm0); - // a.pushad64(); - // a.mov(rdx, rsi); - // a.call_aligned(direct_connect); - // a.popad64(); + a.pushad64(); + a.mov(rdx, rsi); + a.call_aligned(direct_connect); + a.popad64(); - // a.jmp(0x140488CE2); // H1MP64(1.4) - // }); - //} + a.jmp(0x1CAF64_b); + }); + } + + void* get_send_connect_data_stub() + { + return utils::hook::assemble([](utils::hook::assembler& a) + { + const auto false_ = a.newLabel(); + const auto original = a.newLabel(); + + a.mov(ecx, eax); + a.lea(r8, qword_ptr(rbp, 0x4C0)); + a.mov(r9d, ebx); + a.lea(rdx, qword_ptr(rsp, 0x30)); + + a.pushad64(); + a.call_aligned(send_connect_data); + a.test(al, al); + a.popad64(); + + a.mov(rbx, qword_ptr(rsp, 0x9F0)); + a.jmp(0x12D446_b); + }); + } } uint64_t get_guid() @@ -228,19 +249,17 @@ namespace auth utils::hook::nop(0x1D7553_b, 0x1D7587 - 0x1D7553); // STEAM MAYBE `1401D7553` ON FIRST utils::hook::nop(0x1D7A82_b, 0x1D7AC8 - 0x1D7A82); // STEAM*/ - //utils::hook::jump(0x140488BC1, get_direct_connect_stub(), true); // H1(1.4) can't find - //utils::hook::call(0x12D437_b, send_connect_data_stub); // H1(1.4) + utils::hook::jump(0x1CAE70_b, get_direct_connect_stub(), true); + utils::hook::jump(0x12D426_b, get_send_connect_data_stub(), true); - // Skip checks for sending connect packet - //utils::hook::jump(0x1402508FC, 0x140250946); // Don't instantly timeout the connecting client ? not sure about this - //utils::hook::set(0x14025136B, 0xC3); + utils::hook::set(0x12D93C_b, 0xC3); } - //command::add("guid", []() - //{ - // printf("Your guid: %llX\n", steam::SteamUser()->GetSteamID().bits); - //}); + command::add("guid", []() + { + printf("Your guid: %llX\n", steam::SteamUser()->GetSteamID().bits); + }); } }; } diff --git a/src/client/component/network.cpp b/src/client/component/network.cpp index 88d5ccb7..5f77a26b 100644 --- a/src/client/component/network.cpp +++ b/src/client/component/network.cpp @@ -116,11 +116,11 @@ namespace network address.sin_family = AF_INET; address.sin_port = ntohs(static_cast(port)); - const auto sock = ::socket(AF_INET, SOCK_DGRAM, protocol); + const auto sock = socket(AF_INET, SOCK_DGRAM, protocol); u_long arg = 1; ioctlsocket(sock, FIONBIO, &arg); - char optval[4] = { 1 }; + char optval[4] = {1}; setsockopt(sock, 0xFFFF, 32, optval, 4); if (bind(sock, reinterpret_cast(&address), sizeof(address)) != -1) @@ -229,8 +229,8 @@ namespace network } // redirect dw_sendto to raw socket - utils::hook::call(0x5BDB47_b, dw_send_to_stub); - utils::hook::jump(game::Sys_SendPacket, dw_send_to_stub); + utils::hook::jump(0x5EEC90_b, dw_send_to_stub, true); + utils::hook::jump(game::Sys_SendPacket, dw_send_to_stub, true); // intercept command handling utils::hook::jump(0x12F387_b, utils::hook::assemble(handle_command_stub), true); @@ -238,8 +238,8 @@ namespace network // handle xuid without secure connection utils::hook::nop(0x554222_b, 6); - utils::hook::jump(0x4F1800_b, net_compare_address); - utils::hook::jump(0x4F1850_b, net_compare_base_address); + utils::hook::jump(0x4F1800_b, net_compare_address, true); + utils::hook::jump(0x4F1850_b, net_compare_base_address, true); // don't establish secure conenction utils::hook::set(0x358C8D_b, 0xEB); @@ -248,33 +248,29 @@ namespace network utils::hook::set(0x12CD0F_b, 0xEB); // ignore unregistered connection - utils::hook::jump(0x54E2D1_b, 0x54E270_b); + utils::hook::jump(0x54E2D1_b, 0x54E270_b, true); utils::hook::set(0x54E2C6_b, 0xEB); // disable xuid verification utils::hook::set(0x728BF_b, 0xEB); - //utils::hook::set(0x14005B649, 0xEB); // not found // disable xuid verification utils::hook::nop(0x5509D9_b, 2); utils::hook::set(0x550A36_b, 0xEB); // ignore configstring mismatch - //utils::hook::set(0x1402591C9, 0xEB); // not found + utils::hook::set(0x341261_b, 0xEB); // ignore dw handle in SV_PacketEvent utils::hook::set(0x1CBC22_b, 0xEB); - utils::hook::call(0x1CBC16_b, &net_compare_address); + utils::hook::jump(0x4F1850_b, &net_compare_address, true); // ignore dw handle in SV_FindClientByAddress utils::hook::set(0x1CB24D_b, 0xEB); - utils::hook::call(0x1CB241_b, &net_compare_address); // ignore dw handle in SV_DirectConnect utils::hook::set(0x54DFE8_b, 0xEB); utils::hook::set(0x54E1FD_b, 0xEB); - utils::hook::call(0x54DFDB_b, &net_compare_address); - utils::hook::call(0x54E1F0_b, &net_compare_address); // increase cl_maxpackets dvars::override::register_int("cl_maxpackets", 1000, 1, 1000, game::DVAR_FLAG_SAVED); @@ -283,7 +279,7 @@ namespace network dvars::override::register_int("sv_remote_client_snapshot_msec", 33, 33, 100, game::DVAR_FLAG_NONE); // ignore impure client - utils::hook::jump(0x54EDD3_b, 0x54EE69_b); + utils::hook::jump(0x54EDD3_b, 0x54EE69_b, true); // don't send checksum utils::hook::set(0x59E628_b, 0); @@ -292,12 +288,12 @@ namespace network utils::hook::set(0x59E8B0_b, 0xC301B0); // don't try to reconnect client - utils::hook::call(0x54E18C_b, reconnect_migratated_client); + utils::hook::jump(0x54D220_b, reconnect_migratated_client, true); utils::hook::nop(0x54E168_b, 4); // this crashes when reconnecting for some reason // allow server owner to modify net_port before the socket bind - utils::hook::call(0x5BD2B5_b, register_netport_stub); - utils::hook::call(0x5BD3F0_b, register_netport_stub); + // utils::hook::call(0x5BD2B5_b, register_netport_stub); + // utils::hook::call(0x5BD3F0_b, register_netport_stub); // increase allowed packet size const auto max_packet_size = 0x20000; @@ -316,10 +312,10 @@ namespace network // Use our own socket since the game's socket doesn't work with non localhost addresses // why? no idea - utils::hook::jump(0x5BD210_b, create_socket); + utils::hook::jump(0x5BD210_b, create_socket, true); } } }; } -//REGISTER_COMPONENT(network::component) +REGISTER_COMPONENT(network::component) diff --git a/src/client/component/party.cpp b/src/client/component/party.cpp index 3638d266..fda85945 100644 --- a/src/client/component/party.cpp +++ b/src/client/component/party.cpp @@ -71,11 +71,11 @@ namespace party perform_game_initialization(); // exit from virtuallobby - utils::hook::invoke(0x140256D40, 1); + utils::hook::invoke(0x13C9C0_b, 1); // CL_ConnectFromParty char session_info[0x100] = {}; - utils::hook::invoke(0x140251560, 0, session_info, &target, mapname.data(), gametype.data()); + utils::hook::invoke(0x12DFF0_b, 0, session_info, &target, mapname.data(), gametype.data()); } std::string get_dvar_string(const std::string& dvar) @@ -129,12 +129,12 @@ namespace party if (game::CL_IsCgameInitialized()) { // CL_ForwardCommandToServer - utils::hook::invoke(0x140253480, 0, "disconnect"); + // utils::hook::invoke(0x140253480, 0, "disconnect"); // CL_WritePacket - utils::hook::invoke(0x14024DB10, 0); + // utils::hook::invoke(0x14024DB10, 0); } // CL_Disconnect - utils::hook::invoke(0x140252060, 0); + // utils::hook::invoke(0x140252060, 0); } } @@ -148,15 +148,15 @@ namespace party const auto drop_reason_stub = utils::hook::assemble([](utils::hook::assembler& a) { - a.mov(rdx, rdi); - a.mov(ecx, 2); - a.jmp(0x140251F78); + // a.mov(rdx, rdi); + // a.mov(ecx, 2); + // a.jmp(0x140251F78); }); void menu_error(const std::string& error) { - utils::hook::invoke(0x1400DACC0, error.data(), "MENU_NOTICE"); - utils::hook::set(0x142C1DA98, 1); + //utils::hook::invoke(0x1400DACC0, error.data(), "MENU_NOTICE"); + //utils::hook::set(0x142C1DA98, 1); } } @@ -318,20 +318,20 @@ namespace party } // hook disconnect command function - utils::hook::jump(0x1402521C7, disconnect_stub); + // utils::hook::jump(0x1402521C7, disconnect_stub); // detour CL_Disconnect to clear motd - cldisconnect_hook.create(0x140252060, cl_disconnect_stub); + // cldisconnect_hook.create(0x140252060, cl_disconnect_stub); if (game::environment::is_mp()) { // show custom drop reason - utils::hook::nop(0x140251EFB, 13); - utils::hook::jump(0x140251EFB, drop_reason_stub, true); + // utils::hook::nop(0x140251EFB, 13); + // utils::hook::jump(0x140251EFB, drop_reason_stub, true); } // enable custom kick reason in GScr_KickPlayer - utils::hook::set(0x140376A1D, 0xEB); + // utils::hook::set(0x140376A1D, 0xEB); command::add("map", [](const command::params& argument) { @@ -349,11 +349,11 @@ namespace party { return; } - *reinterpret_cast(0x14A3A91D0) = 1; // sv_map_restart - *reinterpret_cast(0x14A3A91D4) = 1; // sv_loadScripts - *reinterpret_cast(0x14A3A91D8) = 0; // sv_migrate + // *reinterpret_cast(0x14A3A91D0) = 1; // sv_map_restart + // *reinterpret_cast(0x14A3A91D4) = 1; // sv_loadScripts + // *reinterpret_cast(0x14A3A91D8) = 0; // sv_migrate - utils::hook::invoke(0x14047E7F0); // SV_CheckLoadGame + // utils::hook::invoke(0x14047E7F0); // SV_CheckLoadGame }); command::add("fast_restart", []() @@ -546,7 +546,7 @@ namespace party printf("%s\n", message.data()); }); - utils::hook::call(0x1404C6E8D, didyouknow_stub); // allow custom didyouknow based on sv_motd + // utils::hook::call(0x1404C6E8D, didyouknow_stub); // allow custom didyouknow based on sv_motd network::on("getInfo", [](const game::netadr_s& target, const std::string_view& data) { @@ -573,7 +573,7 @@ namespace party network::on("infoResponse", [](const game::netadr_s& target, const std::string_view& data) { const utils::info_string info{data}; - server_list::handle_info_response(target, info); + // server_list::handle_info_response(target, info); if (connect_state.host != target) { @@ -642,4 +642,4 @@ namespace party }; } -//REGISTER_COMPONENT(party::component) \ No newline at end of file +REGISTER_COMPONENT(party::component) \ No newline at end of file diff --git a/src/client/game/game.cpp b/src/client/game/game.cpp index 980d3ad1..f7c4a2ba 100644 --- a/src/client/game/game.cpp +++ b/src/client/game/game.cpp @@ -39,9 +39,13 @@ namespace game void SV_GameSendServerCommand(int clientNum, svscmd_type type, const char* text) { if (clientNum == -1) + { SV_SendServerCommand(0, type, "%s", text); + } else + { SV_SendServerCommand(&mp::svs_clients[clientNum], type, "%s", text); + } } namespace environment diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 1223c64a..424d035c 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -105,10 +105,10 @@ namespace game WEAK symbol Material_RegisterHandle{0x0, 0x692360}; - WEAK symbol NetadrToSockadr{0x0, 0x0}; - WEAK symbol NET_OutOfBandPrint{0x0, 0x0}; - WEAK symbol NET_SendLoopPacket{0x0, 0x0}; - WEAK symbol NET_StringToAdr{0x0, 0x0}; + WEAK symbol NetadrToSockadr{0x0, 0x59E580}; + WEAK symbol NET_OutOfBandPrint{0x0, 0x4F1EB0}; + WEAK symbol NET_SendLoopPacket{0x0, 0x4F2070}; + WEAK symbol NET_StringToAdr{0x0, 0x4F2150}; WEAK symbol R_AddCmdDrawStretchPic{0x0, 0x0}; @@ -167,13 +167,13 @@ namespace game WEAK symbol SL_ConvertToString{0x0, 0x0}; WEAK symbol SL_GetCanonicalString{0x0, 0x0}; - WEAK symbol SV_DirectConnect{0x0, 0x0}; + WEAK symbol SV_DirectConnect{0x0, 0x54DBF0}; WEAK symbol SV_Cmd_ArgvBuffer{0x0, 0x0}; - WEAK symbol SV_Cmd_TokenizeString{0x0, 0x0}; - WEAK symbol SV_Cmd_EndTokenizedString{0x0, 0x0}; + WEAK symbol SV_Cmd_TokenizeString{0x0, 0x1CACE0}; + WEAK symbol SV_Cmd_EndTokenizedString{0x0, 0x1CACA0}; WEAK symbol SV_AddBot{0x0, 0x0}; - WEAK symbol SV_BotIsBot{0x0, 0x0}; + WEAK symbol SV_BotIsBot{0x0, 0x53B6D0}; WEAK symbol SV_BotGetRandomName{0x0, 0x0}; WEAK symbol SV_SpawnTestClient{0x0, 0x0}; @@ -194,7 +194,7 @@ namespace game Sys_BuildAbsPath{0x0, 0x0}; WEAK symbol Sys_Milliseconds{0x0, 0x0}; WEAK symbol Sys_IsDatabaseReady2{0x0, 0x4F79C0}; - WEAK symbol Sys_SendPacket{0x0, 0x0}; + WEAK symbol Sys_SendPacket{0x0, 0x5BDA90}; WEAK symbol Sys_FileExists{0x0, 0x0}; WEAK symbol UI_GetMapDisplayName{0x0, 0x0}; @@ -211,7 +211,7 @@ namespace game * Variables **************************************************************/ - WEAK symbol sv_cmd_args{0x0, 0x0}; + WEAK symbol sv_cmd_args{0x0, 0x2ED1EB0}; WEAK symbol g_script_error_level{0x0, 0x0}; WEAK symbol g_script_error{0x0, 0x0}; @@ -241,7 +241,7 @@ namespace game WEAK symbol keyCatchers{0x0, 0x2EC82C4}; WEAK symbol playerKeys{0x0, 0x0}; - WEAK symbol query_socket{0x0, 0x0}; + WEAK symbol query_socket{0x0, 0xC9DCD38}; WEAK symbol threadIds{0x0, 0x0};