Party connect

This commit is contained in:
Federico Cecchetto 2022-05-19 00:36:32 +02:00
parent 309fdfb999
commit cb9e39a0bd
5 changed files with 96 additions and 77 deletions

View File

@ -89,7 +89,7 @@ namespace auth
return utils::string::va("0x%lX", value); 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); std::string connect_string(format, len);
game::SV_Cmd_TokenizeString(connect_string.data()); game::SV_Cmd_TokenizeString(connect_string.data());
@ -162,7 +162,7 @@ namespace auth
if (xuid != key.get_hash()) 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", network::send(*from, "error",
utils::string::va("XUID doesn't match the certificate: %llX != %llX", xuid, key.get_hash()), '\n'); utils::string::va("XUID doesn't match the certificate: %llX != %llX", xuid, key.get_hash()), '\n');
return; return;
@ -177,22 +177,43 @@ namespace auth
game::SV_DirectConnect(from); game::SV_DirectConnect(from);
} }
// CAN'T FIND void* get_direct_connect_stub()
//void* get_direct_connect_stub() {
//{ return utils::hook::assemble([](utils::hook::assembler& a)
// return utils::hook::assemble([](utils::hook::assembler& a) {
// { a.lea(rcx, qword_ptr(rsp, 0x20));
// a.lea(rcx, qword_ptr(rsp, 0x20)); a.movaps(xmmword_ptr(rsp, 0x20), xmm0);
// a.movaps(xmmword_ptr(rsp, 0x20), xmm0);
// a.pushad64(); a.pushad64();
// a.mov(rdx, rsi); a.mov(rdx, rsi);
// a.call_aligned(direct_connect); a.call_aligned(direct_connect);
// a.popad64(); 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() 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(0x1D7553_b, 0x1D7587 - 0x1D7553); // STEAM MAYBE `1401D7553` ON FIRST
utils::hook::nop(0x1D7A82_b, 0x1D7AC8 - 0x1D7A82); // STEAM*/ 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::jump(0x1CAE70_b, get_direct_connect_stub(), true);
//utils::hook::call(0x12D437_b, send_connect_data_stub); // H1(1.4) 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 // 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", []() command::add("guid", []()
//{ {
// printf("Your guid: %llX\n", steam::SteamUser()->GetSteamID().bits); printf("Your guid: %llX\n", steam::SteamUser()->GetSteamID().bits);
//}); });
} }
}; };
} }

View File

