diff --git a/README.md b/README.md index 6641f129..3b3b314e 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@

A multi-purpose adblocker and skip-bypass for the Spotify for Windows (64 bit)

Please support Spotify by purchasing premium

- Last updated: 24 July 2023
- Last tested version:1.2.16.947.gcfbaa410 + Last updated: 6 August 2023
+ Last tested version: 1.2.17.834.g26ee1129

diff --git a/src/BasicUtils/Console.h b/src/BasicUtils/Console.h index 4d0f1da1..522061dc 100644 --- a/src/BasicUtils/Console.h +++ b/src/BasicUtils/Console.h @@ -130,10 +130,15 @@ namespace Console { std::wcout << fmt.substr(start) << std::endl; } catch (const std::exception& e) { - throw std::runtime_error("Failed to format string: " + std::string(e.what())); + std::wcerr << L"Failed to format string: " << e.what() << std::endl; } #endif } + + void PrintError(std::wstring fmt, const auto&... args) { + Print({ Color::Red }, L"[{}] " + fmt, L"ERROR", args...); + } + // void Print(const std::vector& colors, std::wstring fmt, const auto&... args) // { //#if defined(_DEBUG) || defined(_CONSOLE) diff --git a/src/BasicUtils/Hooking.cpp b/src/BasicUtils/Hooking.cpp index b63f7a69..f4d7437e 100644 --- a/src/BasicUtils/Hooking.cpp +++ b/src/BasicUtils/Hooking.cpp @@ -1,61 +1,67 @@ #include "Hooking.h" #include +#include #include -bool Hooking::HookFunction(std::vector ppPointers, std::vector pDetours) { - if (Begin()) - { - for (size_t i = 0; i < ppPointers.size(); i++) { - if (FindHookFunction(ppPointers[i]) != nullptr) { +std::mutex mtx; + +bool Hooking::HookFunction(HookData data) +{ + std::scoped_lock lock(mtx); + if (Begin()) { + for (auto& [ppPointer, pDetour] : data) { + if (FindHookFunction(ppPointer) != nullptr) { throw std::runtime_error("DetourAttach failed"); } - if (DetourAttach(ppPointers[i], pDetours[i]) != NO_ERROR) { + if (DetourAttach(ppPointer, pDetour) != NO_ERROR) { throw std::runtime_error("DetourAttach failed"); } - InsertHookFunction(ppPointers[i], pDetours[i]); + InsertHookFunction(ppPointer, pDetour); } return Commit(); } return false; } -bool Hooking::HookFunction(PVOID* ppPointers, PVOID pDetours) { - auto _ppPointers = { ppPointers }; - auto _pDetours = { pDetours }; - return HookFunction(_ppPointers, _pDetours); +bool Hooking::HookFunction(PVOID* ppPointers, PVOID pDetours) +{ + HookData data = { {ppPointers, pDetours} }; + return HookFunction(data); } -bool Hooking::UnhookFunction(std::vector ppPointers, std::vector pDetours) { - if (Begin()) - { - for (size_t i = 0; i < ppPointers.size(); i++) { - if (pDetours[i] == nullptr) { - pDetours[i] = FindHookFunction(ppPointers[i]); - if (pDetours[i] == nullptr) { +bool Hooking::UnhookFunction(HookData data) +{ + std::scoped_lock lock(mtx); + if (Begin()) { + for (auto& [ppPointer, pDetour] : data) { + if (pDetour == nullptr) { + pDetour = FindHookFunction(ppPointer); + if (pDetour == nullptr) { throw std::runtime_error("DetourDetach failed"); } } - if (DetourDetach(ppPointers[i], pDetours[i]) != NO_ERROR) { + if (DetourDetach(ppPointer, pDetour) != NO_ERROR) { throw std::runtime_error("DetourDetach failed"); } - EraseHookFunction(ppPointers[i]); + EraseHookFunction(ppPointer); } return Commit(); } return false; } -bool Hooking::UnhookFunction(PVOID* ppPointers, PVOID pDetours) { - auto _ppPointers = { ppPointers }; - auto _pDetours = { pDetours }; - return UnhookFunction(_ppPointers, _pDetours); +bool Hooking::UnhookFunction(PVOID* ppPointers, PVOID pDetours) +{ + HookData data = { {ppPointers, pDetours} }; + return UnhookFunction(data); } -bool Hooking::Begin() { +bool Hooking::Begin() +{ if (DetourIsHelperProcess()) { throw std::runtime_error("DetourIsHelperProcess failed"); } @@ -69,7 +75,8 @@ bool Hooking::Begin() { return true; } -bool Hooking::Commit() { +bool Hooking::Commit() +{ if (DetourTransactionCommit() != NO_ERROR) { throw std::runtime_error("DetourTransactionCommit failed"); } @@ -86,7 +93,8 @@ void Hooking::EraseHookFunction(PVOID* ppPointers) HookFunctionList.erase(ppPointers); } -PVOID Hooking::FindHookFunction(PVOID* ppPointers) { +PVOID Hooking::FindHookFunction(PVOID* ppPointers) +{ auto iter = HookFunctionList.find(ppPointers); if (iter != HookFunctionList.end()) { return iter->second; @@ -94,4 +102,4 @@ PVOID Hooking::FindHookFunction(PVOID* ppPointers) { return nullptr; } -std::map Hooking::HookFunctionList; \ No newline at end of file +Hooking::HookData Hooking::HookFunctionList; \ No newline at end of file diff --git a/src/BasicUtils/Hooking.h b/src/BasicUtils/Hooking.h index dc232d18..8dfc1402 100644 --- a/src/BasicUtils/Hooking.h +++ b/src/BasicUtils/Hooking.h @@ -7,9 +7,10 @@ class Hooking { public: - static bool HookFunction(std::vector ppPointers, std::vector pDetours); + using HookData = std::map; + static bool HookFunction(HookData data); static bool HookFunction(PVOID* ppPointers, PVOID pDetours); - static bool UnhookFunction(std::vector ppPointers, std::vector pDetours = {}); + static bool UnhookFunction(HookData data); static bool UnhookFunction(PVOID* ppPointers, PVOID pDetours = nullptr); @@ -19,7 +20,7 @@ class Hooking { static void InsertHookFunction(PVOID* ppPointers, PVOID pDetours); static void EraseHookFunction(PVOID* ppPointers); static PVOID FindHookFunction(PVOID* ppPointers); - static std::map HookFunctionList; + static HookData HookFunctionList; }; #endif //_HOOKING_H diff --git a/src/BasicUtils/Logger.cpp b/src/BasicUtils/Logger.cpp index 17bfd9b1..09a32bef 100644 --- a/src/BasicUtils/Logger.cpp +++ b/src/BasicUtils/Logger.cpp @@ -18,8 +18,7 @@ namespace Logger void Init(std::wstring_view log_file, bool log_enable) { - if (log_enable) - { + if (log_enable) { file.open(log_file.data(), std::ios::out | std::ios::trunc); std::locale utf8_locale("en_US.UTF-8"); @@ -27,15 +26,14 @@ namespace Logger buffer.imbue(utf8_locale); if (!file.is_open()) { - Print({ Color::Red }, L"[{}] Failed to open log file.", L"ERROR"); + PrintError(L"Failed to open log file."); } } } void Flush() { - if (file.is_open()) - { + if (file.is_open()) { file << buffer.str(); buffer.str(L""); file.flush(); @@ -44,8 +42,7 @@ namespace Logger void Close() { - if (file.is_open()) - { + if (file.is_open()) { Flush(); file.close(); } @@ -69,17 +66,15 @@ namespace Logger #ifndef NDEBUG if (level == LogLevel::Error) { - Print({ Color::Red }, L"[{}] {}", level_str, message); + PrintError(message.data()); } #endif - if (file.is_open()) - { + if (file.is_open()) { auto now_time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); std::wostringstream ss; ss << std::put_time(std::localtime(&now_time), L"%Y-%m-%d %H:%M:%S"); - std::wstring time_str = ss.str(); - buffer << time_str << L" | " << level_str << L" | " << message << std::endl; + buffer << ss.str() << L" | " << std::left << std::setw(5) << level_str << L" | " << message << std::endl; Flush(); } } diff --git a/src/BasicUtils/Memory.h b/src/BasicUtils/Memory.h index e788f5dc..dcf6fb71 100644 --- a/src/BasicUtils/Memory.h +++ b/src/BasicUtils/Memory.h @@ -5,8 +5,6 @@ #include #include #include -#include "Console.h" -using namespace Console; namespace Memory { template @@ -23,7 +21,7 @@ namespace Memory { throw std::runtime_error("Failed to set memory protection for reading"); std::memcpy(static_cast(&buffer), address, bufferSize); - + if (!VirtualProtect(address, bufferSize, oldProtect, &oldProtect)) throw std::runtime_error("Failed to restore memory protection after reading"); return true; @@ -80,6 +78,11 @@ namespace Memory { return true; } + + template + std::size_t GetMemberFunctionOffset(U T::* member_ptr) { + return reinterpret_cast(&(((T*)nullptr)->*member_ptr)); + } } #endif //_MEMORY_H diff --git a/src/BasicUtils/PatternScanner.cpp b/src/BasicUtils/PatternScanner.cpp index a199f807..d4268328 100644 --- a/src/BasicUtils/PatternScanner.cpp +++ b/src/BasicUtils/PatternScanner.cpp @@ -15,15 +15,13 @@ PatternScanner::ModuleInfo PatternScanner::GetModuleInfo(std::wstring_view modul { const HMODULE module_handle = GetModuleHandleW(module_name.empty() ? nullptr : module_name.data()); if (!module_handle) { - const auto error_code = GetLastError(); throw std::runtime_error(Utils::ToString(Utils::FormatString(L"Could not get module handle for {}. Error code: {}", - module_name.empty() ? L"main module" : module_name, error_code)).c_str()); + module_name.empty() ? L"main module" : module_name, GetLastError())).c_str()); } MODULEINFO module_info; if (!GetModuleInformation(GetCurrentProcess(), module_handle, &module_info, sizeof(module_info))) { - const auto error_code = GetLastError(); throw std::runtime_error(Utils::ToString(Utils::FormatString(L"Could not get module information for {}. Error code: {}", - module_name.empty() ? L"main module" : module_name, error_code)).c_str()); + module_name.empty() ? L"main module" : module_name, GetLastError())).c_str()); } return { reinterpret_cast(module_info.lpBaseOfDll), static_cast(module_info.SizeOfImage) }; @@ -115,11 +113,12 @@ bool PatternScanner::ScanMatch(const void* value, ScanTargets targets, ValueType std::string_view val(reinterpret_cast(value)); std::string_view first(reinterpret_cast(targets.first.data()), targets.first.size()); std::string_view second(targets.second.empty() ? "" : reinterpret_cast(targets.second.data()), targets.second.size()); - - //std::wstring_view val(reinterpret_cast(value)); - //std::wstring_view first(reinterpret_cast(targets.first.data()), targets.first.size()); - //std::wstring_view second(targets.second.empty() ? L"" : reinterpret_cast(targets.second.data()), targets.second.size()); - + return ScanMatchNumeric(val, first, second, scan_type); + } + case ValueType::WString: { + std::wstring_view val(reinterpret_cast(value)); + std::wstring_view first(reinterpret_cast(targets.first.data()), targets.first.size()); + std::wstring_view second(targets.second.empty() ? L"" : reinterpret_cast(targets.second.data()), targets.second.size()); return ScanMatchNumeric(val, first, second, scan_type); } default: @@ -200,13 +199,13 @@ std::vector PatternScanner::SignatureToByteArray(std::wstring_view std::vector PatternScanner::ScanAll(std::size_t base_address, std::size_t image_size, ScanTargets byte_pattern, ValueType value_type, ScanType scan_type, bool forward) { if (!base_address) - throw std::invalid_argument(Utils::FormatString("Invalid base address ({})", value_type == ValueType::String ? std::string(byte_pattern.first.begin(), byte_pattern.first.end()) : Utils::ToHexString(byte_pattern.first.data(), byte_pattern.first.size()))); + throw std::invalid_argument(Utils::FormatString("Invalid base address ({})", value_type == ValueType::String || value_type == ValueType::WString ? std::string(byte_pattern.first.begin(), byte_pattern.first.end()) : Utils::ToHexString(byte_pattern.first.data(), byte_pattern.first.size()))); if (!image_size) - throw std::invalid_argument(Utils::FormatString("Invalid image size ({})", value_type == ValueType::String ? std::string(byte_pattern.first.begin(), byte_pattern.first.end()) : Utils::ToHexString(byte_pattern.first.data(), byte_pattern.first.size()))); + throw std::invalid_argument(Utils::FormatString("Invalid image size ({})", value_type == ValueType::String || value_type == ValueType::WString ? std::string(byte_pattern.first.begin(), byte_pattern.first.end()) : Utils::ToHexString(byte_pattern.first.data(), byte_pattern.first.size()))); if (byte_pattern.first.empty() || byte_pattern.first.size() > image_size) - throw std::invalid_argument(Utils::FormatString("Invalid pattern size ({})", value_type == ValueType::String ? std::string(byte_pattern.first.begin(), byte_pattern.first.end()) : Utils::ToHexString(byte_pattern.first.data(), byte_pattern.first.size()))); + throw std::invalid_argument(Utils::FormatString("Invalid pattern size ({})", value_type == ValueType::String || value_type == ValueType::WString ? std::string(byte_pattern.first.begin(), byte_pattern.first.end()) : Utils::ToHexString(byte_pattern.first.data(), byte_pattern.first.size()))); const auto pattern_size = byte_pattern.first.size(); const auto end_address = base_address + image_size - pattern_size; @@ -246,7 +245,7 @@ std::vector PatternScanner::ScanAll(std::size_t base_address, std::size_t std::vector PatternScanner::ScanAll(std::size_t base_address, std::size_t image_size, std::wstring_view value, ScanType scan_type, bool forward) { - return ScanAll(base_address, image_size, { SignatureToByteArray(value) }, ValueType::String, scan_type, forward); + return ScanAll(base_address, image_size, { SignatureToByteArray(value) }, ValueType::WString, scan_type, forward); } std::vector PatternScanner::ScanAll(std::wstring_view value, std::wstring_view module_name, ScanType scan_type, bool forward) @@ -258,13 +257,13 @@ std::vector PatternScanner::ScanAll(std::wstring_view value, std::wstring_ Scan PatternScanner::ScanFirst(std::size_t base_address, std::size_t image_size, ScanTargets byte_pattern, ValueType value_type, ScanType scan_type, bool forward) { if (!base_address) - throw std::invalid_argument(Utils::FormatString("Invalid base address ({})", value_type == ValueType::String ? std::string(byte_pattern.first.begin(), byte_pattern.first.end()) : Utils::ToHexString(byte_pattern.first.data(), byte_pattern.first.size()))); + throw std::invalid_argument(Utils::FormatString("Invalid base address ({})", value_type == ValueType::String || value_type == ValueType::WString ? std::string(byte_pattern.first.begin(), byte_pattern.first.end()) : Utils::ToHexString(byte_pattern.first.data(), byte_pattern.first.size()))); if (!image_size) - throw std::invalid_argument(Utils::FormatString("Invalid image size ({})", value_type == ValueType::String ? std::string(byte_pattern.first.begin(), byte_pattern.first.end()) : Utils::ToHexString(byte_pattern.first.data(), byte_pattern.first.size()))); + throw std::invalid_argument(Utils::FormatString("Invalid image size ({})", value_type == ValueType::String || value_type == ValueType::WString ? std::string(byte_pattern.first.begin(), byte_pattern.first.end()) : Utils::ToHexString(byte_pattern.first.data(), byte_pattern.first.size()))); if (byte_pattern.first.empty() || byte_pattern.first.size() > image_size) - throw std::invalid_argument(Utils::FormatString("Invalid pattern size ({})", value_type == ValueType::String ? std::string(byte_pattern.first.begin(), byte_pattern.first.end()) : Utils::ToHexString(byte_pattern.first.data(), byte_pattern.first.size()))); + throw std::invalid_argument(Utils::FormatString("Invalid pattern size ({})", value_type == ValueType::String || value_type == ValueType::WString ? std::string(byte_pattern.first.begin(), byte_pattern.first.end()) : Utils::ToHexString(byte_pattern.first.data(), byte_pattern.first.size()))); const auto pattern_size = byte_pattern.first.size(); const auto end_address = base_address + image_size - pattern_size; @@ -301,7 +300,7 @@ Scan PatternScanner::ScanFirst(std::size_t base_address, std::size_t image_size, Scan PatternScanner::ScanFirst(std::size_t base_address, std::size_t image_size, std::wstring_view value, ScanType scan_type, bool forward) { - return ScanFirst(base_address, image_size, { SignatureToByteArray(value) }, ValueType::String, scan_type, forward); + return ScanFirst(base_address, image_size, { SignatureToByteArray(value) }, ValueType::WString, scan_type, forward); } Scan PatternScanner::ScanFirst(std::wstring_view value, std::wstring_view module_name, ScanType scan_type, bool forward) @@ -419,6 +418,11 @@ bool Scan::unhook() const return is_found() ? Hooking::UnhookFunction(&(PVOID&)m_address) : false; } +Scan Scan::scan_first(std::wstring_view value, ScanType scan_type, bool forward) const +{ + return is_found() ? PatternScanner::ScanFirst(m_address, m_module_info.second, { PatternScanner::SignatureToByteArray(value) }, ValueType::WString, scan_type, forward) : Scan(NULL, m_module_info); +} + std::vector Scan::get_all_matching_codes(AssemblyCode code, std::size_t base_address, std::size_t image_size) const { std::vector pattern = { static_cast(code) }; diff --git a/src/BasicUtils/PatternScanner.h b/src/BasicUtils/PatternScanner.h index e63390a6..f546560a 100644 --- a/src/BasicUtils/PatternScanner.h +++ b/src/BasicUtils/PatternScanner.h @@ -6,6 +6,7 @@ #include #include #include +#include "Memory.h" enum class AssemblyCode { PUSH_VALUE = 0x68, @@ -31,6 +32,7 @@ enum class ValueType { Float, Double, String, + WString, }; class Scan { @@ -50,6 +52,8 @@ class Scan { bool hook(PVOID p_detours) const; bool unhook() const; + Scan scan_first(std::wstring_view value, ScanType scan_type = ScanType::Unknown, bool forward = true) const; + std::vector get_all_matching_codes(AssemblyCode code, std::size_t base_address = 0, std::size_t image_size = 0) const; Scan get_first_matching_code(AssemblyCode code, std::size_t base_address = 0, std::size_t image_size = 0) const; @@ -64,11 +68,8 @@ class Scan { } template - bool write(const T& value) const { - if constexpr (std::is_pointer_v || std::is_same_v || std::is_same_v) - return ::WriteProcessMemory(::GetCurrentProcess(), reinterpret_cast(m_address), value, (std::char_traits::length(reinterpret_cast(value)) + 1) * sizeof(wchar_t), nullptr) != 0; - else - return ::WriteProcessMemory(::GetCurrentProcess(), reinterpret_cast(m_address), std::addressof(value), sizeof(value), nullptr) != 0; + bool write(const T& buffer, std::size_t bufferSize = -1) const { + return is_found() ? Memory::Write(reinterpret_cast(m_address), buffer, bufferSize) : false; } private: diff --git a/src/BasicUtils/Utils.cpp b/src/BasicUtils/Utils.cpp index e5a1b679..e6bfb125 100644 --- a/src/BasicUtils/Utils.cpp +++ b/src/BasicUtils/Utils.cpp @@ -99,6 +99,12 @@ namespace Utils return converter.from_bytes(narrow_string.data(), narrow_string.data() + narrow_string.size()); } + std::wstring ToString(std::u16string_view utf16_string) + { + std::wstring_convert> converter; + return converter.from_bytes(reinterpret_cast(utf16_string.data()), reinterpret_cast(utf16_string.data() + utf16_string.size())); + } + bool Contains(std::string_view str1, std::string_view str2, bool case_sensitive) { auto it = std::search( @@ -204,7 +210,6 @@ namespace Utils existingData = ReadIniFile(fileName); } - // Remove any key-value pairs from existingData that are not present in data for (auto& [sectionName, sectionData] : existingData) { for (auto it = sectionData.begin(); it != sectionData.end();) { const auto& [key, value] = *it; diff --git a/src/BasicUtils/Utils.h b/src/BasicUtils/Utils.h index 2273f011..fe53e2fe 100644 --- a/src/BasicUtils/Utils.h +++ b/src/BasicUtils/Utils.h @@ -18,6 +18,7 @@ namespace Utils std::string ToString(std::wstring_view wide_string); std::wstring ToString(std::string_view narrow_string); + std::wstring ToString(std::u16string_view utf16_string); bool Contains(std::string_view str1, std::string_view str2, bool case_sensitive = false); bool Contains(std::wstring_view str1, std::wstring_view str2, bool case_sensitive = false); diff --git a/src/BlockTheSpot.vcxproj b/src/BlockTheSpot.vcxproj index 5a4f10cf..77f91216 100644 --- a/src/BlockTheSpot.vcxproj +++ b/src/BlockTheSpot.vcxproj @@ -59,6 +59,7 @@ Console true + C:\cef\lib;%(AdditionalLibraryDirectories) @@ -100,9 +101,6 @@ - - - @@ -110,8 +108,8 @@ - + diff --git a/src/BlockTheSpot.vcxproj.filters b/src/BlockTheSpot.vcxproj.filters index c1af70d5..169b190a 100644 --- a/src/BlockTheSpot.vcxproj.filters +++ b/src/BlockTheSpot.vcxproj.filters @@ -78,11 +78,6 @@ Source Files - - - Source Files - - Source Files diff --git a/src/Modify.cpp b/src/Modify.cpp index 4ff54379..84dacc44 100644 --- a/src/Modify.cpp +++ b/src/Modify.cpp @@ -11,20 +11,28 @@ // struct _cef_request_context_t* request_context); using _cef_urlrequest_create = void* (*)(void* request, void* client, void* request_context); -static _cef_urlrequest_create cef_urlrequest_create_orig; +static _cef_urlrequest_create cef_urlrequest_create_orig = nullptr; -using _cef_string_userfree_utf16_free = void * (*)(/*void* str*/void* addr); -static _cef_string_userfree_utf16_free cef_string_userfree_utf16_free_orig; +using _cef_string_userfree_utf16_free = void (*)(void* str); +static _cef_string_userfree_utf16_free cef_string_userfree_utf16_free_orig = nullptr; + +#ifdef NEW_HOOK_SYSTEM +using _cef_zip_reader_create = void* (*)(void* stream); +static _cef_zip_reader_create cef_zip_reader_create_orig = nullptr; + +using _cef_zip_reader_read_file = int(__stdcall*)(void* self, void* buffer, size_t bufferSize); +static _cef_zip_reader_read_file cef_zip_reader_read_file_orig = nullptr; +#endif static constexpr std::array block_list = { L"/ads/", L"/ad-logic/", L"/gabo-receiver-service/" }; -#ifdef _WIN64 +#if defined(_WIN64) && !defined(NEW_HOOK_SYSTEM) static std::wstring file_name; std::uintptr_t file_name_pointer; std::uintptr_t ret_addr_file_name; std::uintptr_t ret_addr_file_source; PatternScanner::ModuleInfo ZipScan; -#else +#elif !defined(NEW_HOOK_SYSTEM) //static bool xpui_found = false; static std::wstring file_name; static std::uintptr_t file_name_pointer; @@ -69,18 +77,18 @@ void* cef_urlrequest_create_hook(void* request, void* client, void* request_cont { #ifndef NDEBUG cef_string_utf16_t* url_utf16 = request->get_url (request); - std::wstring url(url_utf16->str); + std::wstring url(Utils::ToString(url_utf16->str)); + //Print({ Color::Yellow }, L"[{}] {}", L"request_get_url", Memory::GetMemberFunctionOffset(&_cef_request_t::get_url)); #else #ifdef _WIN64 - auto get_url = *(std::uintptr_t(__fastcall**)(void*))((std::uintptr_t)request + 48); - auto url_utf16 = get_url(request); - std::wstring url(*reinterpret_cast(url_utf16)); + auto request_get_url = *(void* (__stdcall**)(void*))((std::uintptr_t)request + 48); #else - auto url_utf16 = get_url(reinterpret_cast(request)); - std::wstring url(reinterpret_cast(get_str(url_utf16))); + auto request_get_url = *(void* (__stdcall**)(void*))((std::uintptr_t)request + 24); #endif - + + auto url_utf16 = request_get_url(request); + std::wstring url(*reinterpret_cast(url_utf16)); #endif for (const auto& blockurl : block_list) { if (std::wstring_view::npos != url.find (blockurl)) { @@ -96,6 +104,191 @@ void* cef_urlrequest_create_hook(void* request, void* client, void* request_cont return cef_urlrequest_create_orig (request, client, request_context); } +#ifdef NEW_HOOK_SYSTEM +#ifndef NDEBUG +int cef_zip_reader_read_file_hook(struct _cef_zip_reader_t* self, void* buffer, size_t bufferSize) +#else +int cef_zip_reader_read_file_hook(void* self, void* buffer, size_t bufferSize) +#endif +{ + int _retval = cef_zip_reader_read_file_orig(self, buffer, bufferSize); + try { +#ifndef NDEBUG + std::wstring file_name = Utils::ToString(self->get_file_name(self)->str); + //Print({ Color::Yellow }, L"[{}] {}", L"zip_reader_read_file", Memory::GetMemberFunctionOffset(&_cef_zip_reader_t::get_file_name)); + //Print(L"{} {} {:X}", file_name, bufferSize, buffer); +#else +#ifdef _WIN64 + auto get_file_name = (*(void* (__stdcall**)(void*))((std::uintptr_t)self + 72)); +#else + auto get_file_name = (*(void* (__stdcall**)(void*))((std::uintptr_t)self + 36)); +#endif + std::wstring file_name(*reinterpret_cast(get_file_name(self))); +#endif + + if (file_name == L"home-hpto.css") { + const auto hpto = PatternScanner::ScanFirst(reinterpret_cast(buffer), bufferSize, L".WiPggcPDzbwGxoxwLWFf{-webkit-box-pack:center;-ms-flex-pack:center;display:-webkit-box;display:-ms-flexbox;display:flex;"); + if (hpto.is_found()) { + if (hpto.write(".WiPggcPDzbwGxoxwLWFf{-webkit-box-pack:center;-ms-flex-pack:center;display:-webkit-box;display:-ms-flexbox;display:none;")) { + Logger::Log(L"hptocss patched!", Logger::LogLevel::Info); + } + else { + Logger::Log(L"hptocss patch failed!", Logger::LogLevel::Error); + } + } + else { + Logger::Log(L"hptocss - failed not found!", Logger::LogLevel::Error); + } + } + + if (file_name == L"xpui-routes-profile.js") { + const auto isModalOpen = PatternScanner::ScanAll(reinterpret_cast(buffer), bufferSize, L"isModalOpen:!0"); + if (isModalOpen[0].is_found()) { + for (const auto& it : isModalOpen) { + if (it.offset(13).write('1')) { + Logger::Log(L"isModalOpen patched!", Logger::LogLevel::Info); + } + else { + Logger::Log(L"isModalOpen - patch failed!", Logger::LogLevel::Error); + } + } + } + else { + Logger::Log(L"isModalOpen - failed not found!", Logger::LogLevel::Error); + } + } + + if (file_name == L"xpui.js") { + const auto skipads = PatternScanner::ScanFirst(reinterpret_cast(buffer), bufferSize, L"adsEnabled:!0"); + if (skipads.is_found()) { + if (skipads.offset(12).write('1')) { + Logger::Log(L"adsEnabled patched!", Logger::LogLevel::Info); + } + else { + Logger::Log(L"adsEnabled - patch failed!", Logger::LogLevel::Error); + } + } + else { + Logger::Log(L"adsEnabled - failed not found!", Logger::LogLevel::Error); + } + + const auto sponsorship = PatternScanner::ScanFirst(reinterpret_cast(buffer), bufferSize, L".set(\"allSponsorships\",t.sponsorships)}}(e,t);"); + if (sponsorship.is_found()) { + if (sponsorship.offset(5).write(std::string(15, ' ').append("\"").c_str())) { + Logger::Log(L"sponsorship patched!", Logger::LogLevel::Info); + } + else { + Logger::Log(L"sponsorship patch failed!", Logger::LogLevel::Error); + } + } + else { + Logger::Log(L"sponsorship - failed not found!", Logger::LogLevel::Error); + } + + const auto skipsentry = PatternScanner::ScanFirst(reinterpret_cast(buffer), bufferSize, L"sentry.io"); + if (skipsentry.is_found()) { + if (skipsentry.write("localhost")) { + Logger::Log(L"sentry.io -> localhost patched!", Logger::LogLevel::Info); + } + else { + Logger::Log(L"sentry.io -> localhost - patch failed!", Logger::LogLevel::Error); + } + } + else { + Logger::Log(L"sentry.io -> localhost - failed not found!", Logger::LogLevel::Error); + } + + const auto ishptoenable = PatternScanner::ScanFirst(reinterpret_cast(buffer), bufferSize, L"hptoEnabled:!0"); + if (ishptoenable.is_found()) + { + if (ishptoenable.offset(13).write('1')) { + Logger::Log(L"hptoEnabled patched!", Logger::LogLevel::Info); + } + else { + Logger::Log(L"hptoEnabled - patch failed!", Logger::LogLevel::Error); + } + } + else { + Logger::Log(L"hptoEnabled - failed not found!", Logger::LogLevel::Error); + } + + const auto ishptohidden = PatternScanner::ScanFirst(reinterpret_cast(buffer), bufferSize, L"isHptoHidden:!0"); + if (ishptohidden.is_found()) { + if (ishptohidden.offset(14).write('1')) { + Logger::Log(L"isHptoHidden patched!", Logger::LogLevel::Info); + } + else { + Logger::Log(L"isHptoHidden - patch failed!", Logger::LogLevel::Error); + } + } + else { + Logger::Log(L"isHptoHidden - failed not found!", Logger::LogLevel::Error); + } + + const auto sp_localhost = PatternScanner::ScanFirst(reinterpret_cast(buffer), bufferSize, L"sp://ads/v1/ads/"); + if (sp_localhost.is_found()) { + if (sp_localhost.write("sp://localhost//")) { + Logger::Log(L"sp://ads/v1/ads/ patched!", Logger::LogLevel::Info); + } + else { + Logger::Log(L"sp://ads/v1/ads/ - patch failed!", Logger::LogLevel::Error); + } + } + else { + Logger::Log(L"sp://ads/v1/ads/ - failed not found!", Logger::LogLevel::Error); + } + + const auto premium_free = PatternScanner::ScanFirst(reinterpret_cast(buffer), bufferSize, L"\"free\"===e.session?.productState?.catalogue?.toLowerCase(),r=e=>null!==e.session?.productState&&1===parseInt(e.session?.productState?.ads,10),o=e=>\"premium\"===e.session?.productState?.catalogue?.toLowerCase(),"); + if (premium_free.is_found()) { + //Print(L"{}", premium_free.read()); + if (premium_free.write("\"premium\"===e.session?.productState?.catalogue?.toLowerCase(),r=e=>null!==e.session?.productState&&1===parseInt(e.session?.productState?.ads,10),o=e=>\"free\"===e.session?.productState?.catalogue?.toLowerCase(),")) { + Logger::Log(L"premium patched!", Logger::LogLevel::Info); + } + else { + Logger::Log(L"premium - patch failed!", Logger::LogLevel::Error); + } + } + else { + Logger::Log(L"premium - failed not found!", Logger::LogLevel::Error); + } + } + } + catch (const std::exception& e) { + PrintError(Utils::ToString(e.what())); + } + + return _retval; +} + +#ifndef NDEBUG +cef_zip_reader_t* cef_zip_reader_create_hook(cef_stream_reader_t* stream) +#else +void* cef_zip_reader_create_hook(void* stream) +#endif +{ +#ifndef NDEBUG + cef_zip_reader_t* zip_reader = (cef_zip_reader_t*)cef_zip_reader_create_orig(stream); + cef_zip_reader_read_file_orig = (_cef_zip_reader_read_file)zip_reader->read_file; + //Print({ Color::Yellow }, L"[{}] {}", L"zip_reader_read_file", Memory::GetMemberFunctionOffset(&cef_zip_reader_t::read_file)); + +#else + auto zip_reader = cef_zip_reader_create_orig(stream); + +#ifdef _WIN64 + cef_zip_reader_read_file_orig = *(_cef_zip_reader_read_file*)((std::uintptr_t)zip_reader + 112); +#else + cef_zip_reader_read_file_orig = *(_cef_zip_reader_read_file*)((std::uintptr_t)zip_reader + 56); +#endif + +#endif + + if (cef_zip_reader_read_file_orig) { + Hooking::HookFunction(&(PVOID&)cef_zip_reader_read_file_orig, (PVOID)cef_zip_reader_read_file_hook); + } + + return zip_reader; +} +#else void WINAPI get_file_name() { try { @@ -104,7 +297,7 @@ void WINAPI get_file_name() //_wsystem(L"pause"); } catch (const std::exception& e) { - Print({ Color::Red }, L"[{}] {}", L"ERROR", e.what()); + PrintError(Utils::ToString(e.what())); } } @@ -250,7 +443,7 @@ void WINAPI modify_source() } } catch (const std::exception& e) { - Print({ Color::Red }, L"[{}] {}", L"ERROR", e.what()); + PrintError(Utils::ToString(e.what())); } } @@ -306,6 +499,7 @@ __declspec(naked) void hook_zip_buffer() } } #endif +#endif DWORD WINAPI EnableDeveloper(LPVOID lpParam) { @@ -331,7 +525,7 @@ DWORD WINAPI EnableDeveloper(LPVOID lpParam) } catch (const std::exception& e) { - Print({ Color::Red }, L"[{}] {}", L"ERROR", e.what()); + PrintError(Utils::ToString(e.what())); } return 0; } @@ -349,28 +543,22 @@ DWORD WINAPI BlockAds(LPVOID lpParam) Logger::Log(L"Block Audio Ads - patch failed!", Logger::LogLevel::Error); } #else - auto hModule = GetModuleHandleW(L"libcef.dll"); - if (!hModule) - hModule = LoadLibraryW(L"libcef.dll"); - - if (hModule) { - cef_urlrequest_create_orig = /*cef_urlrequest_create;*/(_cef_urlrequest_create)GetProcAddress(hModule, "cef_urlrequest_create"); - cef_string_userfree_utf16_free_orig = /*cef_urlrequest_create;*/(_cef_string_userfree_utf16_free)GetProcAddress(hModule, "cef_string_userfree_utf16_free"); + cef_urlrequest_create_orig = (_cef_urlrequest_create)PatternScanner::GetFunctionAddress(L"libcef.dll", L"cef_urlrequest_create").data(); + cef_string_userfree_utf16_free_orig = (_cef_string_userfree_utf16_free)PatternScanner::GetFunctionAddress(L"libcef.dll", L"cef_string_userfree_utf16_free").data(); - if (cef_urlrequest_create_orig && cef_string_userfree_utf16_free_orig) { - if (!Hooking::HookFunction(&(PVOID&)cef_urlrequest_create_orig, (PVOID)cef_urlrequest_create_hook)) { - Logger::Log(L"BlockAds - patch failed!", Logger::LogLevel::Error); - } - else { - Logger::Log(L"BlockAds - patch success!", Logger::LogLevel::Info); - } + if (cef_urlrequest_create_orig && cef_string_userfree_utf16_free_orig) { + if (Hooking::HookFunction(&(PVOID&)cef_urlrequest_create_orig, (PVOID)cef_urlrequest_create_hook)) { + Logger::Log(L"BlockAds - patch success!", Logger::LogLevel::Info); + } + else { + Logger::Log(L"BlockAds - patch failed!", Logger::LogLevel::Error); } } #endif } catch (const std::exception& e) { - Print({ Color::Red }, L"[{}] {}", L"ERROR", e.what()); + PrintError(Utils::ToString(e.what())); } return 0; } @@ -379,6 +567,18 @@ DWORD WINAPI BlockBanner(LPVOID lpParam) { try { +#ifdef NEW_HOOK_SYSTEM + cef_zip_reader_create_orig = (_cef_zip_reader_create)PatternScanner::GetFunctionAddress(L"libcef.dll", L"cef_zip_reader_create").data(); + + if (cef_zip_reader_create_orig) { + if (Hooking::HookFunction(&(PVOID&)cef_zip_reader_create_orig, (PVOID)cef_zip_reader_create_hook)) { + Logger::Log(L"BlockBanner - patch success!", Logger::LogLevel::Info); + } + else { + Logger::Log(L"BlockBanner - patch failed!", Logger::LogLevel::Error); + } + } +#else #ifdef _WIN64 const auto FileName = PatternScanner::ScanFirst(L"48 85 C9 74 23 38 5C 24 48 74 14 E8 ?? ?? ?? ?? BA 18 00 00 00 48 8B 4C 24 40 E8 ?? ?? ?? ?? 48 89 5C 24 40 88 5C 24 48 48 8D 5E 08"); ret_addr_file_name = FileName + 5; @@ -416,11 +616,12 @@ DWORD WINAPI BlockBanner(LPVOID lpParam) else { Logger::Log(L"SourceCode - patch failed!", Logger::LogLevel::Error); } +#endif #endif } catch (const std::exception& e) { - Print({ Color::Red }, L"[{}] {}", L"ERROR", e.what()); + PrintError(Utils::ToString(e.what())); } return 0; } \ No newline at end of file diff --git a/src/Modify.h b/src/Modify.h index 8308f512..a7a192cb 100644 --- a/src/Modify.h +++ b/src/Modify.h @@ -3,7 +3,9 @@ DWORD WINAPI EnableDeveloper(LPVOID lpParam); DWORD WINAPI BlockAds(LPVOID lpParam); DWORD WINAPI BlockBanner(LPVOID lpParam); -#ifdef _WIN64 +#define NEW_HOOK_SYSTEM + +#if defined(_WIN64) && !defined(NEW_HOOK_SYSTEM) extern "C" void WINAPI get_file_name(); extern "C" void WINAPI modify_source(); diff --git a/src/dllmain.cpp b/src/dllmain.cpp index a5b0d038..01813ef6 100644 --- a/src/dllmain.cpp +++ b/src/dllmain.cpp @@ -63,7 +63,7 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReser } } catch (const std::exception& e) { - Print({ Color::Red }, L"[{}] {}", L"ERROR", Utils::ToString(e.what())); + PrintError(Utils::ToString(e.what())); } } break; diff --git a/src/framework.h b/src/framework.h index 2d62817b..1536f021 100644 --- a/src/framework.h +++ b/src/framework.h @@ -8,14 +8,12 @@ #include #ifndef NDEBUG -#include +#ifdef _WIN64 +#pragma comment(lib, "libcef_x64.lib") +#else +#pragma comment(lib, "libcef_x86.lib") #endif -#include "BasicUtils/Utils.h" -#include "BasicUtils/Logger.h" -#include "BasicUtils/PatternScanner.h" -#include "BasicUtils/Memory.h" -#include "BasicUtils/Hooking.h" -#include "BasicUtils/Console.h" - -using namespace Console; \ No newline at end of file +#include +#include +#endif \ No newline at end of file diff --git a/src/pch.h b/src/pch.h index c6503f01..41481543 100644 --- a/src/pch.h +++ b/src/pch.h @@ -9,6 +9,16 @@ // add headers that you want to pre-compile here #include "framework.h" + +#include "BasicUtils/Utils.h" +#include "BasicUtils/Logger.h" +#include "BasicUtils/PatternScanner.h" +#include "BasicUtils/Memory.h" +#include "BasicUtils/Hooking.h" +#include "BasicUtils/Console.h" + +using namespace Console; + #include "Debug.h" #include "Modify.h"