- Added discord url to banner
- Added exception handler
- Fixed crashes in autoupdater
This commit is contained in:
Arsenii Esenin 2022-01-09 19:31:02 +01:00
parent a762348351
commit 253cb64798
13 changed files with 99 additions and 41 deletions

View File

@ -2,6 +2,10 @@
#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( ) {
@ -16,8 +20,9 @@ namespace util {
util::logger::info( " 88P' )88" );
util::logger::info( " d88 ,d8P" );
util::logger::info( " ?8P `?888P " );
util::logger::info( " by es3n.in | compiled at %s %s", __DATE__, __TIME__ );
util::logger::info( " git: https://git.tcp.direct/dg/Unspotify" );
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( "" );
}

View File

@ -3,6 +3,7 @@
#include "../spotify/spotify.h"
#include "../hooks/hooks.h"
#include "../updates/updates.h"
#include "../exceptions/exceptions.h"
#include "shared/logo.h"
#include <thread>
@ -12,6 +13,8 @@ namespace bootstrap {
DWORD __stdcall _initial_routine( HANDLE ) {
util::logo::create_console_and_draw_logo( );
exceptions::subscribe( );
#ifdef CHECK_FOR_UPDATES
updates::do_job( );
#endif
@ -36,13 +39,14 @@ namespace bootstrap {
}
bool startup( HINSTANCE dll_handle ) {
_::dll_handle = 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 >( _::dll_handle ), 0x1 );
FreeLibraryAndExitThread( reinterpret_cast< HMODULE >( detail::dll_handle ), 0x1 );
}
}

View File

@ -3,8 +3,9 @@
namespace bootstrap {
namespace _ {
namespace detail {
inline HINSTANCE dll_handle;
inline DWORD region_size;
}
DWORD __stdcall _initial_routine( HANDLE );

View File

@ -3,7 +3,7 @@
// autoupdates
// @note: es3n1n: v1.0.5 = 105
#define UNSPOTIFY_VERSION 105
#define UNSPOTIFY_VERSION 106
#define AUTOUPDATER_DOMAIN "es3n.in"
#define AUTOUPDATER_URL "unspotify.json"

View File

@ -0,0 +1,42 @@
#include "exceptions.h"
#include "../bootstrap/bootstrap.h"
#include "shared/logger.h"
#include <string>
#include <sstream>
#include <iostream>
namespace exceptions {
LONG __stdcall handler( EXCEPTION_POINTERS* info ) {
static bool logged { false };
if ( logged )
return EXCEPTION_CONTINUE_SEARCH; // @note: es3n1n: log exceptions only once
auto exc_addr = reinterpret_cast< uintptr_t >( 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
}
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( ) );
logged = true;
return EXCEPTION_EXECUTE_HANDLER;
}
void subscribe( ) {
AddVectoredExceptionHandler( 1, handler );
}
}

View File

@ -0,0 +1,9 @@
#pragma once
#include <cstdint>
#include <Windows.h>
namespace exceptions {
LONG __stdcall handler( EXCEPTION_POINTERS* info );
void subscribe( );
}

View File

@ -1,24 +0,0 @@
#include "../hooks.h"
namespace hooks {
namespace hooked {
/*
@note: es3n1n:
First of all find xref "Creating track player for track", then at the end
there would be a call to a function with 13 params, this is it ;)
*/
std::uintptr_t __fastcall play_track(
std::uintptr_t pthis,
std::uintptr_t pEDX,
spotify::structs::player_meta_t* player_meta,
spotify::structs::player_track_meta_t* track_meta,
char a4, int a5, char a6, int a7, int a8, char a9, char a10, int a11, char a12, int a13
) {
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" );
return original::play_track( pthis, pEDX, player_meta, track_meta, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13 );
}
}
}

View File

@ -109,6 +109,7 @@
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalOptions>-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)</AdditionalOptions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -149,6 +150,7 @@
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<AdditionalOptions>-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)</AdditionalOptions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -181,6 +183,7 @@
<ItemGroup>
<ClCompile Include="bootstrap\bootstrap.cpp" />
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="exceptions\exceptions.cpp" />
<ClCompile Include="hooks\hooked\debug_msg.cpp" />
<ClCompile Include="hooks\hooked\get_ad.cpp" />
<ClCompile Include="hooks\hooked\create_track.cpp" />
@ -199,6 +202,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="bootstrap\bootstrap.h" />
<ClInclude Include="exceptions\exceptions.h" />
<ClInclude Include="hooks\hooks.h" />
<ClInclude Include="spotify\spotify.h" />
<ClInclude Include="updates\updates.h" />

View File

@ -66,6 +66,9 @@
<ClCompile Include="updates\updates.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="exceptions\exceptions.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="util\util.h">
@ -128,5 +131,8 @@
<ClInclude Include="updates\updates.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="exceptions\exceptions.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -8,7 +8,7 @@ namespace updates {
return update_info_t {
.m_error = true,
.m_error_desc = data[ "error" ].get<std::string>( )
};
};
return update_info_t {
.m_error = false,

View File

@ -12,6 +12,7 @@ namespace util::mem {
//
// 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;
@ -59,7 +60,7 @@ namespace util::mem {
bool safe( std::uintptr_t ptr ) {
return ptr >= m_addr && ptr <= m_addr.add( get_nt_headers( )->OptionalHeader.SizeOfImage );
}
protected:
public:
IMAGE_DOS_HEADER* get_dos_headers( ) {
return m_addr.ptr<IMAGE_DOS_HEADER>( );
}

View File

@ -4,23 +4,27 @@
namespace util {
namespace networking {
nlohmann::json get( const char* domain, const char* url ) {
std::string response_data = "{\"error\": \"Unable to connect to server\"}";
std::string response_data = err_json_data;
auto internet_session = InternetOpenA( "", 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 );
if ( !internet_session )
return nlohmann::json::parse( response_data );
auto http_session = InternetConnectA( internet_session, domain, 80, 0, 0, INTERNET_SERVICE_HTTP, 0, NULL );
if ( !http_session ) return nlohmann::json::parse( response_data );
if ( !http_session )
return nlohmann::json::parse( response_data );
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: text/html\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;
if ( !HttpSendRequestA( http_req, szHeaders, strlen( szHeaders ), NULL, NULL ) )
return response_data;
response_data.clear( );
@ -33,8 +37,12 @@ namespace util {
InternetCloseHandle( http_req );
InternetCloseHandle( http_session );
InternetCloseHandle( internet_session );
return nlohmann::json::parse( response_data );
try {
return nlohmann::json::parse( response_data );
} catch ( const nlohmann::json::parse_error& er ) {
return nlohmann::json::parse( err_json_data );
}
}
}
}

View File

@ -11,6 +11,8 @@
namespace util {
namespace networking {
constexpr const char* err_json_data = "{\"error\": \"Unable to connect to server\"}";
nlohmann::json get( const char* domain, const char* url );
}
}