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. 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
BREAKUP_KICK_DESC BREAKUP_KICK_DESC
@ -53,10 +61,6 @@ Arg Count: 1
SCRIPT_HOST_KICK_DESC SCRIPT_HOST_KICK_DESC
Arg Count: 1 Arg Count: 1
### multikick
MULTI_KICK_DESC
Arg Count: 1
### clearwanted ### clearwanted
CLEAR_WANTED_LEVEL_DESC CLEAR_WANTED_LEVEL_DESC
Arg Count: 1 Arg Count: 1

View File

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

View File

@ -2,7 +2,7 @@
Table containing helper functions for network related features. Table containing helper functions for network related features.
## Functions (11) ## Functions (12)
### `trigger_script_event(bitset, _args)` ### `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) 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)` ### `get_flagged_modder_reason(player_idx)`
- **Parameters:** - **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. 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_SELF`
### `GUI_TAB_WEAPONS` ### `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_MOBILE`
### `GUI_TAB_OUTFIT_EDITOR` ### `GUI_TAB_OUTFIT_EDITOR`
### `GUI_TAB_OUTFIT_SLOTS` ### `GUI_TAB_OUTFIT_SLOTS`
### `GUI_TAB_ANIMATIONS`
### `GUI_TAB_VEHICLE` ### `GUI_TAB_VEHICLE`
### `GUI_TAB_HANDLING` ### `GUI_TAB_HANDLING`
### `GUI_TAB_HANDLING_SEARCH` ### `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_BLACKHOLE`
### `GUI_TAB_MODEL_SWAPPER` ### `GUI_TAB_MODEL_SWAPPER`
### `GUI_TAB_VFX` ### `GUI_TAB_VFX`
### `GUI_TAB_XML_MAPS`
### `GUI_TAB_NETWORK` ### `GUI_TAB_NETWORK`
### `GUI_TAB_MISSIONS` ### `GUI_TAB_MISSIONS`
### `GUI_TAB_SPOOFING` ### `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_REACTION_SETTINGS`
### `GUI_TAB_PROTECTION_SETTINGS` ### `GUI_TAB_PROTECTION_SETTINGS`
### `GUI_TAB_TRANSLATION_SETTINGS` ### `GUI_TAB_TRANSLATION_SETTINGS`
### `GUI_TAB_PROXY_SETTINGS`
### `GUI_TAB_DEBUG` ### `GUI_TAB_DEBUG`
### `GUI_TAB_PLAYER` ### `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); 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); auto len = std::min(max_len, (int)strlen(string) + 1);
bool extended = len > 127; bool extended = len > 127;
Write<bool>(extended, 1); Write<bool>(extended, 1);
Write<int>(len, extended ? 15 : 7); Write<int>(len, extended ? 15 : 7);
WriteArray(string, 8 * len); WriteArray((void*)string, 8 * len);
} }
bool ReadArray(PVOID array, int size) bool ReadArray(PVOID array, int size)

View File

@ -353,10 +353,6 @@ namespace big
bool* m_is_social_club_overlay_active; 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; PVOID m_game_skeleton_update;
functions::get_ped_bone m_get_ped_bone; functions::get_ped_bone m_get_ped_bone;

View File

@ -17,9 +17,7 @@ namespace big
{ {
hooking::hooking() : hooking::hooking() :
m_swapchain_hook(*g_pointers->m_gta.m_swapchain, hooks::swapchain_num_funcs), 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_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_swapchain_hook.hook(hooks::swapchain_present_index, &hooks::swapchain_present); m_swapchain_hook.hook(hooks::swapchain_present_index, &hooks::swapchain_present);
m_swapchain_hook.hook(hooks::swapchain_resizebuffers_index, &hooks::swapchain_resizebuffers); m_swapchain_hook.hook(hooks::swapchain_resizebuffers_index, &hooks::swapchain_resizebuffers);
@ -169,8 +167,6 @@ namespace big
m_swapchain_hook.enable(); m_swapchain_hook.enable();
m_sync_data_reader_hook.enable(); m_sync_data_reader_hook.enable();
m_og_wndproc = WNDPROC(SetWindowLongPtrW(g_pointers->m_hwnd, GWLP_WNDPROC, LONG_PTR(&hooks::wndproc))); 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) 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)); SetWindowLongPtrW(g_pointers->m_hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(m_og_wndproc));
m_sync_data_reader_hook.disable(); m_sync_data_reader_hook.disable();
m_swapchain_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(); MH_ApplyQueued();

