Rewrite AC bypass (#2430)

* fix(anticheat): rewrite AC bypass again (the old one isn't detected but this is cleaner)
* fix(chat): some chat tweaks
* fix(anticheat): fix memory leak
* feat(lua): add is_player_friend
* fix(protections): fix possible false positives with the vehicle task mismatch protection
* feat(protections): add debug logs to trace false positive
* fix(spam): add some more stuff
This commit is contained in:
maybegreat48 2023-11-19 22:20:15 +00:00 committed by GitHub
parent 6ec0478414
commit a97af16888
17 changed files with 78 additions and 91 deletions

View File

@ -11,7 +11,15 @@ command.call_player(somePlayerIndex, "spawn", {joaat("adder")})
For a complete list of available command functions, please refer to the command table documentation.
## Command Count: 212
## Command Count: 213
### bailkick
BAIL_KICK_DESC
Arg Count: 1
### bailkickall
BAIL_KICK_DESC
Arg Count: 0
### breakup
BREAKUP_KICK_DESC
@ -53,10 +61,6 @@ Arg Count: 1
SCRIPT_HOST_KICK_DESC
Arg Count: 1
### multikick
MULTI_KICK_DESC
Arg Count: 1
### clearwanted
CLEAR_WANTED_LEVEL_DESC
Arg Count: 1

View File

@ -605,8 +605,8 @@ for table_name, table in tables.items():
file_name = f"./tables/{table_name}.md"
if os.path.exists(file_name):
os.remove(file_name)
f = open(file_name, "a")
f.write(str(table))
f = open(file_name, "ba")
f.write(bytes(str(table), "UTF8"))
f.close()
tabs_file_name = f"./tabs.md"
@ -675,8 +675,8 @@ for class_name, class_ in classes.items():
file_name = f"./classes/{class_name}.md"
if os.path.exists(file_name):
os.remove(file_name)
f = open(file_name, "a")
f.write(str(class_))
f = open(file_name, "ba")
f.write(bytes(str(class_), "UTF8"))
f.close()

View File

@ -2,7 +2,7 @@
Table containing helper functions for network related features.
## Functions (11)
## Functions (12)
### `trigger_script_event(bitset, _args)`
@ -106,6 +106,19 @@ network.flag_player_as_modder(player_idx, reason, custom_reason)
boolean = network.is_player_flagged_as_modder(player_idx)
```
### `is_player_friend(player_idx)`
- **Parameters:**
- `player_idx` (integer): Index of the player.
- **Returns:**
- `boolean`: Returns true if the given player is a friend.
**Example Usage:**
```lua
boolean = network.is_player_friend(player_idx)
```
### `get_flagged_modder_reason(player_idx)`
- **Parameters:**

View File

@ -13,7 +13,7 @@ end)
For a complete list of available gui functions, please refer to the tab class documentation and the gui table documentation.
## Tab Count: 44
## Tab Count: 47
### `GUI_TAB_SELF`
### `GUI_TAB_WEAPONS`
@ -22,6 +22,7 @@ For a complete list of available gui functions, please refer to the tab class do
### `GUI_TAB_MOBILE`
### `GUI_TAB_OUTFIT_EDITOR`
### `GUI_TAB_OUTFIT_SLOTS`
### `GUI_TAB_ANIMATIONS`
### `GUI_TAB_VEHICLE`
### `GUI_TAB_HANDLING`
### `GUI_TAB_HANDLING_SEARCH`
@ -39,6 +40,7 @@ For a complete list of available gui functions, please refer to the tab class do
### `GUI_TAB_BLACKHOLE`
### `GUI_TAB_MODEL_SWAPPER`
### `GUI_TAB_VFX`
### `GUI_TAB_XML_MAPS`
### `GUI_TAB_NETWORK`
### `GUI_TAB_MISSIONS`
### `GUI_TAB_SPOOFING`
@ -55,5 +57,6 @@ For a complete list of available gui functions, please refer to the tab class do
### `GUI_TAB_REACTION_SETTINGS`
### `GUI_TAB_PROTECTION_SETTINGS`
### `GUI_TAB_TRANSLATION_SETTINGS`
### `GUI_TAB_PROXY_SETTINGS`
### `GUI_TAB_DEBUG`
### `GUI_TAB_PLAYER`

View File

@ -223,13 +223,13 @@ namespace rage
return big::g_pointers->m_gta.m_write_bitbuf_array(this, array, size, 0);
}
void WriteString(char* string, int max_len)
void WriteString(const char* string, int max_len)
{
auto len = std::min(max_len, (int)strlen(string) + 1);
bool extended = len > 127;
Write<bool>(extended, 1);
Write<int>(len, extended ? 15 : 7);
WriteArray(string, 8 * len);
WriteArray((void*)string, 8 * len);
}
bool ReadArray(PVOID array, int size)

View File

@ -353,10 +353,6 @@ namespace big
bool* m_is_social_club_overlay_active;
functions::remove_player_from_sender_list m_remove_player_from_sender_list;
PVOID m_remove_player_from_sender_list_caller_1;
PVOID m_remove_player_from_sender_list_caller_2;
PVOID m_game_skeleton_update;
functions::get_ped_bone m_get_ped_bone;

View File

@ -17,9 +17,7 @@ namespace big
{
hooking::hooking() :
m_swapchain_hook(*g_pointers->m_gta.m_swapchain, hooks::swapchain_num_funcs),
m_sync_data_reader_hook(g_pointers->m_gta.m_sync_data_reader_vtable, 27),
m_remove_player_from_sender_list_caller_1_hook(g_pointers->m_gta.m_remove_player_from_sender_list_caller_1, hooks::remove_player_from_sender_list),
m_remove_player_from_sender_list_caller_2_hook(g_pointers->m_gta.m_remove_player_from_sender_list_caller_2, hooks::remove_player_from_sender_list)
m_sync_data_reader_hook(g_pointers->m_gta.m_sync_data_reader_vtable, 27)
{
m_swapchain_hook.hook(hooks::swapchain_present_index, &hooks::swapchain_present);
m_swapchain_hook.hook(hooks::swapchain_resizebuffers_index, &hooks::swapchain_resizebuffers);
@ -169,8 +167,6 @@ namespace big
m_swapchain_hook.enable();
m_sync_data_reader_hook.enable();
m_og_wndproc = WNDPROC(SetWindowLongPtrW(g_pointers->m_hwnd, GWLP_WNDPROC, LONG_PTR(&hooks::wndproc)));
m_remove_player_from_sender_list_caller_1_hook.enable();
m_remove_player_from_sender_list_caller_2_hook.enable();
for (auto& detour_hook_helper : m_detour_hook_helpers)
{
@ -194,8 +190,6 @@ namespace big
SetWindowLongPtrW(g_pointers->m_hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(m_og_wndproc));
m_sync_data_reader_hook.disable();
m_swapchain_hook.disable();
m_remove_player_from_sender_list_caller_1_hook.disable();
m_remove_player_from_sender_list_caller_2_hook.disable();
MH_ApplyQueued();

View File

@ -127,7 +127,7 @@ namespace big
static void serialize_parachute_task(__int64 info, rage::CSyncDataBase* serializer);
static int nt_query_virtual_memory(void* _this, HANDLE handle, PVOID base_addr, int info_class, MEMORY_BASIC_INFORMATION* info, int size, size_t* return_len);
static void queue_dependency(void* dependency);
static int queue_dependency(void* a1, int a2, void* dependency);
static bool prepare_metric_for_sending(rage::datBitBuffer* bit_buffer, int unk, int time, rage::rlMetric* metric);
static bool http_start_request(void* request, const char* uri);
@ -273,8 +273,6 @@ namespace big
vmt_hook m_swapchain_hook;
vtable_hook m_sync_data_reader_hook;
call_hook m_remove_player_from_sender_list_caller_1_hook;
call_hook m_remove_player_from_sender_list_caller_2_hook;
WNDPROC m_og_wndproc = nullptr;

View File

@ -7,11 +7,12 @@ namespace big
{
bool hooks::http_start_request(void* request, const char* uri)
{
if(strstr(uri, "Bonus"))
if (strstr(uri, "Bonus"))
{
// This is for worst case scenario where a report does slip through the cracks...
// Lets make it go somewhere it doesn't matter -- don't let the reports reach their servers!
uri = "https://www.google.com";
LOG(WARNING) << "Blocked bonus report!";
uri = "https://0.0.0.0/";
}
return g_hooking->get_original<hooks::http_start_request>()(request, uri);
}

View File

@ -35,7 +35,7 @@ namespace big
return value == 0xE9;
}
bool is_unwanted_dependency(__int64 cb, uint64_t caller_addr_offset)
bool is_unwanted_dependency(__int64 cb)
{
auto f1 = *(__int64*)(cb + 0x60);
auto f2 = *(__int64*)(cb + 0x100);
@ -46,19 +46,19 @@ namespace big
return is_jump(f1) || is_jump(f2);
}
void hooks::queue_dependency(void* dependency)
static bool nullsub()
{
uint64_t caller_addr_offset = (uint64_t)_ReturnAddress();
return true; // returning false would cause the dependency to requeue
}
static auto module_base = (uint64_t)GetModuleHandle(0);
caller_addr_offset -= module_base;
if (is_unwanted_dependency((__int64)dependency, caller_addr_offset))
int hooks::queue_dependency(void* a1, int a2, void* dependency)
{
if (is_unwanted_dependency((__int64)dependency))
{
return;
*(void**)((__int64)dependency + 0x60) = nullsub;
*(void**)((__int64)dependency + 0x100) = nullsub;
}
return g_hooking->get_original<hooks::queue_dependency>()(dependency);
return g_hooking->get_original<hooks::queue_dependency>()(a1, a2, dependency);
}
}

View File

@ -1,11 +0,0 @@
#include "hooking.hpp"
#include "pointers.hpp"
namespace big
{
bool hooks::remove_player_from_sender_list(void* list, uint64_t rockstar_id)
{
g_pointers->m_gta.m_remove_player_from_sender_list(list, &rockstar_id);
return true;
}
}

View File

@ -23,16 +23,15 @@ namespace big
packet msg{};
msg.write_message(rage::eNetMessage::MsgTextMessage);
msg.m_buffer.WriteString(message, 256);
msg.m_buffer.WriteString(message ? message : "", 256);
gamer_handle_serialize(g_player_service->get_self()->get_net_data()->m_gamer_handle, msg.m_buffer);
msg.write<bool>(is_team, 1);
for (auto& player : g_player_service->players())
if (player.second->get_net_game_player())
msg.send(player.second->get_net_game_player()->m_msg_id);
if (*g_pointers->m_gta.m_is_session_started)
for (auto& player : g_player_service->players())
if (player.second && player.second->is_valid())
msg.send(player.second->get_net_game_player()->m_msg_id);
return true;
//return g_hooking->get_original<hooks::send_chat_message>()(team_mgr, local_gamer_info, message, is_team);
}
}

View File

@ -137,6 +137,19 @@ namespace lua::network
return false;
}
// Lua API: Function
// Table: network
// Name: is_player_friend
// Param: player_idx: integer: Index of the player.
// Returns: boolean: Returns true if the given player is a friend.
static bool is_player_friend(int player_idx)
{
if (auto player = big::g_player_service->get_by_id(player_idx))
return player->is_friend();
return false;
}
// Lua API: Function
// Table: network
// Name: get_flagged_modder_reason
@ -210,10 +223,11 @@ namespace lua::network
ns["set_all_player_coords"] = set_all_player_coords;
ns["get_selected_player"] = get_selected_player;
ns["get_selected_database_player_rockstar_id"] = get_selected_database_player_rockstar_id;
ns["flag_player_as_modder"] = sol::overload(flag_player_as_modder, flag_player_as_modder_custom_reason);
ns["is_player_flagged_as_modder"] = is_player_flagged_as_modder;
ns["get_flagged_modder_reason"] = get_flagged_modder_reason;
ns["force_script_host"] = force_script_host;
ns["send_chat_message"] = send_chat_message;
ns["flag_player_as_modder"] = sol::overload(flag_player_as_modder, flag_player_as_modder_custom_reason);
ns["is_player_flagged_as_modder"] = is_player_flagged_as_modder;
ns["is_player_friend"] = is_player_friend;
ns["get_flagged_modder_reason"] = get_flagged_modder_reason;
ns["force_script_host"] = force_script_host;
ns["send_chat_message"] = send_chat_message;
}
}

View File

@ -10,7 +10,7 @@
namespace big
{
packet::packet() :
m_buffer(m_data, 0x4000)
m_buffer(m_data, sizeof(m_data))
{
}

View File

@ -8,7 +8,7 @@ namespace big
class packet
{
public:
char m_data[0x4000]{};
char m_data[0x400]{};
rage::datBitBuffer m_buffer;
packet();

View File

@ -1018,7 +1018,7 @@ namespace big
// Queue Dependency
{
"QD",
"48 89 5C 24 ? 57 48 83 EC ? 0F B6 99",
"48 89 5C 24 08 48 89 74 24 10 57 48 83 EC 20 8B F2 49 8B F8",
[](memory::handle ptr)
{
g_pointers->m_gta.m_queue_dependency = ptr.as<PVOID>();
@ -1501,15 +1501,6 @@ namespace big
g_pointers->m_gta.m_delete_object = ptr.as<functions::delete_object>();
}
},
// Remove Player From Sender List
{
"RPFSL",
"48 89 5C 24 08 48 89 74 24 10 57 48 83 EC 20 33 F6 48 8B FA 48 8B D9 66 39 71 08 76",
[](memory::handle ptr)
{
g_pointers->m_gta.m_remove_player_from_sender_list = ptr.as<functions::remove_player_from_sender_list>();
}
},
// Max Wanted Level
{
"MWL",
@ -1731,24 +1722,6 @@ namespace big
g_pointers->m_gta.m_is_social_club_overlay_active = ptr.add(2).rip().as<bool*>();
}
},
// Remove Player From Sender List Caller 1
{
"RPFSLC1",
"E8 ? ? ? ? 84 C0 74 0D B0 01 EB 1E",
[](memory::handle ptr)
{
g_pointers->m_gta.m_remove_player_from_sender_list_caller_1 = ptr.as<PVOID>();
}
},
// Remove Player From Sender List Caller 2
{
"RPFSLC2",
"E8 ? ? ? ? 84 C0 74 0A B0 01 EB 08",
[](memory::handle ptr)
{
g_pointers->m_gta.m_remove_player_from_sender_list_caller_2 = ptr.as<PVOID>();
}
},
// Game Skeleton Update
{
"GSU",

View File

@ -56,6 +56,9 @@ namespace
"Fast Delivery",
"yosativa",
"rich2day",
"LevelLifters",
". com",
"$1,000,000,000",
};
}