Added FeatureManager::UserFeatureSet spoofing.

- Fixes intro/credit markers not being sent to clients in recent updates.
This commit is contained in:
yuv420p10le 2024-08-31 16:45:30 +03:00
parent 36046155d1
commit 1209483a5b
6 changed files with 33 additions and 1 deletions

Binary file not shown.

Binary file not shown.

View File

@ -221,6 +221,7 @@ std::bitset<704>* g_feature_flags;
auto _is_feature_available = reinterpret_cast<decltype(&hook_is_feature_available)>(0);
auto _map_find = reinterpret_cast<decltype(&hook_map_find)>(0);
auto _bitset_init = reinterpret_cast<decltype(&hook_bitset_init)>(0);
auto _is_user_feature_set = reinterpret_cast<decltype(&hook_is_user_feature_set)>(0);
std::optional<std::tuple<uintptr_t, uintptr_t>> get_dottext_info()
{
@ -388,6 +389,11 @@ uint64_t hook_bitset_init(uintptr_t rcx)
return ret;
}
bool hook_is_user_feature_set([[maybe_unused]] uintptr_t rcx, [[maybe_unused]] int expected, [[maybe_unused]] int feature)
{
return static_cast<bool>(expected);
}
void hook()
{
auto info = get_dottext_info();
@ -400,6 +406,14 @@ void hook()
const auto start = std::get<0>(info.value());
const auto end = std::get<1>(info.value());
if(const auto is_user_feature_set = sig_scan(start, end, "55 48 89 E5 48 8B 07 48 85 C0 74 6A"); is_user_feature_set)
{
if(auto trampoline = create_hook(is_user_feature_set.value(), reinterpret_cast<uintptr_t>(hook_is_user_feature_set)); trampoline)
{
_is_user_feature_set = reinterpret_cast<decltype(_is_user_feature_set)>(trampoline.value());
}
}
// Features are now enabled in boost::atomic<std::bitset> as of 2024/08/13 PMS BETA
if(const auto bitset = sig_scan(start, end, "48 8D 0D ? ? ? ? 48 8B 94 05 90 FE FF FF"); bitset)
{

View File

@ -12,4 +12,5 @@ uintptr_t follow_call_rel32(const uintptr_t address);
uint64_t hook_is_feature_available(uintptr_t rcx, const char** guid);
uint64_t* hook_map_find(uintptr_t* rcx, const char** str);
uint64_t hook_bitset_init(uintptr_t rcx);
bool hook_is_user_feature_set(uintptr_t rcx, int expected, int feature);
void hook();

View File

@ -250,6 +250,7 @@ std::bitset<416>* g_feature_flags;
SafetyHookInline _is_feature_available{};
SafetyHookInline _map_find{};
SafetyHookInline _is_user_feature_set{};
SafetyHookInline _feature_manager_init{};
SafetyHookInline _bitset_init{};
auto _feature_manager = reinterpret_cast<FeatureManager*>(0);
@ -413,6 +414,15 @@ void hook_bitset_init(uintptr_t rcx, uintptr_t rdx)
#endif
}
uint64_t hook_is_user_feature_set([[maybe_unused]] int expected, [[maybe_unused]] int feature)
{
#if _DEBUG
std::println("[INFO] [plexmediaserver_crack] Spoofed feature {} to {}.", feature, expected);
#endif
return expected;
}
FeatureManager* hook_feature_manager_init(FeatureManager* rcx)
{
return _feature_manager = _feature_manager_init.call<FeatureManager*>(rcx);
@ -439,7 +449,13 @@ void hook()
const auto start = std::get<0>(info.value());
const auto end = std::get<1>(info.value());
const auto bitset = sig_scan(start, end, "8B 84 24 ? ? 00 00 87 05 ? ? ? ? 8B");
const auto bitset_init = sig_scan(start, end, "48 89 5C 24 18 48 89 74 24 20 57 41 54 41 55 41 56 41 57 48 81 EC 90 02 00 00 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 88");
const auto bitset_init = sig_scan(start, end, "48 89 5C 24 18 48 89 74 24 20 57 41 54 41 55 41 56 41 57 48 81 EC 90 02 00 00 48 8B 05 ? ? ? ? 48 33 C4 48 89 84 24 88");
const auto is_user_feature_set = sig_scan(start, end, "48 89 5C 24 08 48 89 6C 24 10 48 89 74 24 18 48 89 7C 24 20 41 56 48 83 EC 30 48 63");
if(is_user_feature_set)
{
_is_user_feature_set = safetyhook::create_inline(reinterpret_cast<void*>(is_user_feature_set.value()), reinterpret_cast<void*>(hook_is_user_feature_set));
}
// Features are now enabled in std::atomic<std::bitset> as of 2024/08/13 PMS BETA
if(bitset && bitset_init)

View File

@ -42,5 +42,6 @@ std::optional<uintptr_t> sig_scan(const uintptr_t start, const uintptr_t end, st
uint64_t hook_is_feature_available(uintptr_t rcx, str_holder* guid);
uint64_t* hook_map_find(uintptr_t* rcx, uintptr_t rdx, str_holder* str);
void hook_bitset_init(uintptr_t rcx, uintptr_t rdx);
uint64_t hook_is_user_feature_set(int expected, int feature);
FeatureManager* hook_feature_manager_init(FeatureManager* rcx);
void hook();