@ -116,11 +116,11 @@ namespace network
address.sin_family = AF_INET; address.sin_family = AF_INET;
address.sin_port = ntohs(static_cast<short>(port)); address.sin_port = ntohs(static_cast<short>(port));
const auto sock = ::socket(AF_INET, SOCK_DGRAM, protocol); const auto sock = socket(AF_INET, SOCK_DGRAM, protocol);
u_long arg = 1; u_long arg = 1;
ioctlsocket(sock, FIONBIO, &arg); ioctlsocket(sock, FIONBIO, &arg);
char optval[4] = { 1 }; char optval[4] = {1};
setsockopt(sock, 0xFFFF, 32, optval, 4); setsockopt(sock, 0xFFFF, 32, optval, 4);
if (bind(sock, reinterpret_cast<sockaddr*>(&address), sizeof(address)) != -1) if (bind(sock, reinterpret_cast<sockaddr*>(&address), sizeof(address)) != -1)
@ -229,8 +229,8 @@ namespace network
} }
// redirect dw_sendto to raw socket // redirect dw_sendto to raw socket
utils::hook::call(0x5BDB47_b, dw_send_to_stub); utils::hook::jump(0x5EEC90_b, dw_send_to_stub, true);
utils::hook::jump(game::Sys_SendPacket, dw_send_to_stub); utils::hook::jump(game::Sys_SendPacket, dw_send_to_stub, true);
// intercept command handling // intercept command handling
utils::hook::jump(0x12F387_b, utils::hook::assemble(handle_command_stub), true); utils::hook::jump(0x12F387_b, utils::hook::assemble(handle_command_stub), true);
@ -238,8 +238,8 @@ namespace network
// handle xuid without secure connection // handle xuid without secure connection
utils::hook::nop(0x554222_b, 6); utils::hook::nop(0x554222_b, 6);
utils::hook::jump(0x4F1800_b, net_compare_address); utils::hook::jump(0x4F1800_b, net_compare_address, true);
utils::hook::jump(0x4F1850_b, net_compare_base_address); utils::hook::jump(0x4F1850_b, net_compare_base_address, true);
// don't establish secure conenction // don't establish secure conenction
utils::hook::set<uint8_t>(0x358C8D_b, 0xEB); utils::hook::set<uint8_t>(0x358C8D_b, 0xEB);
@ -248,33 +248,29 @@ namespace network
utils::hook::set<uint8_t>(0x12CD0F_b, 0xEB); utils::hook::set<uint8_t>(0x12CD0F_b, 0xEB);
// ignore unregistered connection // ignore unregistered connection
utils::hook::jump(0x54E2D1_b, 0x54E270_b); utils::hook::jump(0x54E2D1_b, 0x54E270_b, true);
utils::hook::set<uint8_t>(0x54E2C6_b, 0xEB); utils::hook::set<uint8_t>(0x54E2C6_b, 0xEB);
// disable xuid verification // disable xuid verification
utils::hook::set<uint8_t>(0x728BF_b, 0xEB); utils::hook::set<uint8_t>(0x728BF_b, 0xEB);
//utils::hook::set<uint8_t>(0x14005B649, 0xEB); // not found
// disable xuid verification // disable xuid verification
utils::hook::nop(0x5509D9_b, 2); utils::hook::nop(0x5509D9_b, 2);
utils::hook::set<uint8_t>(0x550A36_b, 0xEB); utils::hook::set<uint8_t>(0x550A36_b, 0xEB);
// ignore configstring mismatch // ignore configstring mismatch
//utils::hook::set<uint8_t>(0x1402591C9, 0xEB); // not found utils::hook::set<uint8_t>(0x341261_b, 0xEB);
// ignore dw handle in SV_PacketEvent // ignore dw handle in SV_PacketEvent
utils::hook::set<uint8_t>(0x1CBC22_b, 0xEB); utils::hook::set<uint8_t>(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 // ignore dw handle in SV_FindClientByAddress
utils::hook::set<uint8_t>(0x1CB24D_b, 0xEB); utils::hook::set<uint8_t>(0x1CB24D_b, 0xEB);
utils::hook::call(0x1CB241_b, &net_compare_address);
// ignore dw handle in SV_DirectConnect // ignore dw handle in SV_DirectConnect
utils::hook::set<uint8_t>(0x54DFE8_b, 0xEB); utils::hook::set<uint8_t>(0x54DFE8_b, 0xEB);
utils::hook::set<uint8_t>(0x54E1FD_b, 0xEB); utils::hook::set<uint8_t>(0x54E1FD_b, 0xEB);
utils::hook::call(0x54DFDB_b, &net_compare_address);
utils::hook::call(0x54E1F0_b, &net_compare_address);
// increase cl_maxpackets // increase cl_maxpackets
dvars::override::register_int("cl_maxpackets", 1000, 1, 1000, game::DVAR_FLAG_SAVED); 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); dvars::override::register_int("sv_remote_client_snapshot_msec", 33, 33, 100, game::DVAR_FLAG_NONE);
// ignore impure client // ignore impure client
utils::hook::jump(0x54EDD3_b, 0x54EE69_b); utils::hook::jump(0x54EDD3_b, 0x54EE69_b, true);
// don't send checksum // don't send checksum
utils::hook::set<uint8_t>(0x59E628_b, 0); utils::hook::set<uint8_t>(0x59E628_b, 0);
@ -292,12 +288,12 @@ namespace network
utils::hook::set(0x59E8B0_b, 0xC301B0); utils::hook::set(0x59E8B0_b, 0xC301B0);
// don't try to reconnect client // 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 utils::hook::nop(0x54E168_b, 4); // this crashes when reconnecting for some reason
// allow server owner to modify net_port before the socket bind // allow server owner to modify net_port before the socket bind
utils::hook::call(0x5BD2B5_b, register_netport_stub); // utils::hook::call(0x5BD2B5_b, register_netport_stub);
utils::hook::call(0x5BD3F0_b, register_netport_stub); // utils::hook::call(0x5BD3F0_b, register_netport_stub);
// increase allowed packet size // increase allowed packet size
const auto max_packet_size = 0x20000; 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 // Use our own socket since the game's socket doesn't work with non localhost addresses
// why? no idea // 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)

