Add protections for remote crash and kick (#776)
* fix(protections): Return true instead of false * fix(protections): fix remote crash protection * feat(protections): add protection for remote kick as host * fix(protections): Try to decrease code complexity
This commit is contained in:
parent
a063d817f5
commit
a83b9523cc
@ -57,24 +57,48 @@ namespace big
|
|||||||
|
|
||||||
bool hooks::receive_net_message(void* netConnectionManager, void* a2, rage::netConnection::InFrame* frame)
|
bool hooks::receive_net_message(void* netConnectionManager, void* a2, rage::netConnection::InFrame* frame)
|
||||||
{
|
{
|
||||||
if (frame->get_event_type() == rage::netConnection::InFrame::EventType::FrameReceived)
|
if (frame->get_event_type() != rage::netConnection::InFrame::EventType::FrameReceived)
|
||||||
|
return g_hooking->get_original<hooks::receive_net_message>()(netConnectionManager, a2, frame);
|
||||||
|
|
||||||
|
rage::datBitBuffer buffer((uint8_t*)frame->m_data, frame->m_length);
|
||||||
|
buffer.m_flagBits = 1;
|
||||||
|
|
||||||
|
rage::eNetMessage msgType;
|
||||||
|
player_ptr player;
|
||||||
|
|
||||||
|
for (std::uint32_t i = 0; i < gta_util::get_network()->m_game_session_ptr->m_player_count; i++)
|
||||||
{
|
{
|
||||||
rage::datBitBuffer buffer((uint8_t*)frame->m_data, frame->m_length);
|
if (gta_util::get_network()->m_game_session_ptr->m_players[i]->m_player_data.m_peer_id_2 == frame->m_peer_id)
|
||||||
buffer.m_flagBits = 1;
|
|
||||||
rage::eNetMessage msgType;
|
|
||||||
player_ptr player;
|
|
||||||
for (std::uint32_t i = 0; i < gta_util::get_network()->m_game_session_ptr->m_player_count; i++)
|
|
||||||
{
|
{
|
||||||
if (gta_util::get_network()->m_game_session_ptr->m_players[i]->m_player_data.m_peer_id_2 == frame->m_peer_id)
|
player = g_player_service->get_by_host_token(gta_util::get_network()->m_game_session_ptr->m_players[i]->m_player_data.m_host_token);
|
||||||
{
|
break;
|
||||||
player = g_player_service->get_by_host_token(gta_util::get_network()->m_game_session_ptr->m_players[i]->m_player_data.m_host_token);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (player && get_msg_type(msgType, buffer))
|
}
|
||||||
|
|
||||||
|
if (!get_msg_type(msgType, buffer))
|
||||||
|
return g_hooking->get_original<hooks::receive_net_message>()(netConnectionManager, a2, frame);
|
||||||
|
|
||||||
|
if (msgType == rage::eNetMessage::MsgTransitionLaunchNotify)
|
||||||
|
{
|
||||||
|
if (frame->m_connection_identifier != gta_util::get_network()->m_transition_session.m_connection_identifier)
|
||||||
{
|
{
|
||||||
switch (msgType)
|
if (player)
|
||||||
{
|
{
|
||||||
|
g_notification_service->push_error("Protections", std::format("Blocked invalid transition launch notify crash from {}", player->get_name()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_notification_service->push_error("Protections", "Blocked invalid transition launch notify remote crash");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player)
|
||||||
|
{
|
||||||
|
switch (msgType)
|
||||||
|
{
|
||||||
case rage::eNetMessage::MsgTextMessage:
|
case rage::eNetMessage::MsgTextMessage:
|
||||||
case rage::eNetMessage::MsgTextMessage2:
|
case rage::eNetMessage::MsgTextMessage2:
|
||||||
{
|
{
|
||||||
@ -173,7 +197,7 @@ namespace big
|
|||||||
|
|
||||||
for (auto& [_, plyr] : g_player_service->players())
|
for (auto& [_, plyr] : g_player_service->players())
|
||||||
{
|
{
|
||||||
if (plyr->get_net_data() && plyr != player && player->get_net_data()->m_gamer_handle_2.m_rockstar_id == handle.m_rockstar_id)
|
if (plyr->get_net_data() && plyr != player && plyr->get_net_data()->m_gamer_handle_2.m_rockstar_id == handle.m_rockstar_id)
|
||||||
{
|
{
|
||||||
session::add_infraction(player, Infraction::LOST_CONNECTION_KICK_DETECTED);
|
session::add_infraction(player, Infraction::LOST_CONNECTION_KICK_DETECTED);
|
||||||
g_notification_service->push_error("Protections", std::format("{} tried to lost connection kick {}!", player->get_name(), plyr->get_name()));
|
g_notification_service->push_error("Protections", std::format("{} tried to lost connection kick {}!", player->get_name(), plyr->get_name()));
|
||||||
@ -235,7 +259,7 @@ namespace big
|
|||||||
|
|
||||||
if (script.m_hash == RAGE_JOAAT("freemode") && g.session.force_script_host)
|
if (script.m_hash == RAGE_JOAAT("freemode") && g.session.force_script_host)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case rage::eNetMessage::MsgNetTimeSync:
|
case rage::eNetMessage::MsgNetTimeSync:
|
||||||
@ -258,9 +282,82 @@ namespace big
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (msgType)
|
||||||
|
{
|
||||||
|
case rage::eNetMessage::MsgLostConnectionToHost:
|
||||||
|
{
|
||||||
|
uint64_t session_id;
|
||||||
|
buffer.ReadQWord(&session_id, 64);
|
||||||
|
rage::rlGamerHandle handle;
|
||||||
|
gamer_handle_deserialize(handle, buffer);
|
||||||
|
|
||||||
|
auto self = g_player_service->get_self();
|
||||||
|
if (self->get_net_data() && self->get_net_data()->m_gamer_handle_2.m_rockstar_id == handle.m_rockstar_id)
|
||||||
|
{
|
||||||
|
g_notification_service->push_error("Warning!", "Someone tried to lost connection kick you remotely!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& [_, plyr] : g_player_service->players())
|
||||||
|
{
|
||||||
|
if (plyr->get_net_data() && plyr->get_net_data()->m_gamer_handle_2.m_rockstar_id == handle.m_rockstar_id)
|
||||||
|
{
|
||||||
|
g_notification_service->push_error("Warning!", std::format("Someone tried to lost connection kick {} remotely!", plyr->get_name()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case rage::eNetMessage::MsgRemoveGamersFromSessionCmd:
|
||||||
|
{
|
||||||
|
if (!g_player_service->get_self()->is_host())
|
||||||
|
break;
|
||||||
|
|
||||||
|
player_ptr target;
|
||||||
|
uint64_t session_id;
|
||||||
|
buffer.ReadQWord(&session_id, 64);
|
||||||
|
uint32_t count;
|
||||||
|
buffer.ReadDword(&count, 6);
|
||||||
|
for (std::uint32_t i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
uint64_t peer_id;
|
||||||
|
buffer.ReadQWord(&peer_id, 64);
|
||||||
|
|
||||||
|
if (g_player_service->get_self()->get_net_data() && g_player_service->get_self()->get_net_data()->m_peer_id_2 == peer_id)
|
||||||
|
{
|
||||||
|
target = g_player_service->get_self();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (std::uint32_t i = 0; i < gta_util::get_network()->m_game_session_ptr->m_peer_count; i++)
|
||||||
|
{
|
||||||
|
if (gta_util::get_network()->m_game_session_ptr->m_peers[i]->m_peer_data.m_peer_id_2 == peer_id)
|
||||||
|
{
|
||||||
|
target = g_player_service->get_by_host_token(gta_util::get_network()->m_game_session_ptr->m_peers[i]->m_peer_data.m_host_token);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target && count == 1 && frame->m_msg_id == -1)
|
||||||
|
{
|
||||||
|
if (target->id() == g_player_service->get_self()->id())
|
||||||
|
g_notification_service->push_error("Warning!", "Someone tried to breakup kick you remotely!");
|
||||||
|
else
|
||||||
|
g_notification_service->push_error("Warning!", std::format("Someone tried to breakup kick {} remotely!", target->get_name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return g_hooking->get_original<hooks::receive_net_message>()(netConnectionManager, a2, frame);
|
return g_hooking->get_original<hooks::receive_net_message>()(netConnectionManager, a2, frame);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user