diff --git a/binaries/IPHLPAPI.dll b/binaries/IPHLPAPI.dll index d3c1c72..862a2ad 100644 Binary files a/binaries/IPHLPAPI.dll and b/binaries/IPHLPAPI.dll differ diff --git a/binaries/plexmediaserver_crack.so b/binaries/plexmediaserver_crack.so index 768f438..826f773 100644 Binary files a/binaries/plexmediaserver_crack.so and b/binaries/plexmediaserver_crack.so differ diff --git a/linux/hook.cpp b/linux/hook.cpp index bcc0b5f..aebe8db 100644 --- a/linux/hook.cpp +++ b/linux/hook.cpp @@ -221,6 +221,7 @@ std::bitset<704>* g_feature_flags; auto _is_feature_available = reinterpret_cast(0); auto _map_find = reinterpret_cast(0); auto _bitset_init = reinterpret_cast(0); +auto _is_user_feature_set = reinterpret_cast(0); std::optional> 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(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(hook_is_user_feature_set)); trampoline) + { + _is_user_feature_set = reinterpret_cast(trampoline.value()); + } + } + // Features are now enabled in boost::atomic 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) { diff --git a/linux/hook.hpp b/linux/hook.hpp index 7196a41..a422c3b 100644 --- a/linux/hook.hpp +++ b/linux/hook.hpp @@ -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(); diff --git a/windows/hook.cpp b/windows/hook.cpp index 0554373..b5e2117 100644 --- a/windows/hook.cpp +++ b/windows/hook.cpp @@ -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(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(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(is_user_feature_set.value()), reinterpret_cast(hook_is_user_feature_set)); + } // Features are now enabled in std::atomic as of 2024/08/13 PMS BETA if(bitset && bitset_init) diff --git a/windows/hook.hpp b/windows/hook.hpp index a9016d8..ead78f2 100644 --- a/windows/hook.hpp +++ b/windows/hook.hpp @@ -42,5 +42,6 @@ std::optional 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();