View File

@ -127,7 +127,7 @@ namespace big
static void serialize_parachute_task(__int64 info, rage::CSyncDataBase* serializer); 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 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 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); static bool http_start_request(void* request, const char* uri);
@ -273,8 +273,6 @@ namespace big
vmt_hook m_swapchain_hook; vmt_hook m_swapchain_hook;
vtable_hook m_sync_data_reader_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; WNDPROC m_og_wndproc = nullptr;

View File

@ -7,11 +7,12 @@ namespace big
{ {
bool hooks::http_start_request(void* request, const char* uri) 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... // 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! // 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); return g_hooking->get_original<hooks::http_start_request>()(request, uri);
} }

View File

@ -35,7 +35,7 @@ namespace big
return value == 0xE9; 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 f1 = *(__int64*)(cb + 0x60);
auto f2 = *(__int64*)(cb + 0x100); auto f2 = *(__int64*)(cb + 0x100);
@ -46,19 +46,19 @@ namespace big
return is_jump(f1) || is_jump(f2); 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); int hooks::queue_dependency(void* a1, int a2, void* dependency)
{
caller_addr_offset -= module_base; if (is_unwanted_dependency((__int64)dependency))
if (is_unwanted_dependency((__int64)dependency, caller_addr_offset))
{ {
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{}; packet msg{};
msg.write_message(rage::eNetMessage::MsgTextMessage); 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); gamer_handle_serialize(g_player_service->get_self()->get_net_data()->m_gamer_handle, msg.m_buffer);
msg.write<bool>(is_team, 1); msg.write<bool>(is_team, 1);
for (auto& player : g_player_service->players()) if (*g_pointers->m_gta.m_is_session_started)
if (player.second->get_net_game_player()) for (auto& player : g_player_service->players())
msg.send(player.second->get_net_game_player()->m_msg_id); if (player.second && player.second->is_valid())
msg.send(player.second->get_net_game_player()->m_msg_id);
return true; 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; 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 // Lua API: Function
// Table: network // Table: network
// Name: get_flagged_modder_reason // Name: get_flagged_modder_reason
@ -210,10 +223,11 @@ namespace lua::network
ns["set_all_player_coords"] = set_all_player_coords; ns["set_all_player_coords"] = set_all_player_coords;
ns["get_selected_player"] = get_selected_player; ns["get_selected_player"] = get_selected_player;
ns["get_selected_database_player_rockstar_id"] = get_selected_database_player_rockstar_id; 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["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_flagged_as_modder"] = is_player_flagged_as_modder;
ns["get_flagged_modder_reason"] = get_flagged_modder_reason; ns["is_player_friend"] = is_player_friend;
ns["force_script_host"] = force_script_host; ns["get_flagged_modder_reason"] = get_flagged_modder_reason;
ns["send_chat_message"] = send_chat_message; ns["force_script_host"] = force_script_host;
ns["send_chat_message"] = send_chat_message;
} }
} }

View File

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

View File

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

View File

@ -1018,7 +1018,7 @@ namespace big
// Queue Dependency // Queue Dependency
{ {
"QD", "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) [](memory::handle ptr)
{ {
g_pointers->m_gta.m_queue_dependency = ptr.as<PVOID>(); 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>(); 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 // Max Wanted Level
{ {
"MWL", "MWL",
@ -1731,24 +1722,6 @@ namespace big
g_pointers->m_gta.m_is_social_club_overlay_active = ptr.add(2).rip().as<bool*>(); 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 // Game Skeleton Update
{ {
"GSU", "GSU",

View File

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