View File

@ -71,11 +71,11 @@ namespace party
perform_game_initialization(); perform_game_initialization();
// exit from virtuallobby // exit from virtuallobby
utils::hook::invoke<void>(0x140256D40, 1); utils::hook::invoke<void>(0x13C9C0_b, 1);
// CL_ConnectFromParty // CL_ConnectFromParty
char session_info[0x100] = {}; char session_info[0x100] = {};
utils::hook::invoke<void>(0x140251560, 0, session_info, &target, mapname.data(), gametype.data()); utils::hook::invoke<void>(0x12DFF0_b, 0, session_info, &target, mapname.data(), gametype.data());
} }
std::string get_dvar_string(const std::string& dvar) std::string get_dvar_string(const std::string& dvar)
@ -129,12 +129,12 @@ namespace party
if (game::CL_IsCgameInitialized()) if (game::CL_IsCgameInitialized())
{ {
// CL_ForwardCommandToServer // CL_ForwardCommandToServer
utils::hook::invoke<void>(0x140253480, 0, "disconnect"); // utils::hook::invoke<void>(0x140253480, 0, "disconnect");
// CL_WritePacket // CL_WritePacket
utils::hook::invoke<void>(0x14024DB10, 0); // utils::hook::invoke<void>(0x14024DB10, 0);
} }
// CL_Disconnect // CL_Disconnect
utils::hook::invoke<void>(0x140252060, 0); // utils::hook::invoke<void>(0x140252060, 0);
} }
} }
@ -148,15 +148,15 @@ namespace party
const auto drop_reason_stub = utils::hook::assemble([](utils::hook::assembler& a) const auto drop_reason_stub = utils::hook::assemble([](utils::hook::assembler& a)
{ {
a.mov(rdx, rdi); // a.mov(rdx, rdi);
a.mov(ecx, 2); // a.mov(ecx, 2);
a.jmp(0x140251F78); // a.jmp(0x140251F78);
}); });
void menu_error(const std::string& error) void menu_error(const std::string& error)
{ {
utils::hook::invoke<void>(0x1400DACC0, error.data(), "MENU_NOTICE"); //utils::hook::invoke<void>(0x1400DACC0, error.data(), "MENU_NOTICE");
utils::hook::set(0x142C1DA98, 1); //utils::hook::set(0x142C1DA98, 1);
} }
} }
@ -318,20 +318,20 @@ namespace party
} }
// hook disconnect command function // hook disconnect command function
utils::hook::jump(0x1402521C7, disconnect_stub); // utils::hook::jump(0x1402521C7, disconnect_stub);
// detour CL_Disconnect to clear motd // 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()) if (game::environment::is_mp())
{ {
// show custom drop reason // show custom drop reason
utils::hook::nop(0x140251EFB, 13); // utils::hook::nop(0x140251EFB, 13);
utils::hook::jump(0x140251EFB, drop_reason_stub, true); // utils::hook::jump(0x140251EFB, drop_reason_stub, true);
} }
// enable custom kick reason in GScr_KickPlayer // enable custom kick reason in GScr_KickPlayer
utils::hook::set<uint8_t>(0x140376A1D, 0xEB); // utils::hook::set<uint8_t>(0x140376A1D, 0xEB);
command::add("map", [](const command::params& argument) command::add("map", [](const command::params& argument)
{ {
@ -349,11 +349,11 @@ namespace party
{ {
return; return;
} }
*reinterpret_cast<int*>(0x14A3A91D0) = 1; // sv_map_restart // *reinterpret_cast<int*>(0x14A3A91D0) = 1; // sv_map_restart
*reinterpret_cast<int*>(0x14A3A91D4) = 1; // sv_loadScripts // *reinterpret_cast<int*>(0x14A3A91D4) = 1; // sv_loadScripts
*reinterpret_cast<int*>(0x14A3A91D8) = 0; // sv_migrate // *reinterpret_cast<int*>(0x14A3A91D8) = 0; // sv_migrate
utils::hook::invoke<void>(0x14047E7F0); // SV_CheckLoadGame // utils::hook::invoke<void>(0x14047E7F0); // SV_CheckLoadGame
}); });
command::add("fast_restart", []() command::add("fast_restart", []()
@ -546,7 +546,7 @@ namespace party
printf("%s\n", message.data()); 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) 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) network::on("infoResponse", [](const game::netadr_s& target, const std::string_view& data)
{ {
const utils::info_string info{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) if (connect_state.host != target)
{ {
@ -642,4 +642,4 @@ namespace party
}; };
} }
//REGISTER_COMPONENT(party::component) REGISTER_COMPONENT(party::component)

View File

@ -39,10 +39,14 @@ namespace game
void SV_GameSendServerCommand(int clientNum, svscmd_type type, const char* text) void SV_GameSendServerCommand(int clientNum, svscmd_type type, const char* text)
{ {
if (clientNum == -1) if (clientNum == -1)
{
SV_SendServerCommand(0, type, "%s", text); SV_SendServerCommand(0, type, "%s", text);
}
else else
{
SV_SendServerCommand(&mp::svs_clients[clientNum], type, "%s", text); SV_SendServerCommand(&mp::svs_clients[clientNum], type, "%s", text);
} }
}
namespace environment namespace environment
{ {

View File

@ -105,10 +105,10 @@ namespace game
WEAK symbol<Material* (const char* material)> Material_RegisterHandle{0x0, 0x692360}; WEAK symbol<Material* (const char* material)> Material_RegisterHandle{0x0, 0x692360};
WEAK symbol<void(netadr_s*, sockaddr*)> NetadrToSockadr{0x0, 0x0}; WEAK symbol<void(netadr_s*, sockaddr*)> NetadrToSockadr{0x0, 0x59E580};
WEAK symbol<void(netsrc_t, netadr_s*, const char*)> NET_OutOfBandPrint{0x0, 0x0}; WEAK symbol<void(netsrc_t, netadr_s*, const char*)> NET_OutOfBandPrint{0x0, 0x4F1EB0};
WEAK symbol<void(netsrc_t sock, int length, const void* data, const netadr_s* to)> NET_SendLoopPacket{0x0, 0x0}; WEAK symbol<void(netsrc_t sock, int length, const void* data, const netadr_s* to)> NET_SendLoopPacket{0x0, 0x4F2070};
WEAK symbol<bool(const char* s, netadr_s* a)> NET_StringToAdr{0x0, 0x0}; WEAK symbol<bool(const char* s, netadr_s* a)> NET_StringToAdr{0x0, 0x4F2150};
WEAK symbol<void(float x, float y, float width, float height, float s0, float t0, float s1, float t1, WEAK symbol<void(float x, float y, float width, float height, float s0, float t0, float s1, float t1,
float* color, Material* material)> R_AddCmdDrawStretchPic{0x0, 0x0}; float* color, Material* material)> R_AddCmdDrawStretchPic{0x0, 0x0};
@ -167,13 +167,13 @@ namespace game
WEAK symbol<const char*(scr_string_t stringValue)> SL_ConvertToString{0x0, 0x0}; WEAK symbol<const char*(scr_string_t stringValue)> SL_ConvertToString{0x0, 0x0};
WEAK symbol<unsigned int(const char* str)> SL_GetCanonicalString{0x0, 0x0}; WEAK symbol<unsigned int(const char* str)> SL_GetCanonicalString{0x0, 0x0};
WEAK symbol<void(netadr_s* from)> SV_DirectConnect{0x0, 0x0}; WEAK symbol<void(netadr_s* from)> SV_DirectConnect{0x0, 0x54DBF0};
WEAK symbol<void(int arg, char* buffer, int bufferLength)> SV_Cmd_ArgvBuffer{0x0, 0x0}; WEAK symbol<void(int arg, char* buffer, int bufferLength)> SV_Cmd_ArgvBuffer{0x0, 0x0};
WEAK symbol<void(const char* text_in)> SV_Cmd_TokenizeString{0x0, 0x0}; WEAK symbol<void(const char* text_in)> SV_Cmd_TokenizeString{0x0, 0x1CACE0};
WEAK symbol<void()> SV_Cmd_EndTokenizedString{0x0, 0x0}; WEAK symbol<void()> SV_Cmd_EndTokenizedString{0x0, 0x1CACA0};
WEAK symbol<mp::gentity_s*(const char* name)> SV_AddBot{0x0, 0x0}; WEAK symbol<mp::gentity_s*(const char* name)> SV_AddBot{0x0, 0x0};
WEAK symbol<bool(int clientNum)> SV_BotIsBot{0x0, 0x0}; WEAK symbol<bool(int clientNum)> SV_BotIsBot{0x0, 0x53B6D0};
WEAK symbol<const char* ()> SV_BotGetRandomName{0x0, 0x0}; WEAK symbol<const char* ()> SV_BotGetRandomName{0x0, 0x0};
WEAK symbol<int(mp::gentity_s* ent)> SV_SpawnTestClient{0x0, 0x0}; WEAK symbol<int(mp::gentity_s* ent)> SV_SpawnTestClient{0x0, 0x0};
@ -194,7 +194,7 @@ namespace game
Sys_BuildAbsPath{0x0, 0x0}; Sys_BuildAbsPath{0x0, 0x0};
WEAK symbol<int()> Sys_Milliseconds{0x0, 0x0}; WEAK symbol<int()> Sys_Milliseconds{0x0, 0x0};
WEAK symbol<bool()> Sys_IsDatabaseReady2{0x0, 0x4F79C0}; WEAK symbol<bool()> Sys_IsDatabaseReady2{0x0, 0x4F79C0};
WEAK symbol<bool(int, void const*, const netadr_s*)> Sys_SendPacket{0x0, 0x0}; WEAK symbol<bool(int, void const*, const netadr_s*)> Sys_SendPacket{0x0, 0x5BDA90};
WEAK symbol<bool(const char* path)> Sys_FileExists{0x0, 0x0}; WEAK symbol<bool(const char* path)> Sys_FileExists{0x0, 0x0};
WEAK symbol<const char* (const char*)> UI_GetMapDisplayName{0x0, 0x0}; WEAK symbol<const char* (const char*)> UI_GetMapDisplayName{0x0, 0x0};
@ -211,7 +211,7 @@ namespace game
* Variables * Variables
**************************************************************/ **************************************************************/
WEAK symbol<CmdArgs> sv_cmd_args{0x0, 0x0}; WEAK symbol<CmdArgs> sv_cmd_args{0x0, 0x2ED1EB0};
WEAK symbol<int> g_script_error_level{0x0, 0x0}; WEAK symbol<int> g_script_error_level{0x0, 0x0};
WEAK symbol<jmp_buf> g_script_error{0x0, 0x0}; WEAK symbol<jmp_buf> g_script_error{0x0, 0x0};
@ -241,7 +241,7 @@ namespace game
WEAK symbol<int> keyCatchers{0x0, 0x2EC82C4}; WEAK symbol<int> keyCatchers{0x0, 0x2EC82C4};
WEAK symbol<PlayerKeyState> playerKeys{0x0, 0x0}; WEAK symbol<PlayerKeyState> playerKeys{0x0, 0x0};
WEAK symbol<SOCKET> query_socket{0x0, 0x0}; WEAK symbol<SOCKET> query_socket{0x0, 0xC9DCD38};
WEAK symbol<DWORD> threadIds{0x0, 0x0}; WEAK symbol<DWORD> threadIds{0x0, 0x0};