Bypass integrity checks (#2216)
Closes #2215 Closes #2218 Closes #2220 Closes #2212
This commit is contained in:
parent
207e5457f9
commit
05575a6357
62
src/call_hook.cpp
Normal file
62
src/call_hook.cpp
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#include "common.hpp"
|
||||||
|
#include "call_hook.hpp"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
big::call_hook_memory g_call_hook_memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/martonp96/ClosedIV/blob/master/src/utils/memory.h#L64
|
||||||
|
|
||||||
|
namespace big
|
||||||
|
{
|
||||||
|
call_hook_memory::call_hook_memory()
|
||||||
|
{
|
||||||
|
m_memory = VirtualAlloc((void*)((uintptr_t)GetModuleHandle(0) + 0x20000000), 1024, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||||
|
m_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
call_hook_memory::~call_hook_memory()
|
||||||
|
{
|
||||||
|
VirtualFree(m_memory.as<void*>(), 0, MEM_RELEASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* call_hook_memory::allocate_jump_sequence(void* func)
|
||||||
|
{
|
||||||
|
m_offset = m_offset + ((16 - (m_offset % 16)) % 16); // align
|
||||||
|
|
||||||
|
*m_memory.add(m_offset).as<int16_t*>() = 0xB848;
|
||||||
|
*m_memory.add(m_offset).add(2).as<void**>() = func;
|
||||||
|
*m_memory.add(m_offset).add(10).as<int16_t*>() = 0xE0FF;
|
||||||
|
|
||||||
|
m_offset += 12;
|
||||||
|
|
||||||
|
return m_memory.add(m_offset).sub(12).as<void*>();
|
||||||
|
}
|
||||||
|
|
||||||
|
call_hook::call_hook(void* location, void* hook) :
|
||||||
|
m_location(location),
|
||||||
|
m_hook(hook)
|
||||||
|
{
|
||||||
|
auto seq = g_call_hook_memory.allocate_jump_sequence(hook);
|
||||||
|
m_patched_bytes[0] = 0xE8;
|
||||||
|
*(int32_t*)&m_patched_bytes[1] = (int32_t)((uint64_t)seq - (uint64_t)location - 5);
|
||||||
|
memcpy(m_original_bytes, location, 5);
|
||||||
|
m_original_function = memory::handle(location).add(1).rip().as<void*>();
|
||||||
|
}
|
||||||
|
|
||||||
|
call_hook::~call_hook()
|
||||||
|
{
|
||||||
|
disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void call_hook::enable()
|
||||||
|
{
|
||||||
|
memcpy(m_location, m_patched_bytes, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
void call_hook::disable()
|
||||||
|
{
|
||||||
|
memcpy(m_location, m_original_bytes, 5);
|
||||||
|
}
|
||||||
|
}
|
49
src/call_hook.hpp
Normal file
49
src/call_hook.hpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "common.hpp"
|
||||||
|
#include "memory/handle.hpp"
|
||||||
|
|
||||||
|
namespace big
|
||||||
|
{
|
||||||
|
class call_hook_memory
|
||||||
|
{
|
||||||
|
memory::handle m_memory;
|
||||||
|
int m_offset;
|
||||||
|
|
||||||
|
public:
|
||||||
|
call_hook_memory();
|
||||||
|
~call_hook_memory();
|
||||||
|
|
||||||
|
void* allocate_jump_sequence(void* func);
|
||||||
|
};
|
||||||
|
|
||||||
|
class call_hook
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit call_hook(void* location, void* hook);
|
||||||
|
~call_hook();
|
||||||
|
|
||||||
|
call_hook(call_hook&& that) = delete;
|
||||||
|
call_hook& operator=(call_hook&& that) = delete;
|
||||||
|
call_hook(call_hook const&) = delete;
|
||||||
|
call_hook& operator=(call_hook const&) = delete;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T get_original();
|
||||||
|
|
||||||
|
void enable();
|
||||||
|
void disable();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void* m_location;
|
||||||
|
void* m_hook;
|
||||||
|
uint8_t m_patched_bytes[5];
|
||||||
|
uint8_t m_original_bytes[5];
|
||||||
|
void* m_original_function;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline T call_hook::get_original()
|
||||||
|
{
|
||||||
|
return static_cast<T>(m_original_function);
|
||||||
|
}
|
||||||
|
}
|
@ -188,4 +188,6 @@ namespace big::functions
|
|||||||
using delete_object = bool (*)(CObject* object, bool unk);
|
using delete_object = bool (*)(CObject* object, bool unk);
|
||||||
|
|
||||||
using decal_manager_remove = void(*)(PVOID manager, rage::fwEntity*, DWORD a3, DWORD64 a4, DWORD ignore_bitset);
|
using decal_manager_remove = void(*)(PVOID manager, rage::fwEntity*, DWORD a3, DWORD64 a4, DWORD ignore_bitset);
|
||||||
|
|
||||||
|
using remove_player_from_sender_list = bool(*)(void* list, uint64_t* rockstar_id);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <memory/handle.hpp>
|
#include <memory/handle.hpp>
|
||||||
|
#include "function_types.hpp"
|
||||||
|
|
||||||
class CCommunications;
|
class CCommunications;
|
||||||
class FriendRegistry;
|
class FriendRegistry;
|
||||||
@ -28,6 +29,9 @@ namespace rage
|
|||||||
class rlGamerInfo;
|
class rlGamerInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class HashTable;
|
||||||
|
|
||||||
namespace big
|
namespace big
|
||||||
{
|
{
|
||||||
// needed for serialization of the pointers cache
|
// needed for serialization of the pointers cache
|
||||||
@ -339,6 +343,12 @@ namespace big
|
|||||||
PVOID m_decal_manager;
|
PVOID m_decal_manager;
|
||||||
|
|
||||||
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;
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
static_assert(sizeof(gta_pointers) % 8 == 0, "Pointers are not properly aligned");
|
static_assert(sizeof(gta_pointers) % 8 == 0, "Pointers are not properly aligned");
|
||||||
|
@ -17,7 +17,9 @@ 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);
|
||||||
@ -147,6 +149,8 @@ namespace big
|
|||||||
|
|
||||||
detour_hook_helper::add<hooks::read_bits_single>("RBS", g_pointers->m_gta.m_read_bits_single);
|
detour_hook_helper::add<hooks::read_bits_single>("RBS", g_pointers->m_gta.m_read_bits_single);
|
||||||
|
|
||||||
|
detour_hook_helper::add<hooks::game_skeleton_update>("GSU", g_pointers->m_gta.m_game_skeleton_update);
|
||||||
|
|
||||||
g_hooking = this;
|
g_hooking = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,6 +169,8 @@ 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)
|
||||||
{
|
{
|
||||||
@ -188,6 +194,8 @@ 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();
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "gta/script_thread.hpp"
|
#include "gta/script_thread.hpp"
|
||||||
#include "vmt_hook.hpp"
|
#include "vmt_hook.hpp"
|
||||||
#include "vtable_hook.hpp"
|
#include "vtable_hook.hpp"
|
||||||
|
#include "call_hook.hpp"
|
||||||
|
|
||||||
#include <network/netConnection.hpp>
|
#include <network/netConnection.hpp>
|
||||||
|
|
||||||
@ -180,6 +181,9 @@ namespace big
|
|||||||
static bool sync_reader_serialize_vec3(void* _this, rage::fvector3* vec, float divisor, int size);
|
static bool sync_reader_serialize_vec3(void* _this, rage::fvector3* vec, float divisor, int size);
|
||||||
static bool sync_reader_serialize_vec3_signed(void* _this, rage::fvector3* vec, float divisor, int size);
|
static bool sync_reader_serialize_vec3_signed(void* _this, rage::fvector3* vec, float divisor, int size);
|
||||||
static bool sync_reader_serialize_array(void* _this, void* array, int size);
|
static bool sync_reader_serialize_array(void* _this, void* array, int size);
|
||||||
|
|
||||||
|
static bool remove_player_from_sender_list(void* list, uint64_t rockstar_id);
|
||||||
|
static void game_skeleton_update(__int64 update_group);
|
||||||
};
|
};
|
||||||
|
|
||||||
class minhook_keepalive
|
class minhook_keepalive
|
||||||
@ -269,6 +273,8 @@ 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;
|
||||||
|
|
||||||
|
24
src/hooks/misc/game_skeleton_update.cpp
Normal file
24
src/hooks/misc/game_skeleton_update.cpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#include "hooking.hpp"
|
||||||
|
|
||||||
|
namespace big
|
||||||
|
{
|
||||||
|
#pragma pack(push, 8)
|
||||||
|
struct game_skeleton_item
|
||||||
|
{
|
||||||
|
virtual ~game_skeleton_item() = default;
|
||||||
|
virtual void run() = 0; // 0x08
|
||||||
|
|
||||||
|
char m_pad[0x8]; // 0x08
|
||||||
|
uint32_t m_hash; // 0x10
|
||||||
|
game_skeleton_item* m_next; // 0x18
|
||||||
|
};
|
||||||
|
static_assert(sizeof(game_skeleton_item) == 0x20);
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
void hooks::game_skeleton_update(__int64 update_group)
|
||||||
|
{
|
||||||
|
for (auto item = *(game_skeleton_item**)(update_group + 0x20); item; item = item->m_next)
|
||||||
|
if (item->m_hash != 0xA0F39FB6)
|
||||||
|
item->run();
|
||||||
|
}
|
||||||
|
}
|
11
src/hooks/misc/remove_player_from_sender_list.cpp
Normal file
11
src/hooks/misc/remove_player_from_sender_list.cpp
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
@ -1438,6 +1438,15 @@ 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",
|
||||||
@ -1658,6 +1667,33 @@ 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
|
||||||
|
{
|
||||||
|
"GSU",
|
||||||
|
"40 53 48 83 EC 20 48 8B 59 20 EB 0D",
|
||||||
|
[](memory::handle ptr)
|
||||||
|
{
|
||||||
|
g_pointers->m_gta.m_game_skeleton_update = ptr.as<PVOID>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
>(); // don't leave a trailing comma at the end
|
>(); // don't leave a trailing comma at the end
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user