Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
es3n1n | 506e1b7c87 | ||
es3n1n | 5243685a90 | ||
Arsenii es3n1n | e858bf3afc |
129
.clang-format
129
.clang-format
|
@ -1,31 +1,110 @@
|
|||
# es3n1n's clang-format, last upd 19 jun 22 17:50:03
|
||||
|
||||
BasedOnStyle: WebKit
|
||||
|
||||
Language: Cpp
|
||||
|
||||
# es3n1n's clang-format, last upd 13 aug 2022 23:07:09
|
||||
---
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments: false
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AllowShortEnumsOnASingleLine: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: Empty
|
||||
AllowShortCaseLabelsOnASingleLine: 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
|
||||
AllowShortEnumsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
|
||||
BasedOnStyle: WebKit
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BitFieldColonSpacing: None
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakBeforeConceptDeclarations: false
|
||||
BreakBeforeTernaryOperators: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 155
|
||||
CommentPragmas: true
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth : 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DeriveLineEnding: true
|
||||
DerivePointerAlignment: false
|
||||
EmptyLineBeforeAccessModifier: Never
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
IncludeBlocks: Preserve
|
||||
IndentCaseBlocks: false
|
||||
IndentCaseLabels: false
|
||||
IndentExternBlock: Indent
|
||||
IndentGotoLabels: false
|
||||
IndentPPDirectives: BeforeHash
|
||||
IndentRequires: false
|
||||
IndentWrappedFunctionNames: false
|
||||
InsertTrailingCommas: None
|
||||
Language: Cpp
|
||||
NamespaceIndentation: All
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyIndentedWhitespace: 0
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerAlignment: Left
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: false
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceBeforeSquareBrackets: false
|
||||
SpaceInEmptyBlock: true
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Latest
|
||||
TabWidth: 8
|
||||
UseCRLF: false
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<PlatformToolset>ClangCL</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<LLVMToolsVersion>13.0.1</LLVMToolsVersion>
|
||||
<LLVMToolsVersion>15.0.1</LLVMToolsVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
@ -96,7 +96,7 @@
|
|||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalOptions>/MAP /MERGE:.voltbl=.data /MERGE:.retplne=.data /MERGE:.gehcont=.data /MERGE:.00cfg=.data /MERGE:_RDATA=.rdata /FORCE:UNRESOLVED %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalOptions>/MAP /MERGE:.voltbl=.data /MERGE:.retplne=.data /MERGE:.gehcont=.data /MERGE:.00cfg=.data /MERGE:_RDATA=.rdata /FORCE:UNRESOLVED /pdbaltpath:%_PDB% %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
|
|
|
@ -2,22 +2,23 @@
|
|||
#include <Windows.h>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <stdio.h>
|
||||
|
||||
#define L_ERROR(...) util::logger::error(__FUNCTION__ "(): " __VA_ARGS__);
|
||||
#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); \
|
||||
#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 CREATE_LOGGER_METHOD(n) \
|
||||
inline void n(const char* fmt, ...) { \
|
||||
LOGGER_PARSE_FMT; \
|
||||
log(#n, e_level_color::level_color_##n, buf); \
|
||||
}
|
||||
|
||||
namespace util {
|
||||
|
@ -45,7 +46,9 @@ namespace util {
|
|||
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<uint32_t>(e_level_color::level_color_none));
|
||||
}
|
||||
|
||||
inline void colorify(uint32_t clr, std::function<void()> cb) {
|
||||
apply(clr);
|
||||
|
@ -54,7 +57,13 @@ namespace util {
|
|||
}
|
||||
} // namespace _colors
|
||||
|
||||
namespace {
|
||||
inline std::mutex _mtx;
|
||||
}
|
||||
|
||||
inline void log(const char* prefix, e_level_color level, const char* message) {
|
||||
std::lock_guard<std::mutex> _lock(_mtx);
|
||||
|
||||
_colors::colorify(static_cast<uint32_t>(level), [prefix]() -> void { printf("%s >> ", prefix); });
|
||||
|
||||
printf("%s\n", message);
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#include "bootstrap.h"
|
||||
#include "../exceptions/exceptions.h"
|
||||
#include "../hooks/hooks.h"
|
||||
#include "../spotify/spotify.h"
|
||||
#include "../updates/updates.h"
|
||||
#include "../util/util.h"
|
||||
#include "exceptions/exceptions.h"
|
||||
#include "hooks/hooks.h"
|
||||
#include "shared/logo.h"
|
||||
#include "spotify/spotify.h"
|
||||
#include "updates/updates.h"
|
||||
#include "util/util.h"
|
||||
|
||||
#include <thread>
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
// autoupdates
|
||||
|
||||
// @note: es3n1n: v1.0.8 = 108
|
||||
#define UNSPOTIFY_VERSION 108
|
||||
// @note: es3n1n: v1.1.1 = 111
|
||||
#define UNSPOTIFY_VERSION 111
|
||||
|
||||
#define AUTOUPDATER_DOMAIN "es3n.in"
|
||||
#define AUTOUPDATER_URL "unspotify.json"
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
#include "exceptions.h"
|
||||
#include "../bootstrap/bootstrap.h"
|
||||
#include "shared/logger.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "bootstrap/bootstrap.h"
|
||||
#include "exceptions/exceptions.h"
|
||||
#include "shared/logger.h"
|
||||
|
||||
namespace exceptions {
|
||||
LONG __stdcall handler(EXCEPTION_POINTERS* info) {
|
||||
static bool logged { false };
|
||||
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))) {
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -28,6 +29,7 @@ namespace exceptions {
|
|||
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;
|
||||
log_msg << std::endl << "PLEASE PRESS CTRL+C AND REPORT THIS ERROR IN OUR DISCORD" << std::endl;
|
||||
|
||||
util::logger::fatal(log_msg.str().c_str());
|
||||
|
||||
|
@ -35,5 +37,7 @@ namespace exceptions {
|
|||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
||||
void subscribe() { AddVectoredExceptionHandler(1, handler); }
|
||||
void subscribe() {
|
||||
AddVectoredExceptionHandler(1, handler);
|
||||
}
|
||||
} // namespace exceptions
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
#include "../hooks.h"
|
||||
#include "hooks/hooks.h"
|
||||
|
||||
namespace hooks {
|
||||
namespace hooked {
|
||||
/*
|
||||
@xref: " Creating track player for track (playback_id %s)"
|
||||
*/
|
||||
@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) {
|
||||
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);
|
||||
}
|
||||
} // namespace hooked
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#include "../hooks.h"
|
||||
#include "hooks/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."
|
||||
const char* fmt, ...) { // @xref: "Path provided in --%s '%s' (resolved to '%s') does not exist."
|
||||
LOGGER_PARSE_FMT;
|
||||
|
||||
for (std::size_t i = 0; i < strlen(buf); i++)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "../hooks.h"
|
||||
#include "hooks/hooks.h"
|
||||
|
||||
namespace hooks {
|
||||
namespace hooked {
|
||||
|
|
|
@ -1,23 +1,25 @@
|
|||
#include "hooks.h"
|
||||
|
||||
#define CREATE_HOOK(n) \
|
||||
if (!util::hooking::detour::create(spotify::addr::##n, hooked::##n, reinterpret_cast<void**>(&original::##n))) \
|
||||
#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);
|
||||
|
||||
namespace hooks {
|
||||
void init() {
|
||||
if (!util::hooking::detour::init())
|
||||
util::logger::fatal("Unable to init minhook");
|
||||
#pragma warning(disable : 5103)
|
||||
#pragma warning(disable:5103)
|
||||
#ifdef _DEBUG
|
||||
CREATE_HOOK(debug_msg);
|
||||
#endif
|
||||
CREATE_HOOK(get_ad);
|
||||
CREATE_HOOK(create_track);
|
||||
#pragma warning(default : 5103)
|
||||
#pragma warning(default:5103)
|
||||
}
|
||||
|
||||
void shutdown() { util::hooking::detour::remove(); }
|
||||
void shutdown() {
|
||||
util::hooking::detour::remove();
|
||||
}
|
||||
} // namespace hooks
|
||||
|
||||
#undef CREATE_HOOK
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
#pragma once
|
||||
#include "../spotify/spotify.h"
|
||||
#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, ...);
|
||||
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);
|
||||
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
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>ClangCL</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<LLVMToolsVersion>13.0.1</LLVMToolsVersion>
|
||||
</PropertyGroup>
|
||||
|
@ -31,7 +31,7 @@
|
|||
<PlatformToolset>ClangCL</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<LLVMToolsVersion>13.0.1</LLVMToolsVersion>
|
||||
<LLVMToolsVersion>15.0.1</LLVMToolsVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
@ -70,14 +70,15 @@
|
|||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<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 </AdditionalOptions>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalOptions>/MAP /MERGE:.voltbl=.data /MERGE:.retplne=.data /MERGE:.gehcont=.data /MERGE:.00cfg=.data /MERGE:_RDATA=.rdata /FORCE:UNRESOLVED %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
|
@ -93,13 +94,14 @@
|
|||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<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 </AdditionalOptions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalOptions>/MAP /MERGE:.voltbl=.data /MERGE:.retplne=.data /MERGE:.gehcont=.data /MERGE:.00cfg=.data /MERGE:_RDATA=.rdata /FORCE:UNRESOLVED %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalOptions>/MAP /MERGE:.voltbl=.data /MERGE:.retplne=.data /MERGE:.gehcont=.data /MERGE:.00cfg=.data /MERGE:_RDATA=.rdata /FORCE:UNRESOLVED /pdbaltpath:%_PDB% %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
|
@ -118,7 +120,6 @@
|
|||
<ClCompile Include="util\hooking\detours\mh\hde\hde64.c" />
|
||||
<ClCompile Include="util\hooking\detours\mh\hook.c" />
|
||||
<ClCompile Include="util\hooking\detours\mh\trampoline.c" />
|
||||
<ClCompile Include="util\hooking\vmt\vmt.cpp" />
|
||||
<ClCompile Include="util\networking\networking.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -137,7 +138,6 @@
|
|||
<ClInclude Include="util\hooking\detours\mh\minhook.h" />
|
||||
<ClInclude Include="util\hooking\detours\mh\trampoline.h" />
|
||||
<ClInclude Include="util\hooking\hooking.h" />
|
||||
<ClInclude Include="util\hooking\vmt\vmt.h" />
|
||||
<ClInclude Include="util\mem\addr.h" />
|
||||
<ClInclude Include="defines.h" />
|
||||
<ClInclude Include="util\mem\module.h" />
|
||||
|
|
|
@ -42,9 +42,6 @@
|
|||
<ClCompile Include="util\hooking\detours\detours.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="util\hooking\vmt\vmt.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="hooks\hooks.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
@ -107,9 +104,6 @@
|
|||
<ClInclude Include="util\hooking\detours\detours.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="util\hooking\vmt\vmt.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="util\hooking\hooking.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<ShowAllFiles>true</ShowAllFiles>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LocalDebuggerCommand>oSpotify.exe</LocalDebuggerCommand>
|
||||
<LocalDebuggerCommand>Spotify.exe</LocalDebuggerCommand>
|
||||
<LocalDebuggerAttach>true</LocalDebuggerAttach>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
#include "spotify.h"
|
||||
|
||||
#define ASSERT_PATTERN(s) \
|
||||
if (!addr::##s.valid()) \
|
||||
#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) \
|
||||
#define ASSERT_PATTERN_STEP(s) \
|
||||
if (!s) \
|
||||
util::logger::fatal("Unable to find %s at %d", #s, __LINE__)
|
||||
|
||||
namespace spotify {
|
||||
void init() {
|
||||
#pragma warning(disable : 5103)
|
||||
#pragma warning(disable:5103)
|
||||
TRACE_FN;
|
||||
|
||||
modules::spotify = util::mem::module_t(nullptr);
|
||||
|
@ -45,7 +45,7 @@ namespace spotify {
|
|||
ASSERT_PATTERN_STEP(sig);
|
||||
do {
|
||||
sig = sig.walk_back_until(0xC2 /* retn */);
|
||||
} while (sig.offset(-5).read<uint8_t>() != 0xE8 && sig.offset(-8).read<uint8_t>() != 0xE8);
|
||||
} while (sig.offset(-5).read<uint8_t>() != 0xE8 && sig.offset(-8).read<uint8_t>() != 0xE8 && sig.offset(-9).read<uint8_t>() != 0xE8);
|
||||
addr::get_ad = sig.add(1).read<uint8_t>() == 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);
|
||||
|
@ -67,7 +67,7 @@ namespace spotify {
|
|||
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)
|
||||
#pragma warning(default:5103)
|
||||
}
|
||||
} // namespace spotify
|
||||
|
||||
|
|
|
@ -1,20 +1,18 @@
|
|||
#pragma once
|
||||
#include "../util/util.h"
|
||||
#include "util/util.h"
|
||||
|
||||
namespace spotify {
|
||||
namespace structs {
|
||||
struct player_meta_t {
|
||||
private:
|
||||
char __pad[0x74];
|
||||
|
||||
public:
|
||||
std::uint32_t m_should_skip;
|
||||
};
|
||||
|
||||
struct player_track_meta_t {
|
||||
private:
|
||||
char __pad[0x48];
|
||||
|
||||
char __pad[0xB0];
|
||||
public:
|
||||
const char* m_track_uri;
|
||||
};
|
||||
|
|
|
@ -4,13 +4,13 @@ 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:" };
|
||||
return update_info_t{.m_error = true, .m_error_desc = "Internal server/app error :shrug:"};
|
||||
|
||||
return update_info_t { .m_error = false,
|
||||
.m_version = data["version"].get<uint32_t>(),
|
||||
.m_changelog = data["changelog"].get<std::string>(),
|
||||
.m_is_required = data["required"].get<bool>(),
|
||||
.m_download_url = data["download_url"].get<std::string>() };
|
||||
return update_info_t{.m_error = false,
|
||||
.m_version = data["version"].get<uint32_t>(),
|
||||
.m_changelog = data["changelog"].get<std::string>(),
|
||||
.m_is_required = data["required"].get<bool>(),
|
||||
.m_download_url = data["download_url"].get<std::string>()};
|
||||
}
|
||||
|
||||
void do_job() {
|
||||
|
@ -25,7 +25,7 @@ namespace updates {
|
|||
|
||||
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());
|
||||
update_info.m_download_url.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
#include "../defines.h"
|
||||
#include "../util/networking/networking.h"
|
||||
#include "defines.h"
|
||||
#include "shared/logger.h"
|
||||
#include "util/networking/networking.h"
|
||||
|
||||
namespace updates {
|
||||
struct update_info_t {
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
#include "detours.h"
|
||||
|
||||
namespace util::hooking::detour {
|
||||
bool init() { return !MH_Initialize(); }
|
||||
bool init() {
|
||||
return !MH_Initialize();
|
||||
}
|
||||
|
||||
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_STATUS::MH_OK; }
|
||||
bool remove(void* target) {
|
||||
return MH_DisableHook(target) == MH_STATUS::MH_OK;
|
||||
}
|
||||
} // namespace util::hooking::detour
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../mem/addr.h"
|
||||
#include "mh/minhook.h"
|
||||
#include "util/mem/addr.h"
|
||||
|
||||
namespace util::hooking::detour {
|
||||
bool init();
|
||||
|
|
|
@ -1,3 +1,2 @@
|
|||
#pragma once
|
||||
#include "detours/detours.h"
|
||||
#include "vmt/vmt.h"
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
#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
|
||||
|
||||
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;
|
||||
|
||||
old_vftbl = *reinterpret_cast<std::uintptr_t**>(class_base);
|
||||
vftbl_len = estimate_vftbl_length(old_vftbl) * sizeof(std::uintptr_t);
|
||||
|
||||
new_vftbl = new std::uintptr_t[vftbl_len + 1]();
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return m_nSize;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
} // namespace util::hooking
|
|
@ -1,49 +0,0 @@
|
|||
#pragma once
|
||||
#include "../../mem/addr.h"
|
||||
#include <Windows.h>
|
||||
#include <cstdint>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace util::hooking {
|
||||
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;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
class vmt {
|
||||
public:
|
||||
vmt();
|
||||
vmt(void* base);
|
||||
~vmt();
|
||||
|
||||
void setup(void* base = nullptr);
|
||||
|
||||
template <typename T>
|
||||
void hook(int index, T fun) {
|
||||
new_vftbl[index + 1] = reinterpret_cast<std::uintptr_t>(fun);
|
||||
}
|
||||
|
||||
void unhook();
|
||||
|
||||
template <typename T>
|
||||
T original(int index) {
|
||||
return reinterpret_cast<T>(old_vftbl[index]);
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
} // namespace util::hooking
|
|
@ -7,17 +7,21 @@ namespace util::mem {
|
|||
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(): 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; }
|
||||
inline operator ptr_type() {
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
inline operator void*() { return reinterpret_cast<void*>(m_ptr); }
|
||||
inline operator void*() {
|
||||
return reinterpret_cast<void*>(m_ptr);
|
||||
}
|
||||
|
||||
inline memory_address_t& operator+=(ptr_type offset) {
|
||||
m_ptr += offset;
|
||||
|
@ -29,19 +33,33 @@ namespace util::mem {
|
|||
return *this;
|
||||
}
|
||||
|
||||
inline memory_address_t operator-(ptr_type offset) { return memory_address_t<ptr_type>(m_ptr - offset); }
|
||||
inline memory_address_t operator-(ptr_type offset) {
|
||||
return memory_address_t<ptr_type>(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<ptr_type>(m_ptr + offset); }
|
||||
inline memory_address_t add(ptr_type offset) {
|
||||
return memory_address_t<ptr_type>(m_ptr + offset);
|
||||
}
|
||||
|
||||
template <typename t = uint32_t>
|
||||
inline memory_address_t rel(ptr_type offset) {
|
||||
|
@ -50,7 +68,9 @@ namespace util::mem {
|
|||
|
||||
//
|
||||
// utils
|
||||
memory_address_t<ptr_type> offset(ptr_type off) { return memory_address_t<ptr_type>(m_ptr + off); }
|
||||
memory_address_t<ptr_type> offset(ptr_type off) {
|
||||
return memory_address_t<ptr_type>(m_ptr + off);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T read() {
|
||||
|
@ -103,10 +123,13 @@ namespace util::mem {
|
|||
return memory_address_t<ptr_type>();
|
||||
}
|
||||
|
||||
inline bool valid() { return static_cast<bool>(m_ptr) && m_ptr > 15; }
|
||||
|
||||
ptr_type raw() { return m_ptr; }
|
||||
inline bool valid() {
|
||||
return static_cast<bool>(m_ptr) && m_ptr > 15;
|
||||
}
|
||||
|
||||
ptr_type raw() {
|
||||
return m_ptr;
|
||||
}
|
||||
private:
|
||||
ptr_type m_ptr;
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "../mem/addr.h"
|
||||
#include "util/mem/addr.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -10,20 +11,23 @@ namespace util::mem {
|
|||
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(): 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<HMODULE>(), name))); }
|
||||
mem::addr_t get_export(const char* name) {
|
||||
return mem::addr_t(reinterpret_cast<void*>(GetProcAddress(m_addr.cast<HMODULE>(), name)));
|
||||
}
|
||||
|
||||
//
|
||||
// pattern scan related
|
||||
public:
|
||||
mem::addr_t sig(std::string_view pattern) { return sig(pattern_to_byte(pattern)); }
|
||||
mem::addr_t sig(std::string_view pattern) {
|
||||
return sig(pattern_to_byte(pattern));
|
||||
}
|
||||
|
||||
mem::addr_t sig(std::vector<int> pattern_bytes) {
|
||||
unsigned long image_size = get_nt_headers()->OptionalHeader.SizeOfImage;
|
||||
|
@ -51,18 +55,21 @@ namespace util::mem {
|
|||
|
||||
return mem::addr_t();
|
||||
}
|
||||
|
||||
public:
|
||||
bool safe(std::uintptr_t ptr) { return ptr >= m_addr && ptr <= m_addr.add(get_nt_headers()->OptionalHeader.SizeOfImage); }
|
||||
|
||||
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<IMAGE_DOS_HEADER>(); }
|
||||
|
||||
IMAGE_NT_HEADERS* get_nt_headers() { return m_addr.offset(get_dos_headers()->e_lfanew).ptr<IMAGE_NT_HEADERS>(); }
|
||||
IMAGE_DOS_HEADER* get_dos_headers() {
|
||||
return m_addr.ptr<IMAGE_DOS_HEADER>();
|
||||
}
|
||||
|
||||
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<int> {};
|
||||
auto bytes = std::vector<int>{};
|
||||
auto start = const_cast<char*>(pattern.data());
|
||||
auto end = const_cast<char*>(start) + pattern.length();
|
||||
|
||||
|
@ -79,7 +86,6 @@ namespace util::mem {
|
|||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
private:
|
||||
mem::addr_t m_addr;
|
||||
};
|
||||
|
|
|
@ -8,12 +8,12 @@ namespace util {
|
|||
auto internet_session = InternetOpenA("Unspotify/1.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
|
||||
|
||||
if (!internet_session)
|
||||
return { nlohmann::json::parse(response_data), true };
|
||||
return {nlohmann::json::parse(response_data), true};
|
||||
|
||||
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 };
|
||||
return {nlohmann::json::parse(response_data), true};
|
||||
|
||||
HINTERNET http_req = HttpOpenRequestA(http_session, "GET", url, 0, 0, 0, INTERNET_FLAG_RELOAD, 0);
|
||||
|
||||
|
@ -23,11 +23,11 @@ namespace util {
|
|||
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 };
|
||||
return {response_data, true};
|
||||
|
||||
response_data.clear();
|
||||
|
||||
CHAR temp_buffer[1024] = { 0 };
|
||||
CHAR temp_buffer[1024] = {0};
|
||||
DWORD read_ret = 0;
|
||||
|
||||
while (InternetReadFile(http_req, temp_buffer, sizeof(temp_buffer) - 1, &read_ret) && read_ret)
|
||||
|
@ -38,8 +38,10 @@ namespace util {
|
|||
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 }; }
|
||||
return {nlohmann::json::parse(response_data), false};
|
||||
} catch (const nlohmann::json::parse_error& err [[maybe_unused]]) {
|
||||
return {nlohmann::json::parse(err_json_data), true};
|
||||
}
|
||||
}
|
||||
} // namespace networking
|
||||
} // namespace util
|
||||
|
|
Loading…
Reference in New Issue