From be25b03a74db9e19b33b31daae0fa81a0bf46c0d Mon Sep 17 00:00:00 2001 From: Arsenii es3n1n Date: Wed, 10 Aug 2022 17:11:45 +0200 Subject: [PATCH] v1.0.9 - crash fixes - reformat everything with clang-format --- .clang-format | 31 +++ .../injector/injector.cpp | 91 +++++---- spotify-reverse-launcher/injector/injector.h | 15 +- spotify-reverse-launcher/main.cpp | 49 +++-- .../spotify-reverse-launcher.vcxproj | 43 +---- spotify-reverse-shared/shared/logger.h | 137 ++++++------- spotify-reverse-shared/shared/logo.h | 40 ++-- spotify-reverse.sln | 19 +- spotify-reverse/bootstrap/bootstrap.cpp | 73 ++++--- spotify-reverse/bootstrap/bootstrap.h | 18 +- spotify-reverse/defines.h | 6 +- spotify-reverse/dllmain.cpp | 8 +- spotify-reverse/exceptions/exceptions.cpp | 55 +++--- spotify-reverse/exceptions/exceptions.h | 9 +- spotify-reverse/hooks/hooked/create_track.cpp | 30 ++- spotify-reverse/hooks/hooked/debug_msg.cpp | 26 +-- spotify-reverse/hooks/hooked/get_ad.cpp | 13 +- spotify-reverse/hooks/hooks.cpp | 33 ++-- spotify-reverse/hooks/hooks.h | 40 ++-- spotify-reverse/spotify-reverse.vcxproj | 94 +-------- .../spotify-reverse.vcxproj.filters | 6 +- spotify-reverse/spotify-reverse.vcxproj.user | 10 - spotify-reverse/spotify/spotify.cpp | 127 ++++++------ spotify-reverse/spotify/spotify.h | 52 ++--- spotify-reverse/updates/updates.cpp | 71 ++++--- spotify-reverse/updates/updates.h | 23 ++- .../util/hooking/detours/detours.cpp | 18 +- .../util/hooking/detours/detours.h | 11 +- spotify-reverse/util/hooking/hooking.h | 2 +- spotify-reverse/util/hooking/vmt/vmt.cpp | 86 ++++----- spotify-reverse/util/hooking/vmt/vmt.h | 69 ++++--- spotify-reverse/util/mem/addr.h | 181 +++++++++--------- spotify-reverse/util/mem/module.h | 142 +++++++------- .../util/networking/networking.cpp | 63 +++--- spotify-reverse/util/networking/networking.h | 17 +- spotify-reverse/util/util.h | 6 +- 36 files changed, 789 insertions(+), 925 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..394acf0 --- /dev/null +++ b/.clang-format @@ -0,0 +1,31 @@ +# es3n1n's clang-format, last upd 19 jun 22 17:50:03 + +BasedOnStyle: WebKit + +Language: Cpp + +AlignTrailingComments: false +AllowAllArgumentsOnNextLine: false +AllowShortEnumsOnASingleLine: false +AllowShortLambdasOnASingleLine: Inline +BreakBeforeBraces: Custom +BraceWrapping: + AfterEnum: false + AfterStruct: false + SplitEmptyFunction: false + AfterFunction: false + AfterNamespace: false +BreakBeforeTernaryOperators: false +BreakConstructorInitializers: BeforeColon +ColumnLimit: 155 +FixNamespaceComments: true +IndentPPDirectives: BeforeHash +ReflowComments: false +NamespaceIndentation: All +BreakStringLiterals: true +CommentPragmas: true +IndentCaseLabels: false +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes + diff --git a/spotify-reverse-launcher/injector/injector.cpp b/spotify-reverse-launcher/injector/injector.cpp index 6b9dc11..b6bda54 100644 --- a/spotify-reverse-launcher/injector/injector.cpp +++ b/spotify-reverse-launcher/injector/injector.cpp @@ -2,65 +2,64 @@ #include #include - -#define INJECTOR_FAIL(s) { util::logger::error(s " Error code: %d\n", GetLastError( ) ); return false; } - +#define INJECTOR_FAIL(s) \ + { \ + util::logger::error(s " Error code: %d\n", GetLastError()); \ + return false; \ + } namespace injector { - namespace detail { - void* get_process_by_name( const wchar_t* name ) { - void* thSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); - if ( thSnapShot == INVALID_HANDLE_VALUE ) - return nullptr; + namespace detail { + void* get_process_by_name(const wchar_t* name) { + void* thSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (thSnapShot == INVALID_HANDLE_VALUE) + return nullptr; - PROCESSENTRY32W pe; - pe.dwSize = sizeof( PROCESSENTRY32W ); + PROCESSENTRY32W pe; + pe.dwSize = sizeof(PROCESSENTRY32W); - unsigned long ret = 0; - for ( bool proc = Process32FirstW( thSnapShot, &pe ); proc; proc = Process32NextW( thSnapShot, &pe ) ) { - if ( wcscmp( pe.szExeFile, name ) ) - continue; - ret = pe.th32ProcessID; - break; - } + unsigned long ret = 0; + for (bool proc = Process32FirstW(thSnapShot, &pe); proc; proc = Process32NextW(thSnapShot, &pe)) { + if (wcscmp(pe.szExeFile, name)) + continue; + ret = pe.th32ProcessID; + break; + } - CloseHandle( thSnapShot ); + CloseHandle(thSnapShot); - return ret ? OpenProcess( PROCESS_ALL_ACCESS, false, ret ) : nullptr; - } - } + return ret ? OpenProcess(PROCESS_ALL_ACCESS, false, ret) : nullptr; + } + } // namespace detail - bool inject( const wchar_t* proc, const char* path ) { - return ::injector::inject( detail::get_process_by_name( proc ), path ); - } + bool inject(const wchar_t* proc, const char* path) { return ::injector::inject(detail::get_process_by_name(proc), path); } - bool inject( HANDLE proc, const char* path ) { - if ( !proc ) - INJECTOR_FAIL( "Failed to open a process. Make sure injector is running as an admin." ); + bool inject(HANDLE proc, const char* path) { + if (!proc) + INJECTOR_FAIL("Failed to open a process. Make sure injector is running as an admin."); - char full_path[ 260 ]; - if ( !GetFullPathNameA( path, sizeof( full_path ), full_path, nullptr ) ) - INJECTOR_FAIL( "Failed to find a dll." ); + char full_path[260]; + if (!GetFullPathNameA(path, sizeof(full_path), full_path, nullptr)) + INJECTOR_FAIL("Failed to find a dll."); - HMODULE kernel32 = GetModuleHandleW( L"kernel32.dll" ); - if ( !kernel32 ) - INJECTOR_FAIL( "Failed to get kernel32.dll handle." ); + HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll"); + if (!kernel32) + INJECTOR_FAIL("Failed to get kernel32.dll handle."); - void* lla = reinterpret_cast< void* >( GetProcAddress( kernel32, "LoadLibraryA" ) ); - if ( !lla ) - INJECTOR_FAIL( "Failed to find LoadLibraryA function." ); + void* lla = reinterpret_cast(GetProcAddress(kernel32, "LoadLibraryA")); + if (!lla) + INJECTOR_FAIL("Failed to find LoadLibraryA function."); - void* str = VirtualAllocEx( proc, nullptr, strlen( full_path ), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE ); - if ( !str ) - INJECTOR_FAIL( "Failed to allocate memory region for str." ); + void* str = VirtualAllocEx(proc, nullptr, strlen(full_path), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); + if (!str) + INJECTOR_FAIL("Failed to allocate memory region for str."); - WriteProcessMemory( proc, str, full_path, strlen( full_path ), nullptr ); - CreateRemoteThread( proc, nullptr, 0, reinterpret_cast< LPTHREAD_START_ROUTINE >( lla ), str, 0, nullptr ); - - CloseHandle( proc ); - return true; - } -} + WriteProcessMemory(proc, str, full_path, strlen(full_path), nullptr); + CreateRemoteThread(proc, nullptr, 0, reinterpret_cast(lla), str, 0, nullptr); + CloseHandle(proc); + return true; + } +} // namespace injector #undef INJECTOR_FAIL diff --git a/spotify-reverse-launcher/injector/injector.h b/spotify-reverse-launcher/injector/injector.h index f307650..4ea1f85 100644 --- a/spotify-reverse-launcher/injector/injector.h +++ b/spotify-reverse-launcher/injector/injector.h @@ -1,13 +1,12 @@ #pragma once -#include #include "shared/logo.h" - +#include namespace injector { - namespace detail { - void* get_process_by_name( const wchar_t* name ); - } + namespace detail { + void* get_process_by_name(const wchar_t* name); + } - bool inject( const wchar_t* proc, const char* path ); - bool inject( HANDLE proc, const char* path ); -} + bool inject(const wchar_t* proc, const char* path); + bool inject(HANDLE proc, const char* path); +} // namespace injector diff --git a/spotify-reverse-launcher/main.cpp b/spotify-reverse-launcher/main.cpp index 83627ca..19eb354 100644 --- a/spotify-reverse-launcher/main.cpp +++ b/spotify-reverse-launcher/main.cpp @@ -4,36 +4,35 @@ #include "injector/injector.h" +int main() { + util::logo::create_console_and_draw_logo(); -int main( ) { - util::logo::create_console_and_draw_logo( ); + STARTUPINFOA si = { .cb = sizeof(si) }; + PROCESS_INFORMATION pi = {}; - STARTUPINFOA si = { .cb = sizeof( si ) }; - PROCESS_INFORMATION pi = {}; + constexpr const char* exe_path = "oSpotify.exe"; - constexpr const char* exe_path = "oSpotify.exe"; + // Creating process + // + util::logger::debug("Spawning %s", exe_path); + if (!CreateProcessA(exe_path, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) { + util::logger::error("Unable to create process, error code: %d", GetLastError()); + system("pause"); + goto END; + } - // Creating process - // - util::logger::debug( "Spawning %s", exe_path ); - if ( !CreateProcessA( exe_path, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi ) ) { - util::logger::error( "Unable to create process, error code: %d", GetLastError( ) ); - system( "pause" ); - goto END; - } + // Injecting Unspotify + // + util::logger::debug("Injecting spotify-reverse.dll"); + if (!injector::inject(pi.hProcess, "spotify-reverse.dll")) { + util::logger::error("Unable to inject module, error code: %d", GetLastError()); + TerminateProcess(pi.hProcess, 0x0); + system("pause"); + goto END; + } - // Injecting Unspotify - // - util::logger::debug( "Injecting spotify-reverse.dll" ); - if ( !injector::inject( pi.hProcess, "spotify-reverse.dll" ) ) { - util::logger::error( "Unable to inject module, error code: %d", GetLastError( ) ); - TerminateProcess( pi.hProcess, 0x0 ); - system( "pause" ); - goto END; - } - - ResumeThread(pi.hThread); + ResumeThread(pi.hThread); END: - return EXIT_SUCCESS; + return EXIT_SUCCESS; } diff --git a/spotify-reverse-launcher/spotify-reverse-launcher.vcxproj b/spotify-reverse-launcher/spotify-reverse-launcher.vcxproj index f646a91..4be1b36 100644 --- a/spotify-reverse-launcher/spotify-reverse-launcher.vcxproj +++ b/spotify-reverse-launcher/spotify-reverse-launcher.vcxproj @@ -9,14 +9,6 @@ Release Win32 - - Debug - x64 - - - Release - x64 - 16.0 @@ -39,22 +31,7 @@ ClangCL true Unicode - 12.0.0 - - - Application - true - v143 - Unicode - 12.0.0 - - - Application - false - ClangCL - true - Unicode - 12.0.0 + 13.0.1 @@ -68,12 +45,6 @@ - - - - - - true @@ -87,18 +58,6 @@ $(SolutionDir)intermediates\$(Configuration)\$(MSBuildProjectName)\ Spotify - - true - $(SolutionDir)output\$(Configuration)\ - $(SolutionDir)intermediates\$(Configuration)\$(MSBuildProjectName)\ - Spotify - - - false - $(SolutionDir)output\$(Configuration)\ - $(SolutionDir)intermediates\$(Configuration)\$(MSBuildProjectName)\ - Spotify - false diff --git a/spotify-reverse-shared/shared/logger.h b/spotify-reverse-shared/shared/logger.h index 770b91b..c94a0c4 100644 --- a/spotify-reverse-shared/shared/logger.h +++ b/spotify-reverse-shared/shared/logger.h @@ -1,87 +1,92 @@ #pragma once -#include -#include #include +#include #include - +#include #define L_ERROR(...) util::logger::error(__FUNCTION__ "(): " __VA_ARGS__); -#define TRACE_FN util::logger::debug( "%s()", __FUNCTION__ ); +#define TRACE_FN util::logger::debug("%s()", __FUNCTION__); -#define LOGGER_PARSE_FMT char buf[2048]; va_list va; va_start( va, fmt ); _vsnprintf_s( buf, 1024, fmt, va ); va_end( va ); -#define CREATE_LOGGER_METHOD(n) inline void n(const char* fmt, ...) { LOGGER_PARSE_FMT; log( #n, e_level_color::level_color_ ##n, buf ); } +#define LOGGER_PARSE_FMT \ + char buf[2048]; \ + va_list va; \ + va_start(va, fmt); \ + _vsnprintf_s(buf, 1024, fmt, va); \ + va_end(va); +#define CREATE_LOGGER_METHOD(n) \ + inline void n(const char* fmt, ...) { \ + LOGGER_PARSE_FMT; \ + log(#n, e_level_color::level_color_##n, buf); \ + } namespace util { - namespace logger { - enum class e_level_color : uint32_t { - level_color_none = 15, // black bg and white fg - level_color_debug = 8, - level_color_info = 10, - level_color_warn = 14, - level_color_error = 12 - }; + namespace logger { + enum class e_level_color : uint32_t { + level_color_none = 15, // black bg and white fg + level_color_debug = 8, + level_color_info = 10, + level_color_warn = 14, + level_color_error = 12 + }; - namespace _colors { - inline void* m_console_handle = nullptr; + namespace _colors { + inline void* m_console_handle = nullptr; - inline bool ensure_handle( ) { - if ( !m_console_handle ) - m_console_handle = GetStdHandle( STD_OUTPUT_HANDLE ); - return static_cast< bool >( m_console_handle ); - } + inline bool ensure_handle() { + if (!m_console_handle) + m_console_handle = GetStdHandle(STD_OUTPUT_HANDLE); + return static_cast(m_console_handle); + } - inline void apply( uint32_t clr ) { - if ( !ensure_handle( ) ) return; - SetConsoleTextAttribute( m_console_handle, clr ); - } + inline void apply(uint32_t clr) { + if (!ensure_handle()) + return; + SetConsoleTextAttribute(m_console_handle, clr); + } - inline void reset( ) { - apply( static_cast< uint32_t >( e_level_color::level_color_none ) ); - } + inline void reset() { apply(static_cast(e_level_color::level_color_none)); } - inline void colorify( uint32_t clr, std::function cb ) { - apply( clr ); - cb( ); - reset( ); - } - } + inline void colorify(uint32_t clr, std::function cb) { + apply(clr); + cb(); + reset(); + } + } // namespace _colors - inline void log( const char* prefix, e_level_color level, const char* message ) { - _colors::colorify( static_cast< uint32_t >( level ), [ prefix ] ( ) -> void { - printf( "%s >> ", prefix ); - } ); + inline void log(const char* prefix, e_level_color level, const char* message) { + _colors::colorify(static_cast(level), [prefix]() -> void { printf("%s >> ", prefix); }); - printf( "%s\n", message ); - } + printf("%s\n", message); + } - #ifdef _DEBUG - CREATE_LOGGER_METHOD( debug ); - #else - __forceinline void debug( const char* fmt, ... ) { } - #endif - CREATE_LOGGER_METHOD( info ); - CREATE_LOGGER_METHOD( warn ); - CREATE_LOGGER_METHOD( error ); - inline void fatal( const char* fmt, ... ) { - LOGGER_PARSE_FMT; - error( "Fatal error: %s", buf ); - MessageBoxA( NULL, buf, "Unspotify fatal error", MB_OK ); - ExitProcess( -1 ); - } +#ifdef _DEBUG + CREATE_LOGGER_METHOD(debug); +#else + __forceinline void debug(const char* fmt, ...) { } +#endif + CREATE_LOGGER_METHOD(info); + CREATE_LOGGER_METHOD(warn); + CREATE_LOGGER_METHOD(error); + inline void fatal(const char* fmt, ...) { + LOGGER_PARSE_FMT; + error("Fatal error: %s", buf); + MessageBoxA(NULL, buf, "Unspotify fatal error", MB_OK); + ExitProcess(-1); + } - __forceinline void startup( ) { - ::AllocConsole( ); - freopen_s( reinterpret_cast< FILE** >( stdin ), "CONIN$", "r", stdin ); - freopen_s( reinterpret_cast< FILE** >( stdout ), "CONOUT$", "w", stdout ); - ::SetConsoleTitleA( "Unspotify" ); - } + __forceinline void startup() { + ::AllocConsole(); + freopen_s(reinterpret_cast(stdin), "CONIN$", "r", stdin); + freopen_s(reinterpret_cast(stdout), "CONOUT$", "w", stdout); + ::SetConsoleTitleA("Unspotify"); + } - __forceinline void detach( ) { - ::ShowWindow( ::GetConsoleWindow( ), SW_HIDE ); - ::FreeConsole( ); - } - } -} + __forceinline void detach() { + ::ShowWindow(::GetConsoleWindow(), SW_HIDE); + ::FreeConsole(); + } + } // namespace logger +} // namespace util #undef CREATE_LOGGER_METHOD \ No newline at end of file diff --git a/spotify-reverse-shared/shared/logo.h b/spotify-reverse-shared/shared/logo.h index 01e2d38..5f824cb 100644 --- a/spotify-reverse-shared/shared/logo.h +++ b/spotify-reverse-shared/shared/logo.h @@ -1,30 +1,28 @@ #pragma once #include "logger.h" - #define UNSPOTIFY_GIT_URL "https://git.tcp.direct/dg/Unspotify" #define UNSPOTIFY_DISCORD_URL "https://discord.gg/U7X9kKcJzF" - namespace util { namespace logo { - inline void create_console_and_draw_logo( ) { - util::logger::startup( ); - util::logger::info( " d8, ,d8888b " ); - util::logger::info( " d8P `8P 88P' " ); - util::logger::info( " d888888P d888888P " ); - util::logger::info( "?88 d8P 88bd88b .d888b,?88,.d88b, d8888b ?88' 88b ?88' ?88 d8P " ); - util::logger::info( "d88 88 88P' ?8b ?8b, `?88' ?88d8P' ?88 88P 88P 88P d88 88 " ); - util::logger::info( "?8( d88 d88 88P `?8b 88b d8P88b d88 88b d88 d88 ?8( d88 " ); - util::logger::info( "`?88P'?8bd88' 88b`?888P' 888888P'`?8888P' `?8b d88' d88' `?88P'?8b " ); - util::logger::info( " 88P' )88" ); - util::logger::info( " d88 ,d8P" ); - util::logger::info( " ?8P `?888P " ); - util::logger::info( " compiled at %s %s", __DATE__, __TIME__ ); - util::logger::info( " git: %s", UNSPOTIFY_GIT_URL ); - util::logger::info( " join our discord: %s", UNSPOTIFY_DISCORD_URL ); - util::logger::info( "" ); - util::logger::info( "" ); + inline void create_console_and_draw_logo() { + util::logger::startup(); + util::logger::info(" d8, ,d8888b "); + util::logger::info(" d8P `8P 88P' "); + util::logger::info(" d888888P d888888P "); + util::logger::info("?88 d8P 88bd88b .d888b,?88,.d88b, d8888b ?88' 88b ?88' ?88 d8P "); + util::logger::info("d88 88 88P' ?8b ?8b, `?88' ?88d8P' ?88 88P 88P 88P d88 88 "); + util::logger::info("?8( d88 d88 88P `?8b 88b d8P88b d88 88b d88 d88 ?8( d88 "); + util::logger::info("`?88P'?8bd88' 88b`?888P' 888888P'`?8888P' `?8b d88' d88' `?88P'?8b "); + util::logger::info(" 88P' )88"); + util::logger::info(" d88 ,d8P"); + util::logger::info(" ?8P `?888P "); + util::logger::info(" compiled at %s %s", __DATE__, __TIME__); + util::logger::info(" git: %s", UNSPOTIFY_GIT_URL); + util::logger::info(" join our discord: %s", UNSPOTIFY_DISCORD_URL); + util::logger::info(""); + util::logger::info(""); } - } -} \ No newline at end of file + } // namespace logo +} // namespace util \ No newline at end of file diff --git a/spotify-reverse.sln b/spotify-reverse.sln index f263542..b897f9f 100644 --- a/spotify-reverse.sln +++ b/spotify-reverse.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31515.178 +# Visual Studio Version 17 +VisualStudioVersion = 17.1.32210.238 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spotify-reverse", "spotify-reverse\spotify-reverse.vcxproj", "{930F56C2-377E-4C4D-815D-B0BB2C7DDFC9}" EndProject @@ -9,12 +9,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spotify-reverse-launcher", EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spotify-reverse-shared", "spotify-reverse-shared\spotify-reverse-shared.vcxitems", "{80C10288-CFBD-49D7-84DE-BF83B13E3B24}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "solution", "solution", "{C6266EFA-749F-4905-80BB-F71B4ECE4595}" + ProjectSection(SolutionItems) = preProject + .clang-format = .clang-format + EndProjectSection +EndProject Global - GlobalSection(SharedMSBuildProjectFiles) = preSolution - spotify-reverse-shared\spotify-reverse-shared.vcxitems*{0b43a5fb-d64c-45cb-b87d-af45d7d67932}*SharedItemsImports = 4 - spotify-reverse-shared\spotify-reverse-shared.vcxitems*{80c10288-cfbd-49d7-84de-bf83b13e3b24}*SharedItemsImports = 9 - spotify-reverse-shared\spotify-reverse-shared.vcxitems*{930f56c2-377e-4c4d-815d-b0bb2c7ddfc9}*SharedItemsImports = 4 - EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x86 = Debug|x86 Release|x86 = Release|x86 @@ -35,4 +35,9 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4464B17F-3892-49EA-B9CF-52D3AC9C0DD8} EndGlobalSection + GlobalSection(SharedMSBuildProjectFiles) = preSolution + spotify-reverse-shared\spotify-reverse-shared.vcxitems*{0b43a5fb-d64c-45cb-b87d-af45d7d67932}*SharedItemsImports = 4 + spotify-reverse-shared\spotify-reverse-shared.vcxitems*{80c10288-cfbd-49d7-84de-bf83b13e3b24}*SharedItemsImports = 9 + spotify-reverse-shared\spotify-reverse-shared.vcxitems*{930f56c2-377e-4c4d-815d-b0bb2c7ddfc9}*SharedItemsImports = 4 + EndGlobalSection EndGlobal diff --git a/spotify-reverse/bootstrap/bootstrap.cpp b/spotify-reverse/bootstrap/bootstrap.cpp index cf9cf82..e3225c1 100644 --- a/spotify-reverse/bootstrap/bootstrap.cpp +++ b/spotify-reverse/bootstrap/bootstrap.cpp @@ -1,52 +1,51 @@ #include "bootstrap.h" -#include "../util/util.h" -#include "../spotify/spotify.h" -#include "../hooks/hooks.h" -#include "../updates/updates.h" #include "../exceptions/exceptions.h" +#include "../hooks/hooks.h" +#include "../spotify/spotify.h" +#include "../updates/updates.h" +#include "../util/util.h" #include "shared/logo.h" #include - namespace bootstrap { - DWORD __stdcall _initial_routine( HANDLE ) { - util::logo::create_console_and_draw_logo( ); + DWORD __stdcall _initial_routine(HANDLE) { + util::logo::create_console_and_draw_logo(); - exceptions::subscribe( ); + exceptions::subscribe(); - #ifdef CHECK_FOR_UPDATES - std::thread( updates::do_job ).detach( ); - #endif +#ifdef CHECK_FOR_UPDATES + std::thread(updates::do_job).detach(); +#endif - spotify::init( ); - hooks::init( ); + spotify::init(); + hooks::init(); - #ifdef _DEBUG - while ( !GetAsyncKeyState( VK_DELETE ) ) { - #else - util::logger::warn( "press any key to close this console" ); - _getwch( ); - util::logger::detach( ); +#ifdef _DEBUG + while (!GetAsyncKeyState(VK_DELETE)) { +#else + util::logger::warn("press any key to close this console"); + _getwch(); + util::logger::detach(); - while ( true ) { - #endif - std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); - } + while (true) { +#endif + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } - _shutdown( ); - return 1; // unreachable but whatever - } + _shutdown(); + return 1; // unreachable but whatever + } - bool startup( HINSTANCE dll_handle ) { - detail::dll_handle = dll_handle; - detail::region_size = util::mem::module_t( uintptr_t( dll_handle ) ).get_nt_headers( )->OptionalHeader.SizeOfImage; - CreateThread( nullptr, 0, _initial_routine, 0, 0, nullptr ); - return true; - } + bool startup(HINSTANCE dll_handle) { + detail::dll_handle = dll_handle; + detail::region_size = util::mem::module_t(uintptr_t(dll_handle)).get_nt_headers()->OptionalHeader.SizeOfImage; + CreateThread(nullptr, 0, _initial_routine, 0, 0, nullptr); + return true; + } - void _shutdown( ) { - hooks::shutdown( ); - FreeLibraryAndExitThread( reinterpret_cast< HMODULE >( detail::dll_handle ), 0x1 ); - } -} + void _shutdown() { + hooks::shutdown(); + FreeLibraryAndExitThread(reinterpret_cast(detail::dll_handle), 0x1); + } +} // namespace bootstrap diff --git a/spotify-reverse/bootstrap/bootstrap.h b/spotify-reverse/bootstrap/bootstrap.h index 6e50aec..f96adda 100644 --- a/spotify-reverse/bootstrap/bootstrap.h +++ b/spotify-reverse/bootstrap/bootstrap.h @@ -1,16 +1,14 @@ #pragma once #include - namespace bootstrap { - namespace detail { - inline HINSTANCE dll_handle; - inline DWORD region_size; - } + namespace detail { + inline HINSTANCE dll_handle; + inline DWORD region_size; + } // namespace detail - DWORD __stdcall _initial_routine( HANDLE ); - - bool startup( HINSTANCE handle ); - void _shutdown( ); -} + DWORD __stdcall _initial_routine(HANDLE); + bool startup(HINSTANCE handle); + void _shutdown(); +} // namespace bootstrap diff --git a/spotify-reverse/defines.h b/spotify-reverse/defines.h index bc76673..b147783 100644 --- a/spotify-reverse/defines.h +++ b/spotify-reverse/defines.h @@ -2,12 +2,12 @@ // autoupdates -// @note: es3n1n: v1.0.7 = 107 -#define UNSPOTIFY_VERSION 107 +// @note: es3n1n: v1.0.8 = 108 +#define UNSPOTIFY_VERSION 108 #define AUTOUPDATER_DOMAIN "es3n.in" #define AUTOUPDATER_URL "unspotify.json" #ifndef _DEBUG -#define CHECK_FOR_UPDATES + #define CHECK_FOR_UPDATES #endif diff --git a/spotify-reverse/dllmain.cpp b/spotify-reverse/dllmain.cpp index 4c6bda1..df49ca7 100644 --- a/spotify-reverse/dllmain.cpp +++ b/spotify-reverse/dllmain.cpp @@ -1,9 +1,9 @@ #include "bootstrap/bootstrap.h" #include +BOOL __stdcall DllMain(std::uintptr_t hinstDll, std::uint32_t fdwReason, std::uintptr_t) { + if (fdwReason != DLL_PROCESS_ATTACH) + return 1; -BOOL __stdcall DllMain( std::uintptr_t hinstDll, std::uint32_t fdwReason, std::uintptr_t ) { - if ( fdwReason != DLL_PROCESS_ATTACH ) return 1; - - return bootstrap::startup( reinterpret_cast< HINSTANCE >( hinstDll ) ); + return bootstrap::startup(reinterpret_cast(hinstDll)); } diff --git a/spotify-reverse/exceptions/exceptions.cpp b/spotify-reverse/exceptions/exceptions.cpp index fe963ff..423bd07 100644 --- a/spotify-reverse/exceptions/exceptions.cpp +++ b/spotify-reverse/exceptions/exceptions.cpp @@ -1,42 +1,39 @@ #include "exceptions.h" #include "../bootstrap/bootstrap.h" #include "shared/logger.h" -#include -#include #include - +#include +#include namespace exceptions { - LONG __stdcall handler( EXCEPTION_POINTERS* info ) { - static bool logged { false }; + LONG __stdcall handler(EXCEPTION_POINTERS* info) { + static bool logged { false }; - if ( logged ) - return EXCEPTION_CONTINUE_SEARCH; // @note: es3n1n: log exceptions only once + if (logged) + return EXCEPTION_CONTINUE_SEARCH; // @note: es3n1n: log exceptions only once - auto exc_addr = reinterpret_cast< uintptr_t >( info->ExceptionRecord->ExceptionAddress ); + auto exc_addr = reinterpret_cast(info->ExceptionRecord->ExceptionAddress); - if ( ( exc_addr < reinterpret_cast< uintptr_t >( bootstrap::detail::dll_handle ) || - exc_addr >( reinterpret_cast< uintptr_t >( bootstrap::detail::dll_handle ) + bootstrap::detail::region_size ) ) ) { - return EXCEPTION_CONTINUE_SEARCH; // @note: es3n1n: log exceptions only from our mod - } + if ((exc_addr < reinterpret_cast(bootstrap::detail::dll_handle) + || exc_addr > (reinterpret_cast(bootstrap::detail::dll_handle) + bootstrap::detail::region_size))) { + return EXCEPTION_CONTINUE_SEARCH; // @note: es3n1n: log exceptions only from our mod + } - std::stringstream log_msg; - log_msg << "Module base: " << std::hex << std::showbase << bootstrap::detail::dll_handle << std::endl; - log_msg << "Module size: " << std::hex << std::showbase << bootstrap::detail::region_size << std::endl; - log_msg << "Exception address: " << std::hex << std::showbase << exc_addr << std::endl; - log_msg << "Exception code: " << std::hex << std::showbase << info->ExceptionRecord->ExceptionCode << std::endl; - log_msg << "EAX: " << std::hex << std::showbase << info->ContextRecord->Eax << " | EBX: " << info->ContextRecord->Ebx << std::endl; - log_msg << "ECX: " << std::hex << std::showbase << info->ContextRecord->Ecx << " | EDX: " << info->ContextRecord->Edx << std::endl; - log_msg << "EBP: " << std::hex << std::showbase << info->ContextRecord->Ebp << " | ESP: " << info->ContextRecord->Esp << std::endl; - log_msg << "ESI: " << std::hex << std::showbase << info->ContextRecord->Esi << " | EDI: " << info->ContextRecord->Edi << std::endl; + std::stringstream log_msg; + log_msg << "Module base: " << std::hex << std::showbase << bootstrap::detail::dll_handle << std::endl; + log_msg << "Module size: " << std::hex << std::showbase << bootstrap::detail::region_size << std::endl; + log_msg << "Exception address: " << std::hex << std::showbase << exc_addr << std::endl; + log_msg << "Exception code: " << std::hex << std::showbase << info->ExceptionRecord->ExceptionCode << std::endl; + log_msg << "EAX: " << std::hex << std::showbase << info->ContextRecord->Eax << " | EBX: " << info->ContextRecord->Ebx << std::endl; + log_msg << "ECX: " << std::hex << std::showbase << info->ContextRecord->Ecx << " | EDX: " << info->ContextRecord->Edx << std::endl; + log_msg << "EBP: " << std::hex << std::showbase << info->ContextRecord->Ebp << " | ESP: " << info->ContextRecord->Esp << std::endl; + log_msg << "ESI: " << std::hex << std::showbase << info->ContextRecord->Esi << " | EDI: " << info->ContextRecord->Edi << std::endl; - util::logger::fatal( log_msg.str( ).c_str( ) ); + util::logger::fatal(log_msg.str().c_str()); - logged = true; - return EXCEPTION_EXECUTE_HANDLER; - } + logged = true; + return EXCEPTION_EXECUTE_HANDLER; + } - void subscribe( ) { - AddVectoredExceptionHandler( 1, handler ); - } -} + void subscribe() { AddVectoredExceptionHandler(1, handler); } +} // namespace exceptions diff --git a/spotify-reverse/exceptions/exceptions.h b/spotify-reverse/exceptions/exceptions.h index 4c35170..94bd3e0 100644 --- a/spotify-reverse/exceptions/exceptions.h +++ b/spotify-reverse/exceptions/exceptions.h @@ -1,9 +1,8 @@ #pragma once -#include #include - +#include namespace exceptions { - LONG __stdcall handler( EXCEPTION_POINTERS* info ); - void subscribe( ); -} + LONG __stdcall handler(EXCEPTION_POINTERS* info); + void subscribe(); +} // namespace exceptions diff --git a/spotify-reverse/hooks/hooked/create_track.cpp b/spotify-reverse/hooks/hooked/create_track.cpp index b06f105..90dace0 100644 --- a/spotify-reverse/hooks/hooked/create_track.cpp +++ b/spotify-reverse/hooks/hooked/create_track.cpp @@ -1,22 +1,18 @@ #include "../hooks.h" - namespace hooks { - namespace hooked { - /* + namespace hooked { + /* @xref: " Creating track player for track (playback_id %s)" */ - void __fastcall create_track( - void* pthis, void* pedx, - spotify::structs::player_meta_t* player_meta, - spotify::structs::player_track_meta_t* track_meta, - double speed, int normalization, int urgency, int track_select_flag, int flag, int stream_type - ) { - player_meta->m_should_skip = static_cast< std::uint32_t >( static_cast< bool >( strstr( track_meta->m_track_uri, "spotify:ad:" ) ) ); - util::logger::info( "Playing %s | should_skip: %s", track_meta->m_track_uri, player_meta->m_should_skip ? "true" : "false" ); - if ( player_meta->m_should_skip ) - speed = 29.0; - original::create_track( pthis, pedx, player_meta, track_meta, speed, normalization, urgency, track_select_flag, flag, stream_type ); - } - } -} + void __fastcall create_track(void* pthis, void* pedx, spotify::structs::player_meta_t* player_meta, + spotify::structs::player_track_meta_t* track_meta, double speed, int normalization, int urgency, int track_select_flag, int flag, + int stream_type) { + player_meta->m_should_skip = static_cast(static_cast(strstr(track_meta->m_track_uri, "spotify:ad:"))); + util::logger::info("Playing %s | should_skip: %s", track_meta->m_track_uri, player_meta->m_should_skip ? "true" : "false"); + if (player_meta->m_should_skip) + speed = 29.0; + original::create_track(pthis, pedx, player_meta, track_meta, speed, normalization, urgency, track_select_flag, flag, stream_type); + } + } // namespace hooked +} // namespace hooks diff --git a/spotify-reverse/hooks/hooked/debug_msg.cpp b/spotify-reverse/hooks/hooked/debug_msg.cpp index 428e938..76b6902 100644 --- a/spotify-reverse/hooks/hooked/debug_msg.cpp +++ b/spotify-reverse/hooks/hooked/debug_msg.cpp @@ -1,19 +1,19 @@ #include "../hooks.h" - namespace hooks { - namespace hooked { - #ifdef _DEBUG - std::uintptr_t __cdecl debug_msg( std::uint32_t, std::uint32_t, const char* win, const char* flag, std::uint32_t size, std::uint32_t, const char* fmt, ... ) { // @xref: "Path provided in --%s '%s' (resolved to '%s') does not exist." - LOGGER_PARSE_FMT; + namespace hooked { +#ifdef _DEBUG + std::uintptr_t __cdecl debug_msg(std::uint32_t, std::uint32_t, const char* win, const char* flag, std::uint32_t size, std::uint32_t, + const char* fmt, ...) { // @xref: "Path provided in --%s '%s' (resolved to '%s') does not exist." + LOGGER_PARSE_FMT; - for ( int i = 0; i < strlen( buf ); i++ ) - buf[ i ] = buf[ i ] == '\n' ? ' ' : buf[ i ]; + for (std::size_t i = 0; i < strlen(buf); i++) + buf[i] = buf[i] == '\n' ? ' ' : buf[i]; - printf( "[spotify::debug_msg] %s\n", buf ); + printf("[spotify::debug_msg] %s\n", buf); - return 0; - } - #endif - } -} \ No newline at end of file + return 0; + } +#endif + } // namespace hooked +} // namespace hooks \ No newline at end of file diff --git a/spotify-reverse/hooks/hooked/get_ad.cpp b/spotify-reverse/hooks/hooked/get_ad.cpp index 17327ac..b6579ab 100644 --- a/spotify-reverse/hooks/hooked/get_ad.cpp +++ b/spotify-reverse/hooks/hooked/get_ad.cpp @@ -1,10 +1,9 @@ #include "../hooks.h" - namespace hooks { - namespace hooked { - std::uintptr_t __cdecl get_ad( int a1, int a2 ) { // @xref: "advertiser" - return 0; - } - } -} \ No newline at end of file + namespace hooked { + std::uintptr_t __cdecl get_ad(int a1, int a2) { // @xref: "advertiser" + return 0; + } + } // namespace hooked +} // namespace hooks \ No newline at end of file diff --git a/spotify-reverse/hooks/hooks.cpp b/spotify-reverse/hooks/hooks.cpp index 63b8fc0..8d805d5 100644 --- a/spotify-reverse/hooks/hooks.cpp +++ b/spotify-reverse/hooks/hooks.cpp @@ -1,24 +1,23 @@ #include "hooks.h" - -#define CREATE_HOOK(n) if ( !util::hooking::detour::create(spotify::addr:: ##n, hooked:: ##n, reinterpret_cast< void** > ( &original:: ##n ) ) ) util::logger::fatal("Unable to hook %s", #n); - +#define CREATE_HOOK(n) \ + if (!util::hooking::detour::create(spotify::addr::##n, hooked::##n, reinterpret_cast(&original::##n))) \ + util::logger::fatal("Unable to hook %s", #n); namespace hooks { - void init( ) { - if ( !util::hooking::detour::init( ) ) - util::logger::fatal( "Unable to init minhook" ); - #ifdef _DEBUG - CREATE_HOOK( debug_msg ); - #endif - CREATE_HOOK( get_ad ); - CREATE_HOOK( create_track ); - } - - void shutdown( ) { - util::hooking::detour::remove( ); - } -} + void init() { + if (!util::hooking::detour::init()) + util::logger::fatal("Unable to init minhook"); +#pragma warning(disable : 5103) +#ifdef _DEBUG + CREATE_HOOK(debug_msg); +#endif + CREATE_HOOK(get_ad); + CREATE_HOOK(create_track); +#pragma warning(default : 5103) + } + void shutdown() { util::hooking::detour::remove(); } +} // namespace hooks #undef CREATE_HOOK diff --git a/spotify-reverse/hooks/hooks.h b/spotify-reverse/hooks/hooks.h index 3493a80..dfa3e50 100644 --- a/spotify-reverse/hooks/hooks.h +++ b/spotify-reverse/hooks/hooks.h @@ -1,24 +1,26 @@ #pragma once -#include "../util/util.h" #include "../spotify/spotify.h" - +#include "../util/util.h" namespace hooks { - namespace hooked { - #ifdef _DEBUG - std::uintptr_t __cdecl debug_msg( std::uint32_t, std::uint32_t, const char* win, const char* flag, std::uint32_t size, std::uint32_t, const char* fmt, ... ); - #endif - std::uintptr_t __cdecl get_ad( int a1, int a2 ); - void __fastcall create_track( void* pthis, void* pedx, spotify::structs::player_meta_t* player_meta, spotify::structs::player_track_meta_t* track_meta, double speed, int normalization, int urgency, int track_select_flag, int flag, int stream_type ); - } - namespace original { - #ifdef _DEBUG - inline decltype( &hooked::debug_msg ) debug_msg; - #endif - inline decltype( &hooked::get_ad ) get_ad; - inline decltype( &hooked::create_track ) create_track; - } + namespace hooked { +#ifdef _DEBUG + std::uintptr_t __cdecl debug_msg(std::uint32_t, std::uint32_t, const char* win, const char* flag, std::uint32_t size, std::uint32_t, + const char* fmt, ...); +#endif + std::uintptr_t __cdecl get_ad(int a1, int a2); + void __fastcall create_track(void* pthis, void* pedx, spotify::structs::player_meta_t* player_meta, + spotify::structs::player_track_meta_t* track_meta, double speed, int normalization, int urgency, int track_select_flag, int flag, + int stream_type); + } // namespace hooked + namespace original { +#ifdef _DEBUG + inline decltype(&hooked::debug_msg) debug_msg; +#endif + inline decltype(&hooked::get_ad) get_ad; + inline decltype(&hooked::create_track) create_track; + } // namespace original - void init( ); - void shutdown( ); -} \ No newline at end of file + void init(); + void shutdown(); +} // namespace hooks \ No newline at end of file diff --git a/spotify-reverse/spotify-reverse.vcxproj b/spotify-reverse/spotify-reverse.vcxproj index 250fb17..d929f8c 100644 --- a/spotify-reverse/spotify-reverse.vcxproj +++ b/spotify-reverse/spotify-reverse.vcxproj @@ -9,14 +9,6 @@ Release Win32 - - Debug - x64 - - - Release - x64 - 16.0 @@ -31,7 +23,7 @@ true ClangCL Unicode - 12.0.0 + 13.0.1 DynamicLibrary @@ -39,22 +31,7 @@ ClangCL true Unicode - 12.0.0 - - - DynamicLibrary - true - ClangCL - Unicode - 12.0.0 - - - DynamicLibrary - false - ClangCL - true - Unicode - 12.0.0 + 13.0.1 @@ -68,32 +45,18 @@ - - - - - - true $(SolutionDir)output\$(Configuration)\ $(SolutionDir)intermediates\$(Configuration)\$(MSBuildProjectName)\ + false false $(SolutionDir)output\$(Configuration)\ $(SolutionDir)intermediates\$(Configuration)\$(MSBuildProjectName)\ - - - true - $(SolutionDir)output\$(Configuration)\ - $(SolutionDir)intermediates\$(Configuration)\$(MSBuildProjectName)\ - - - false - $(SolutionDir)output\$(Configuration)\ - $(SolutionDir)intermediates\$(Configuration)\$(MSBuildProjectName)\ + false false @@ -107,7 +70,7 @@ stdcpplatest stdc17 true - -Xclang -Ofast -Xclang -fno-threadsafe-statics -Xclang -fdelayed-template-parsing -fcf-protection=none -mllvm -pgso -Wno-missing-braces -Wno-deprecated-volatile -Wno-missing-field-initializers -Wno-ignored-pragma-optimize /clang:-fno-unwind-tables /clang:-ffast-math /clang:-fno-builtin -Wno-gnu-string-literal-operator-template -Wno-unused-private-field -Wno-invalid-token-paste -Wno-microsoft-cast -Wno-unused-command-line-argument -Wno-pragma-once-outside-header %(AdditionalOptions) + -Xclang -Ofast -Xclang -fno-threadsafe-statics -Xclang -fdelayed-template-parsing -fcf-protection=none -mllvm -pgso -Wno-int-to-void-pointer-cast -Wno-missing-braces -Wno-deprecated-volatile -Wno-missing-field-initializers -Wno-ignored-pragma-optimize /clang:-fno-unwind-tables /clang:-ffast-math /clang:-fno-builtin -Wno-gnu-string-literal-operator-template -Wno-unused-private-field -Wno-invalid-token-paste -Wno-microsoft-cast -Wno-unused-command-line-argument -Wno-sign-compare -Wno-multichar -Wno-unused-parameter -Wno-microsoft-enum-forward-reference MultiThreadedDebug Disabled @@ -123,53 +86,12 @@ true true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _HAS_STATIC_RTTI=0;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true stdcpplatest stdc17 true - -Xclang -Ofast -Xclang -fno-threadsafe-statics -Xclang -fdelayed-template-parsing -fcf-protection=none -mllvm -pgso -Wno-missing-braces -Wno-deprecated-volatile -Wno-missing-field-initializers -Wno-ignored-pragma-optimize /clang:-fno-unwind-tables /clang:-ffast-math /clang:-fno-builtin -Wno-gnu-string-literal-operator-template -Wno-unused-private-field -Wno-invalid-token-paste -Wno-microsoft-cast -Wno-unused-command-line-argument -Wno-pragma-once-outside-header %(AdditionalOptions) - MultiThreaded - - - Windows - true - true - true - /MAP /MERGE:.voltbl=.data /MERGE:.retplne=.data /MERGE:.gehcont=.data /MERGE:.00cfg=.data /MERGE:_RDATA=.rdata /FORCE:UNRESOLVED %(AdditionalOptions) - - - - - Level3 - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - stdcpplatest - stdc17 - true - -Xclang -Ofast -Xclang -fno-threadsafe-statics -Xclang -fdelayed-template-parsing -fcf-protection=none -mllvm -pgso -Wno-missing-braces -Wno-deprecated-volatile -Wno-missing-field-initializers -Wno-ignored-pragma-optimize /clang:-fno-unwind-tables /clang:-ffast-math /clang:-fno-builtin -Wno-gnu-string-literal-operator-template -Wno-unused-private-field -Wno-invalid-token-paste -Wno-microsoft-cast -Wno-unused-command-line-argument -Wno-pragma-once-outside-header %(AdditionalOptions) - MultiThreadedDebug - Disabled - - - Windows - true - /MAP /MERGE:.voltbl=.data /MERGE:.retplne=.data /MERGE:.gehcont=.data /MERGE:.00cfg=.data /MERGE:_RDATA=.rdata /FORCE:UNRESOLVED %(AdditionalOptions) - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - stdcpplatest - stdc17 - true - -Xclang -Ofast -Xclang -fno-threadsafe-statics -Xclang -fdelayed-template-parsing -fcf-protection=none -mllvm -pgso -Wno-missing-braces -Wno-deprecated-volatile -Wno-missing-field-initializers -Wno-ignored-pragma-optimize /clang:-fno-unwind-tables /clang:-ffast-math /clang:-fno-builtin -Wno-gnu-string-literal-operator-template -Wno-unused-private-field -Wno-invalid-token-paste -Wno-microsoft-cast -Wno-unused-command-line-argument -Wno-pragma-once-outside-header %(AdditionalOptions) + -Xclang -fno-rtti -Xclang -Ofast -Xclang -fno-threadsafe-statics -Xclang -fdelayed-template-parsing -fcf-protection=none -mllvm -pgso -Wno-int-to-void-pointer-cast -Wno-missing-braces -Wno-deprecated-volatile -Wno-missing-field-initializers -Wno-ignored-pragma-optimize /clang:-fno-unwind-tables /clang:-ffast-math /clang:-fno-builtin -Wno-gnu-string-literal-operator-template -Wno-unused-private-field -Wno-invalid-token-paste -Wno-microsoft-cast -Wno-unused-command-line-argument -Wno-sign-compare -Wno-multichar -Wno-unused-parameter -Wno-microsoft-enum-forward-reference MultiThreaded @@ -197,7 +119,6 @@ - @@ -219,6 +140,7 @@ + diff --git a/spotify-reverse/spotify-reverse.vcxproj.filters b/spotify-reverse/spotify-reverse.vcxproj.filters index e216926..a3e8c38 100644 --- a/spotify-reverse/spotify-reverse.vcxproj.filters +++ b/spotify-reverse/spotify-reverse.vcxproj.filters @@ -18,9 +18,6 @@ Source Files - - Source Files - Source Files @@ -134,5 +131,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/spotify-reverse/spotify-reverse.vcxproj.user b/spotify-reverse/spotify-reverse.vcxproj.user index 4e67d47..343e5ec 100644 --- a/spotify-reverse/spotify-reverse.vcxproj.user +++ b/spotify-reverse/spotify-reverse.vcxproj.user @@ -13,14 +13,4 @@ true WindowsLocalDebugger - - oSpotify.exe - true - WindowsLocalDebugger - - - Spotify.exe - true - WindowsLocalDebugger - \ No newline at end of file diff --git a/spotify-reverse/spotify/spotify.cpp b/spotify-reverse/spotify/spotify.cpp index 71f52f5..299153d 100644 --- a/spotify-reverse/spotify/spotify.cpp +++ b/spotify-reverse/spotify/spotify.cpp @@ -1,76 +1,75 @@ #include "spotify.h" - -#define ASSERT_PATTERN(s) if ( !addr:: ##s .valid( ) ) util::logger::fatal( "Pattern %s not found. Please update your Unspotify version", #s); -#define ASSERT_PATTERN_STEP(s) if ( !s ) util::logger::fatal( "Unable to find %s at %d", #s, __LINE__ ) - +#define ASSERT_PATTERN(s) \ + if (!addr::##s.valid()) \ + util::logger::fatal("Pattern %s not found. Please update your Unspotify version", #s); +#define ASSERT_PATTERN_STEP(s) \ + if (!s) \ + util::logger::fatal("Unable to find %s at %d", #s, __LINE__) namespace spotify { - void init( ) { - TRACE_FN; + void init() { +#pragma warning(disable : 5103) + TRACE_FN; - modules::spotify = util::mem::module_t( nullptr ); - util::logger::debug( "module::spotify = 0x%p", modules::spotify ); + modules::spotify = util::mem::module_t(nullptr); + util::logger::debug("module::spotify = 0x%p", modules::spotify); - uint32_t str; - util::mem::addr_t sig; - std::vector pattern = {}; + uint32_t str; + util::mem::addr_t sig; + std::vector pattern = {}; +#ifdef _DEBUG + // "Could not create stream reader for file: %s" + str = modules::spotify.sig( + "43 6F 75 6C 64 20 6E 6F 74 20 63 72 65 61 74 65 20 73 74 72 65 61 6D 20 72 65 61 64 65 72 20 66 6F 72 20 66 69 6C 65 3A 20 25 73"); + ASSERT_PATTERN_STEP(str); + pattern.clear(); + pattern.emplace_back(0x68 /* push offset */); + for (int i = 0; i < 4; i++) + pattern.emplace_back((int)(((uint8_t*)(&str))[i])); + sig = modules::spotify.sig(pattern); + ASSERT_PATTERN_STEP(sig); + addr::debug_msg = sig.walk_until(0x6A /* push 02 */).walk_until(0xE8 /* call */).rel(1); + util::logger::debug("addr::debug_msg = 0x%p", addr::debug_msg); + ASSERT_PATTERN(debug_msg); +#endif - #ifdef _DEBUG - // "Could not create stream reader for file: %s" - str = modules::spotify.sig( "43 6F 75 6C 64 20 6E 6F 74 20 63 72 65 61 74 65 20 73 74 72 65 61 6D 20 72 65 61 64 65 72 20 66 6F 72 20 66 69 6C 65 3A 20 25 73" ); - ASSERT_PATTERN_STEP( str ); - pattern.clear( ); - pattern.emplace_back( 0x68 /* push offset */ ); - for ( int i = 0; i < 4; i++ ) - pattern.emplace_back( ( int )( ( ( uint8_t* )( &str ) )[ i ] ) ); - sig = modules::spotify.sig( pattern ); - ASSERT_PATTERN_STEP( sig ); - addr::debug_msg = - sig.walk_until( 0x6A /* push 02 */ ).walk_until( 0xE8 /* call */ ).rel( 1 ); - util::logger::debug( "addr::debug_msg = 0x%p", addr::debug_msg ); - ASSERT_PATTERN( debug_msg ); - #endif - - - // "ad_type" - str = modules::spotify.sig( "61 64 5F 74 79 70 65 00" ); - ASSERT_PATTERN_STEP( str ); - pattern.clear( ); - for ( int i = 0; i < 4; i++ ) - pattern.emplace_back( ( int )( ( ( uint8_t* )( &str ) )[ i ] ) ); - sig = modules::spotify.sig( pattern ); - ASSERT_PATTERN_STEP( sig ); - do { - sig = sig.walk_back_until( 0xC3 /* retn */ ); - } while ( sig.offset( -5 ).read( ) != 0xE8 ); - addr::get_ad = sig.add( 1 ).read( ) == 0x68 /* push */ ? sig.add( 1 ) : sig.walk_until( 0x55 /* push ebp */ ); - util::logger::debug( "addr::get_ad = 0x%p", addr::get_ad ); - ASSERT_PATTERN( get_ad ); - - - // " Creating track player for track (playback_id %s)" - str = modules::spotify.sig( "20 20 20 20 43 72 65 61 74 69 6E 67 20 74 72 61 63 6B 20 70 6C 61 79 65 72 20 66 6F 72 20 74 72 61 63 6B 20 28 70 6C 61 79 62 61 63 6B 5F 69 64 20 25 73 29" ); - ASSERT_PATTERN_STEP( sig ); - pattern.clear( ); - pattern.emplace_back( 0x68 /* push offset */ ); - for ( int i = 0; i < 4; i++ ) - pattern.emplace_back( ( int )( ( ( uint8_t* )( &str ) )[ i ] ) ); - sig = modules::spotify.sig( pattern ); - ASSERT_PATTERN_STEP( sig ); - addr::create_track = sig.walk_back_until( 0xC2 /* retn */ ).offset( 3 /* C2 04 00 */ ); - while ( addr::create_track.read( ) == 0xE8 /* call */ ) - addr::create_track = addr::create_track.add( 5 ); // E8 + 4 bytes addr - //if ( addr::create_track.read( ) == 0xCC /* align */ ) - // addr::create_track = addr::create_track.walk_until( 0x55 /* push ebp */ ); - while ( addr::create_track.read( ) == 0xCC ) - addr::create_track = addr::create_track.add( 1 ); // skip aligns - util::logger::debug( "addr::create_track = 0x%p", addr::create_track ); - ASSERT_PATTERN( create_track ); - } -} + // "ad_type" + str = modules::spotify.sig("61 64 5F 74 79 70 65 00"); + ASSERT_PATTERN_STEP(str); + pattern.clear(); + for (int i = 0; i < 4; i++) + pattern.emplace_back((int)(((uint8_t*)(&str))[i])); + sig = modules::spotify.sig(pattern); + ASSERT_PATTERN_STEP(sig); + do { + sig = sig.walk_back_until(0xC2 /* retn */); + } while (sig.offset(-5).read() != 0xE8 && sig.offset(-8).read() != 0xE8); + addr::get_ad = sig.add(1).read() == 0x68 /* push */ ? sig.add(1) : sig.walk_until(0x68 /* push 0D4h */); + util::logger::debug("addr::get_ad = 0x%p", addr::get_ad); + ASSERT_PATTERN(get_ad); + // " Creating track player for track (playback_id %s)" + str = modules::spotify.sig("20 20 20 20 43 72 65 61 74 69 6E 67 20 74 72 61 63 6B 20 70 6C 61 79 65 72 20 66 6F 72 20 74 72 61 63 6B 20 28 70 6C " + "61 79 62 61 63 6B 5F 69 64 20 25 73 29"); + ASSERT_PATTERN_STEP(sig); + pattern.clear(); + pattern.emplace_back(0x68 /* push offset */); + for (int i = 0; i < 4; i++) + pattern.emplace_back((int)(((uint8_t*)(&str))[i])); + sig = modules::spotify.sig(pattern); + ASSERT_PATTERN_STEP(sig); + addr::create_track = sig.walk_back_until(0xC2 /* retn */).offset(3 /* C2 04 00 */); + while (addr::create_track.read() == 0xE8 /* call */) + addr::create_track = addr::create_track.add(5); // E8 + 4 bytes addr + while (addr::create_track.read() == 0xCC) + addr::create_track = addr::create_track.add(1); // skip aligns + util::logger::debug("addr::create_track = 0x%p", addr::create_track); + ASSERT_PATTERN(create_track); +#pragma warning(default : 5103) + } +} // namespace spotify #undef ASSERT_PATTERN #undef ASSERT_PATTERN_STEP diff --git a/spotify-reverse/spotify/spotify.h b/spotify-reverse/spotify/spotify.h index d0b253f..95bfd97 100644 --- a/spotify-reverse/spotify/spotify.h +++ b/spotify-reverse/spotify/spotify.h @@ -1,31 +1,37 @@ #pragma once #include "../util/util.h" - namespace spotify { - namespace structs { - struct player_meta_t { - private: char __pad[ 0x74 ]; - public: std::uint32_t m_should_skip; - }; + namespace structs { + struct player_meta_t { + private: + char __pad[0x74]; - struct player_track_meta_t { - private: char __pad[ 0x48 ]; - public: const char* m_track_uri; - }; - } + public: + std::uint32_t m_should_skip; + }; - namespace modules { - inline util::mem::module_t spotify; - } + struct player_track_meta_t { + private: + char __pad[0x48]; - namespace addr { - #ifdef _DEBUG - inline util::mem::addr_t debug_msg; - #endif - inline util::mem::addr_t get_ad; - inline util::mem::addr_t create_track; - } + public: + const char* m_track_uri; + }; + } // namespace structs - void init( ); -} + namespace modules { + inline util::mem::module_t spotify; + } + + namespace addr { +#ifdef _DEBUG + inline util::mem::addr_t debug_msg; +#endif + inline util::mem::addr_t get_ad; + inline util::mem::addr_t create_track; + inline util::mem::addr_t should_show_ad; + } // namespace addr + + void init(); +} // namespace spotify diff --git a/spotify-reverse/updates/updates.cpp b/spotify-reverse/updates/updates.cpp index 63b59f3..6cd511e 100644 --- a/spotify-reverse/updates/updates.cpp +++ b/spotify-reverse/updates/updates.cpp @@ -1,46 +1,41 @@ #include "updates.h" - namespace updates { - update_info_t poll_info( ) { - auto [data, error] = util::networking::get( AUTOUPDATER_DOMAIN, AUTOUPDATER_URL ); - if ( error ) - return update_info_t { - .m_error = true, - .m_error_desc = "Internal server error :shrug:" - }; + update_info_t poll_info() { + auto [data, error] = util::networking::get(AUTOUPDATER_DOMAIN, AUTOUPDATER_URL); + if (error) + return update_info_t { .m_error = true, .m_error_desc = "Internal server error :shrug:" }; - return update_info_t { - .m_error = false, - .m_version = data[ "version" ].get( ), - .m_changelog = data[ "changelog" ].get( ), - .m_is_required = data[ "required" ].get( ), - .m_download_url = data[ "download_url" ].get( ) - }; - } + return update_info_t { .m_error = false, + .m_version = data["version"].get(), + .m_changelog = data["changelog"].get(), + .m_is_required = data["required"].get(), + .m_download_url = data["download_url"].get() }; + } - void do_job( ) { - auto update_info = poll_info( ); - if ( update_info.m_error ) { - util::logger::error( "Failed to poll newest version info: %s", update_info.m_error_desc.c_str( ) ); - return; - } + void do_job() { + auto update_info = poll_info(); + if (update_info.m_error) { + util::logger::error("Failed to poll newest version info: %s", update_info.m_error_desc.c_str()); + return; + } - if ( update_info.m_version <= UNSPOTIFY_VERSION ) // @note: es3n1n: if we are up2date - return; + if (update_info.m_version <= UNSPOTIFY_VERSION) // @note: es3n1n: if we are up2date + return; - if ( update_info.m_is_required ) { - util::logger::fatal( "New version is available!\n\nChangelog:\n%s\nDownload url: %s", update_info.m_changelog.c_str( ), update_info.m_download_url.c_str( ) ); - return; - } + if (update_info.m_is_required) { + util::logger::fatal("New version is available!\n\nChangelog:\n%s\nDownload url: %s", update_info.m_changelog.c_str(), + update_info.m_download_url.c_str()); + return; + } - util::logger::info( "New version is available!" ); - util::logger::info( "" ); - util::logger::info( "" ); - util::logger::info( "Changelog:" ); - printf( "%s\n", update_info.m_changelog.c_str( ) ); - util::logger::info( "" ); - util::logger::info( "" ); - util::logger::info( "Download url: %s", update_info.m_download_url.c_str( ) ); - } -} \ No newline at end of file + util::logger::info("New version is available!"); + util::logger::info(""); + util::logger::info(""); + util::logger::info("Changelog:"); + printf("%s\n", update_info.m_changelog.c_str()); + util::logger::info(""); + util::logger::info(""); + util::logger::info("Download url: %s", update_info.m_download_url.c_str()); + } +} // namespace updates \ No newline at end of file diff --git a/spotify-reverse/updates/updates.h b/spotify-reverse/updates/updates.h index 855debb..b05a600 100644 --- a/spotify-reverse/updates/updates.h +++ b/spotify-reverse/updates/updates.h @@ -3,18 +3,17 @@ #include "../util/networking/networking.h" #include "shared/logger.h" - namespace updates { - struct update_info_t { - bool m_error = false; - std::string m_error_desc = "Unable to connect to server"; + struct update_info_t { + bool m_error = false; + std::string m_error_desc = "Unable to connect to server"; - uint32_t m_version = UNSPOTIFY_VERSION; - std::string m_changelog = "Failed to request update info"; - bool m_is_required = false; - std::string m_download_url = "https://git.tcp.direct/dg/unspotify"; - }; + uint32_t m_version = UNSPOTIFY_VERSION; + std::string m_changelog = "Failed to request update info"; + bool m_is_required = false; + std::string m_download_url = "https://git.tcp.direct/dg/unspotify"; + }; - update_info_t poll_info( ); - void do_job( ); -} + update_info_t poll_info(); + void do_job(); +} // namespace updates diff --git a/spotify-reverse/util/hooking/detours/detours.cpp b/spotify-reverse/util/hooking/detours/detours.cpp index 8f6d8a1..68b8d19 100644 --- a/spotify-reverse/util/hooking/detours/detours.cpp +++ b/spotify-reverse/util/hooking/detours/detours.cpp @@ -1,17 +1,11 @@ #include "detours.h" - namespace util::hooking::detour { - bool init( ) { - return MH_Initialize( ) == MH_OK; - } + bool init() { return !MH_Initialize(); } - bool create( void* target, void* detour, void** orig ) { - return MH_CreateHook( target, detour, orig ) == MH_OK && - MH_EnableHook( target ) == MH_OK; - } + bool create(void* target, void* detour, void** orig) { + return MH_CreateHook(target, detour, orig) == MH_STATUS::MH_OK && MH_EnableHook(target) == MH_STATUS::MH_OK; + } - bool remove( void* target ) { - return MH_DisableHook( target ) == MH_OK; - } -} + bool remove(void* target) { return MH_DisableHook(target) == MH_STATUS::MH_OK; } +} // namespace util::hooking::detour diff --git a/spotify-reverse/util/hooking/detours/detours.h b/spotify-reverse/util/hooking/detours/detours.h index 50c8e02..9c4ff37 100644 --- a/spotify-reverse/util/hooking/detours/detours.h +++ b/spotify-reverse/util/hooking/detours/detours.h @@ -1,11 +1,10 @@ #pragma once -#include "mh/minhook.h" #include "../../mem/addr.h" - +#include "mh/minhook.h" namespace util::hooking::detour { - bool init( ); - bool create( void* target, void* detour, void** orig ); - bool remove( void* target = nullptr /* nullptr = MH_ALL_HOOKS */ ); -} + bool init(); + bool create(void* target, void* detour, void** orig); + bool remove(void* target = nullptr /* nullptr = MH_ALL_HOOKS */); +} // namespace util::hooking::detour diff --git a/spotify-reverse/util/hooking/hooking.h b/spotify-reverse/util/hooking/hooking.h index fd4fb47..d500b26 100644 --- a/spotify-reverse/util/hooking/hooking.h +++ b/spotify-reverse/util/hooking/hooking.h @@ -1,3 +1,3 @@ #pragma once -#include "vmt/vmt.h" #include "detours/detours.h" +#include "vmt/vmt.h" diff --git a/spotify-reverse/util/hooking/vmt/vmt.cpp b/spotify-reverse/util/hooking/vmt/vmt.cpp index 53372a4..0279f5c 100644 --- a/spotify-reverse/util/hooking/vmt/vmt.cpp +++ b/spotify-reverse/util/hooking/vmt/vmt.cpp @@ -1,57 +1,55 @@ #include "vmt.h" - namespace util::hooking { - namespace detail { - region_protector::region_protector( void* base, size_t len, std::uint32_t flags ) { - _base = base; - _length = len; - VirtualProtect( base, len, flags, ( PDWORD )&_old ); - } - region_protector::~region_protector( ) { - VirtualProtect( _base, _length, _old, ( PDWORD )&_old ); - } - } + namespace detail { + region_protector::region_protector(void* base, size_t len, std::uint32_t flags) { + _base = base; + _length = len; + VirtualProtect(base, len, flags, (PDWORD)&_old); + } + region_protector::~region_protector() { VirtualProtect(_base, _length, _old, (PDWORD)&_old); } + } // namespace detail - vmt::vmt( ) : class_base( nullptr ), vftbl_len( 0 ), new_vftbl( nullptr ), old_vftbl( nullptr ) {} - vmt::vmt( void* base ) : class_base( base ), vftbl_len( 0 ), new_vftbl( nullptr ), old_vftbl( nullptr ) {} - vmt::~vmt( ) { - unhook( ); - delete[ ] new_vftbl; - } + vmt::vmt() : class_base(nullptr), vftbl_len(0), new_vftbl(nullptr), old_vftbl(nullptr) { } + vmt::vmt(void* base) : class_base(base), vftbl_len(0), new_vftbl(nullptr), old_vftbl(nullptr) { } + vmt::~vmt() { + unhook(); + delete[] new_vftbl; + } - void vmt::setup( void* base ) { - if ( base != nullptr ) - class_base = base; + void vmt::setup(void* base) { + if (base != nullptr) + class_base = base; - old_vftbl = *reinterpret_cast< std::uintptr_t** >( class_base ); - vftbl_len = estimate_vftbl_length( old_vftbl ) * sizeof( std::uintptr_t ); + old_vftbl = *reinterpret_cast(class_base); + vftbl_len = estimate_vftbl_length(old_vftbl) * sizeof(std::uintptr_t); - new_vftbl = new std::uintptr_t[ vftbl_len + 1 ]( ); + new_vftbl = new std::uintptr_t[vftbl_len + 1](); - std::memcpy( &new_vftbl[ 1 ], old_vftbl, vftbl_len * sizeof( std::uintptr_t ) ); + std::memcpy(&new_vftbl[1], old_vftbl, vftbl_len * sizeof(std::uintptr_t)); - auto guard = detail::region_protector { class_base, sizeof( std::uintptr_t ), PAGE_READWRITE }; - new_vftbl[ 0 ] = old_vftbl[ -1 ]; - *reinterpret_cast< std::uintptr_t** >( class_base ) = &new_vftbl[ 1 ]; - } + auto guard = detail::region_protector { class_base, sizeof(std::uintptr_t), PAGE_READWRITE }; + new_vftbl[0] = old_vftbl[-1]; + *reinterpret_cast(class_base) = &new_vftbl[1]; + } - std::size_t vmt::estimate_vftbl_length( std::uintptr_t* vftbl_start ) { - MEMORY_BASIC_INFORMATION memInfo = { NULL }; - int m_nSize = -1; - do { - m_nSize++; - VirtualQuery( reinterpret_cast< LPCVOID >( vftbl_start[ m_nSize ] ), &memInfo, sizeof( memInfo ) ); - } while ( memInfo.Protect == PAGE_EXECUTE_READ || memInfo.Protect == PAGE_EXECUTE_READWRITE ); + std::size_t vmt::estimate_vftbl_length(std::uintptr_t* vftbl_start) { + MEMORY_BASIC_INFORMATION memInfo = { NULL }; + int m_nSize = -1; + do { + m_nSize++; + VirtualQuery(reinterpret_cast(vftbl_start[m_nSize]), &memInfo, sizeof(memInfo)); + } while (memInfo.Protect == PAGE_EXECUTE_READ || memInfo.Protect == PAGE_EXECUTE_READWRITE); - return m_nSize; - } + return m_nSize; + } - void vmt::unhook( ) { - if ( old_vftbl == nullptr ) return; + void vmt::unhook() { + if (old_vftbl == nullptr) + return; - auto guard = detail::region_protector { class_base, sizeof( std::uintptr_t ), PAGE_READWRITE }; - *reinterpret_cast< std::uintptr_t** >( class_base ) = old_vftbl; - old_vftbl = nullptr; - } -} + auto guard = detail::region_protector { class_base, sizeof(std::uintptr_t), PAGE_READWRITE }; + *reinterpret_cast(class_base) = old_vftbl; + old_vftbl = nullptr; + } +} // namespace util::hooking diff --git a/spotify-reverse/util/hooking/vmt/vmt.h b/spotify-reverse/util/hooking/vmt/vmt.h index 91f7624..111cd65 100644 --- a/spotify-reverse/util/hooking/vmt/vmt.h +++ b/spotify-reverse/util/hooking/vmt/vmt.h @@ -4,47 +4,46 @@ #include #include - namespace util::hooking { - namespace detail { - class region_protector { - public: - region_protector( void* base, size_t len, std::uint32_t flags ); - ~region_protector( ); + namespace detail { + class region_protector { + public: + region_protector(void* base, size_t len, std::uint32_t flags); + ~region_protector(); - private: - void* _base; - size_t _length; - std::uint32_t _old; - }; - } + private: + void* _base; + size_t _length; + std::uint32_t _old; + }; + } // namespace detail - class vmt { - public: - vmt( ); - vmt( void* base ); - ~vmt( ); + class vmt { + public: + vmt(); + vmt(void* base); + ~vmt(); - void setup( void* base = nullptr ); + void setup(void* base = nullptr); - template - void hook( int index, T fun ) { - new_vftbl[ index + 1 ] = reinterpret_cast< std::uintptr_t >( fun ); - } + template + void hook(int index, T fun) { + new_vftbl[index + 1] = reinterpret_cast(fun); + } - void unhook( ); + void unhook(); - template - T original( int index ) { - return reinterpret_cast< T >( old_vftbl[ index ] ); - } + template + T original(int index) { + return reinterpret_cast(old_vftbl[index]); + } - private: - static inline std::size_t estimate_vftbl_length( std::uintptr_t* vftbl_start ); + private: + static inline std::size_t estimate_vftbl_length(std::uintptr_t* vftbl_start); - void* class_base; - std::size_t vftbl_len; - std::uintptr_t* new_vftbl; - std::uintptr_t* old_vftbl; - }; -} + void* class_base; + std::size_t vftbl_len; + std::uintptr_t* new_vftbl; + std::uintptr_t* old_vftbl; + }; +} // namespace util::hooking diff --git a/spotify-reverse/util/mem/addr.h b/spotify-reverse/util/mem/addr.h index 8682bce..ce4aba7 100644 --- a/spotify-reverse/util/mem/addr.h +++ b/spotify-reverse/util/mem/addr.h @@ -1,123 +1,114 @@ #pragma once #include - namespace util::mem { - template< typename ptr_type = std::uintptr_t > - struct memory_address_t { - public: - // - // constructors etc... - memory_address_t( ) : m_ptr( ptr_type( 0 ) ) { }; - memory_address_t( ptr_type v ) : m_ptr( v ) { }; - memory_address_t( void* v ) : m_ptr( ptr_type( v ) ) { }; - memory_address_t( const void* v ) : m_ptr( ptr_type( v ) ) { }; - ~memory_address_t( ) = default; + template + struct memory_address_t { + public: + // + // constructors etc... + memory_address_t() : m_ptr(ptr_type(0)) {}; + memory_address_t(ptr_type v) : m_ptr(v) {}; + memory_address_t(void* v) : m_ptr(ptr_type(v)) {}; + memory_address_t(const void* v) : m_ptr(ptr_type(v)) {}; + ~memory_address_t() = default; - // - // operators - inline operator ptr_type( ) { - return m_ptr; - } + // + // operators + inline operator ptr_type() { return m_ptr; } - inline operator void* ( ) { - return reinterpret_cast< void* >( m_ptr ); - } + inline operator void*() { return reinterpret_cast(m_ptr); } - inline memory_address_t& operator+=( ptr_type offset ) { - m_ptr += offset; - return *this; - } + inline memory_address_t& operator+=(ptr_type offset) { + m_ptr += offset; + return *this; + } - inline memory_address_t& operator-=( ptr_type offset ) { - m_ptr -= offset; - return *this; - } + inline memory_address_t& operator-=(ptr_type offset) { + m_ptr -= offset; + return *this; + } - inline memory_address_t operator-( ptr_type offset ) { - return memory_address_t( m_ptr - offset ); - } + inline memory_address_t operator-(ptr_type offset) { return memory_address_t(m_ptr - offset); } - inline memory_address_t operator+( ptr_type offset ) { - return add( offset ); - } + inline memory_address_t operator+(ptr_type offset) { return add(offset); } - inline bool operator>( ptr_type v2 ) { - return m_ptr > v2; - } + inline bool operator>(ptr_type v2) { return m_ptr > v2; } - inline bool operator>=( ptr_type v2 ) { - return m_ptr >= v2; - } + inline bool operator>=(ptr_type v2) { return m_ptr >= v2; } - inline bool operator<( ptr_type v2 ) { - return m_ptr < v2; - } + inline bool operator<(ptr_type v2) { return m_ptr < v2; } - inline bool operator<=( ptr_type v2 ) { - return m_ptr <= v2; - } + inline bool operator<=(ptr_type v2) { return m_ptr <= v2; } - inline memory_address_t add( ptr_type offset ) { - return memory_address_t( m_ptr + offset ); - } + inline memory_address_t add(ptr_type offset) { return memory_address_t(m_ptr + offset); } - template - inline memory_address_t rel( ptr_type offset ) { - return this->add( this->add( offset ).template read( ) ).add( offset + sizeof( t ) ); - } + template + inline memory_address_t rel(ptr_type offset) { + return this->add(this->add(offset).template read()).add(offset + sizeof(t)); + } - // - // utils - memory_address_t offset( ptr_type off ) { return memory_address_t( m_ptr + off ); } + // + // utils + memory_address_t offset(ptr_type off) { return memory_address_t(m_ptr + off); } - template - T read( ) { return *ptr( ); } + template + T read() { + return *ptr(); + } - template - T* read_ptr( ) { return read( ); } + template + T* read_ptr() { + return read(); + } - template - void write( T value ) { *ptr( ) = value; } + template + void write(T value) { + *ptr() = value; + } - template - T* ptr( ) { return reinterpret_cast< T* >( m_ptr ); } + template + T* ptr() { + return reinterpret_cast(m_ptr); + } - template - T cast( ) { return reinterpret_cast< T >( m_ptr ); } + template + T cast() { + return reinterpret_cast(m_ptr); + } - memory_address_t& self_get( ptr_type count = 1 ) { - for ( ptr_type i = 0; i < count; i++ ) - m_ptr = *reinterpret_cast< ptr_type* >( m_ptr ); - return *this; - } + memory_address_t& self_get(ptr_type count = 1) { + for (ptr_type i = 0; i < count; i++) + m_ptr = *reinterpret_cast(m_ptr); + return *this; + } - memory_address_t walk_until( uint8_t byte ) { - constexpr int max_iterations = 1000; - for ( int i = 0; i < max_iterations; i++ ) { - if ( offset( i ).template read( ) != byte ) - continue; - return offset( i ); - } - return memory_address_t( ); - } + memory_address_t walk_until(uint8_t byte) { + constexpr int max_iterations = 1000; + for (int i = 0; i < max_iterations; i++) { + if (offset(i).template read() != byte) + continue; + return offset(i); + } + return memory_address_t(); + } - memory_address_t walk_back_until( uint8_t byte ) { - constexpr int max_iterations = 1000; - for ( int i = 1; i < max_iterations; i++ ) { - if ( offset( -i ).template read( ) != byte ) - continue; - return offset( -i ); - } - return memory_address_t( ); - } + memory_address_t walk_back_until(uint8_t byte) { + constexpr int max_iterations = 1000; + for (int i = 1; i < max_iterations; i++) { + if (offset(-i).template read() != byte) + continue; + return offset(-i); + } + return memory_address_t(); + } - inline bool valid( ) { return static_cast< bool >( m_ptr ) && m_ptr > 15; } + inline bool valid() { return static_cast(m_ptr) && m_ptr > 15; } - ptr_type raw( ) { return m_ptr; } + ptr_type raw() { return m_ptr; } - private: - ptr_type m_ptr; - }; - using addr_t = mem::memory_address_t< std::uintptr_t >; -} \ No newline at end of file + private: + ptr_type m_ptr; + }; + using addr_t = mem::memory_address_t; +} // namespace util::mem \ No newline at end of file diff --git a/spotify-reverse/util/mem/module.h b/spotify-reverse/util/mem/module.h index bed09a0..f7c5800 100644 --- a/spotify-reverse/util/mem/module.h +++ b/spotify-reverse/util/mem/module.h @@ -1,94 +1,86 @@ #pragma once -#include -#include -#include #include "../mem/addr.h" - +#include +#include +#include namespace util::mem { - struct module_t { - public: - // - // constructors, etc... - module_t( ) : m_addr( ) { }; - module_t( uintptr_t s ) : m_addr( s ) { }; - module_t( const char* module_name ) : m_addr( GetModuleHandleA( module_name ) ) { }; - ~module_t( ) = default; + struct module_t { + public: + // + // constructors, etc... + module_t() : m_addr() {}; + module_t(uintptr_t s) : m_addr(s) {}; + module_t(const char* module_name) : m_addr(GetModuleHandleA(module_name)) {}; + ~module_t() = default; - public: - // - // exports related - mem::addr_t get_export( const char* name ) { - return mem::addr_t( reinterpret_cast< void* >( GetProcAddress( m_addr.cast( ), name ) ) ); - } + public: + // + // exports related + mem::addr_t get_export(const char* name) { return mem::addr_t(reinterpret_cast(GetProcAddress(m_addr.cast(), name))); } - // - // pattern scan related - public: - mem::addr_t sig( std::string_view pattern ) { - return sig( pattern_to_byte( pattern ) ); - } + // + // pattern scan related + public: + mem::addr_t sig(std::string_view pattern) { return sig(pattern_to_byte(pattern)); } - mem::addr_t sig( std::vector pattern_bytes ) { - unsigned long image_size = get_nt_headers( )->OptionalHeader.SizeOfImage; - int* pattern_data = pattern_bytes.data( ); - size_t pattern_size = pattern_bytes.size( ); + mem::addr_t sig(std::vector pattern_bytes) { + unsigned long image_size = get_nt_headers()->OptionalHeader.SizeOfImage; + int* pattern_data = pattern_bytes.data(); + size_t pattern_size = pattern_bytes.size(); - for ( unsigned long i = 0ul; i < image_size - pattern_size; i++ ) { - bool found = true; + for (unsigned long i = 0ul; i < image_size - pattern_size; i++) { + bool found = true; - for ( unsigned long j = 0ul; j < pattern_size; j++ ) { - if ( pattern_data[ j ] == -1 ) - continue; - if ( m_addr.offset( i + j ).read( ) == pattern_data[ j ] ) - continue; + for (unsigned long j = 0ul; j < pattern_size; j++) { + if (pattern_data[j] == -1) + continue; + if (m_addr.offset(i + j).read() == pattern_data[j]) + continue; - found = false; - break; - } + found = false; + break; + } - if ( !found ) - continue; + if (!found) + continue; - return m_addr.offset( i ); - } + return m_addr.offset(i); + } - return mem::addr_t( ); - } - public: - bool safe( std::uintptr_t ptr ) { - return ptr >= m_addr && ptr <= m_addr.add( get_nt_headers( )->OptionalHeader.SizeOfImage ); - } - public: - IMAGE_DOS_HEADER* get_dos_headers( ) { - return m_addr.ptr( ); - } + return mem::addr_t(); + } - IMAGE_NT_HEADERS* get_nt_headers( ) { - return m_addr.offset( get_dos_headers( )->e_lfanew ).ptr< IMAGE_NT_HEADERS >( ); - } - protected: - std::vector< int > pattern_to_byte( std::string_view pattern ) { - auto bytes = std::vector {}; - auto start = const_cast< char* >( pattern.data( ) ); - auto end = const_cast< char* >( start ) + pattern.length( ); + public: + bool safe(std::uintptr_t ptr) { return ptr >= m_addr && ptr <= m_addr.add(get_nt_headers()->OptionalHeader.SizeOfImage); } - for ( auto current = start; current < end; ++current ) { - if ( *current == '?' ) { - ++current; + public: + IMAGE_DOS_HEADER* get_dos_headers() { return m_addr.ptr(); } - if ( *current == '?' ) - ++current; + IMAGE_NT_HEADERS* get_nt_headers() { return m_addr.offset(get_dos_headers()->e_lfanew).ptr(); } - bytes.emplace_back( -1 ); - } else - bytes.emplace_back( strtoul( current, ¤t, 16 ) ); - } - return bytes; - } + protected: + std::vector pattern_to_byte(std::string_view pattern) { + auto bytes = std::vector {}; + auto start = const_cast(pattern.data()); + auto end = const_cast(start) + pattern.length(); - private: - mem::addr_t m_addr; - }; -} + for (auto current = start; current < end; ++current) { + if (*current == '?') { + ++current; + + if (*current == '?') + ++current; + + bytes.emplace_back(-1); + } else + bytes.emplace_back(strtoul(current, ¤t, 16)); + } + return bytes; + } + + private: + mem::addr_t m_addr; + }; +} // namespace util::mem diff --git a/spotify-reverse/util/networking/networking.cpp b/spotify-reverse/util/networking/networking.cpp index 8b34b96..8ab7637 100644 --- a/spotify-reverse/util/networking/networking.cpp +++ b/spotify-reverse/util/networking/networking.cpp @@ -1,48 +1,45 @@ #include "networking.h" - namespace util { - namespace networking { - errorable_json_result get( const char* domain, const char* url ) { - std::string response_data = err_json_data; + namespace networking { + errorable_json_result get(const char* domain, const char* url) { + std::string response_data = err_json_data; - auto internet_session = InternetOpenA( "Unspotify/1.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 ); + auto internet_session = InternetOpenA("Unspotify/1.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); - if ( !internet_session ) - return { nlohmann::json::parse( response_data ), true }; + if (!internet_session) + return { nlohmann::json::parse(response_data), true }; - auto http_session = InternetConnectA( internet_session, domain, 80, 0, 0, INTERNET_SERVICE_HTTP, 0, NULL ); + auto http_session = InternetConnectA(internet_session, domain, 80, 0, 0, INTERNET_SERVICE_HTTP, 0, NULL); - if ( !http_session ) - return { nlohmann::json::parse( response_data ), true }; + if (!http_session) + return { nlohmann::json::parse(response_data), true }; - HINTERNET http_req = HttpOpenRequestA( http_session, "GET", url, 0, 0, 0, INTERNET_FLAG_RELOAD, 0 ); + HINTERNET http_req = HttpOpenRequestA(http_session, "GET", url, 0, 0, 0, INTERNET_FLAG_RELOAD, 0); - if ( !http_session ) - return nlohmann::json::parse( response_data ); + if (!http_session) + return nlohmann::json::parse(response_data); - const char* szHeaders = "Content-Type: application/json\r\nUser-Agent: Unspotify/1.0"; + const char* szHeaders = "Content-Type: application/json\r\nUser-Agent: Unspotify/1.0"; - if ( !HttpSendRequestA( http_req, szHeaders, strlen( szHeaders ), NULL, NULL ) ) - return { response_data, true }; + if (!HttpSendRequestA(http_req, szHeaders, strlen(szHeaders), NULL, NULL)) + return { response_data, true }; - response_data.clear( ); + response_data.clear(); - CHAR temp_buffer[ 1024 ] = { 0 }; - DWORD read_ret = 0; + CHAR temp_buffer[1024] = { 0 }; + DWORD read_ret = 0; - while ( InternetReadFile( http_req, temp_buffer, sizeof( temp_buffer ) - 1, &read_ret ) && read_ret ) - response_data.append( temp_buffer, read_ret ); + while (InternetReadFile(http_req, temp_buffer, sizeof(temp_buffer) - 1, &read_ret) && read_ret) + response_data.append(temp_buffer, read_ret); - InternetCloseHandle( http_req ); - InternetCloseHandle( http_session ); - InternetCloseHandle( internet_session ); - - try { - return { nlohmann::json::parse( response_data ), false }; - } catch ( const nlohmann::json::parse_error& er ) { - return { nlohmann::json::parse( err_json_data ), true }; - } - } - } -} + InternetCloseHandle(http_req); + InternetCloseHandle(http_session); + InternetCloseHandle(internet_session); + + try { + return { nlohmann::json::parse(response_data), false }; + } catch (const nlohmann::json::parse_error& er) { return { nlohmann::json::parse(err_json_data), true }; } + } + } // namespace networking +} // namespace util diff --git a/spotify-reverse/util/networking/networking.h b/spotify-reverse/util/networking/networking.h index 6ef53d1..b15291c 100644 --- a/spotify-reverse/util/networking/networking.h +++ b/spotify-reverse/util/networking/networking.h @@ -1,7 +1,9 @@ #pragma once +// clang-format off #include -#include #include +#include +// clang-format on #include #include "ext/json.hpp" @@ -9,12 +11,11 @@ #pragma comment(lib, "urlmon.lib") #pragma comment(lib, "wininet.lib") - namespace util { - namespace networking { - using errorable_json_result = std::pair; - constexpr const char* err_json_data = "{\"error\": \"Unable to connect to server\"}"; + namespace networking { + using errorable_json_result = std::pair; + constexpr const char* err_json_data = "{\"error\": \"Unable to connect to server\"}"; - errorable_json_result get( const char* domain, const char* url ); - } -} + errorable_json_result get(const char* domain, const char* url); + } // namespace networking +} // namespace util diff --git a/spotify-reverse/util/util.h b/spotify-reverse/util/util.h index b6a773c..a31db36 100644 --- a/spotify-reverse/util/util.h +++ b/spotify-reverse/util/util.h @@ -1,9 +1,7 @@ #pragma once #include "hooking/hooking.h" -#include "shared/logger.h" #include "mem/addr.h" #include "mem/module.h" +#include "shared/logger.h" - -namespace util {} - +namespace util { }