2020-11-02 06:08:10 +01:00
|
|
|
#include <iostream>
|
|
|
|
#include <Windows.h>
|
|
|
|
#include <TlHelp32.h>
|
|
|
|
|
2020-12-03 00:13:44 +01:00
|
|
|
// For new visual style for MessageBox
|
|
|
|
#pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
|
|
|
|
2020-11-17 20:11:33 +01:00
|
|
|
static const char* VERSION = "1.0.1";
|
2020-11-02 06:08:10 +01:00
|
|
|
|
2020-12-03 00:13:44 +01:00
|
|
|
static const wchar_t* DLL_FILE_PATH = L"SpotifyKeyDumper.dll";
|
2020-11-02 06:08:10 +01:00
|
|
|
static const wchar_t* PROC_NAME = L"Spotify.exe";
|
|
|
|
|
|
|
|
DWORD GetProcId(const wchar_t* procName)
|
|
|
|
{
|
|
|
|
DWORD procId = 0;
|
|
|
|
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|
|
|
|
|
|
|
if (hSnap != INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
PROCESSENTRY32 procEntry;
|
|
|
|
procEntry.dwSize = sizeof(procEntry);
|
|
|
|
|
|
|
|
if (Process32First(hSnap, &procEntry))
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if (!wcscmp(procEntry.szExeFile, procName))
|
|
|
|
{
|
|
|
|
procId = procEntry.th32ProcessID;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (Process32Next(hSnap, &procEntry));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CloseHandle(hSnap);
|
|
|
|
return procId;
|
|
|
|
}
|
|
|
|
|
2020-12-03 00:13:44 +01:00
|
|
|
void StartSuspendedInjection()
|
2020-11-02 06:08:10 +01:00
|
|
|
{
|
2020-12-03 00:13:44 +01:00
|
|
|
STARTUPINFO startupInfo;
|
|
|
|
PROCESS_INFORMATION procInfo;
|
|
|
|
void* tmpPage;
|
|
|
|
HANDLE injectThread;
|
|
|
|
size_t dllPathLen = (wcslen(DLL_FILE_PATH) + 1) * sizeof(wchar_t);
|
|
|
|
|
|
|
|
// Check if Spotify is already open
|
|
|
|
DWORD procId = GetProcId(PROC_NAME);
|
2020-11-17 20:11:33 +01:00
|
|
|
if (procId)
|
|
|
|
{
|
2020-12-03 00:13:44 +01:00
|
|
|
std::wstring procNameW = std::wstring(PROC_NAME);
|
2020-11-17 20:11:33 +01:00
|
|
|
MessageBox(NULL, std::wstring(procNameW + std::wstring(L" has already been detected!\n\n"
|
|
|
|
"Please launch this before ") + procNameW).c_str(), NULL, MB_OK | MB_ICONERROR);
|
|
|
|
|
2020-12-03 00:13:44 +01:00
|
|
|
return;
|
2020-11-17 20:11:33 +01:00
|
|
|
}
|
2020-11-02 06:08:10 +01:00
|
|
|
|
2020-12-03 00:13:44 +01:00
|
|
|
std::wcout << "Starting " << PROC_NAME << "..." << std::endl;
|
|
|
|
|
|
|
|
ZeroMemory(&startupInfo, sizeof(startupInfo));
|
|
|
|
startupInfo.cb = sizeof(STARTUPINFOA);
|
|
|
|
ZeroMemory(&procInfo, sizeof(procInfo));
|
|
|
|
|
|
|
|
if (!CreateProcess(PROC_NAME, NULL, NULL, NULL, false, CREATE_SUSPENDED, NULL, NULL, &startupInfo, &procInfo))
|
2020-11-02 06:08:10 +01:00
|
|
|
{
|
2020-12-03 00:13:44 +01:00
|
|
|
std::wcout << "Error: Could not start " << PROC_NAME << " (could not create process)" << std::endl;
|
|
|
|
return;
|
2020-11-02 06:08:10 +01:00
|
|
|
}
|
|
|
|
|
2020-12-03 00:13:44 +01:00
|
|
|
std::cout << "Injecting DLL..." << std::endl;
|
2020-11-02 06:08:10 +01:00
|
|
|
|
2020-12-03 00:13:44 +01:00
|
|
|
if (GetFileAttributes(PROC_NAME) == INVALID_FILE_ATTRIBUTES)
|
|
|
|
{
|
|
|
|
std::wcout << "Error: DLL injection failed (could not find " << PROC_NAME << ")" << std::endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GetFileAttributes(DLL_FILE_PATH) == INVALID_FILE_ATTRIBUTES)
|
|
|
|
{
|
|
|
|
std::wcout << "Error: DLL injection failed (could not find " << DLL_FILE_PATH << ")" << std::endl;
|
|
|
|
return;
|
|
|
|
}
|
2020-11-02 06:08:10 +01:00
|
|
|
|
2020-12-03 00:13:44 +01:00
|
|
|
tmpPage = VirtualAllocEx(procInfo.hProcess, NULL, dllPathLen, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
|
|
|
if (tmpPage == NULL)
|
2020-11-02 06:08:10 +01:00
|
|
|
{
|
2020-12-03 00:13:44 +01:00
|
|
|
std::wcout << "Error: DLL injection failed (could not allocate memory)" << std::endl;
|
|
|
|
return;
|
|
|
|
}
|
2020-11-02 06:08:10 +01:00
|
|
|
|
2020-12-03 00:13:44 +01:00
|
|
|
if (!WriteProcessMemory(procInfo.hProcess, tmpPage, (PVOID) DLL_FILE_PATH, dllPathLen, NULL))
|
|
|
|
{
|
|
|
|
std::wcout << "Error: DLL injection failed (could not write memory)" << std::endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
injectThread = CreateRemoteThread(procInfo.hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibrary, tmpPage, 0,
|
|
|
|
NULL);
|
|
|
|
if (injectThread == NULL)
|
|
|
|
{
|
|
|
|
std::wcout << "Error: DLL injection failed (could not load library)" << std::endl;
|
|
|
|
return;
|
|
|
|
}
|
2020-11-02 06:08:10 +01:00
|
|
|
|
2020-12-03 00:13:44 +01:00
|
|
|
if (WaitForSingleObject(injectThread, UINT_MAX) == WAIT_FAILED)
|
|
|
|
{
|
|
|
|
std::wcout << "Error: DLL injection failed (could not wait for thread to return)" << std::endl;
|
|
|
|
return;
|
|
|
|
}
|
2020-11-02 06:08:10 +01:00
|
|
|
|
2020-12-03 00:13:44 +01:00
|
|
|
if (ResumeThread(procInfo.hThread) == -1)
|
|
|
|
{
|
|
|
|
std::wcout << "Error: DLL injection failed (could not resume thread)" << std::endl;
|
|
|
|
return;
|
2020-11-02 06:08:10 +01:00
|
|
|
}
|
|
|
|
|
2020-12-03 00:13:44 +01:00
|
|
|
VirtualFreeEx(procInfo.hProcess, tmpPage, 0, MEM_RELEASE);
|
|
|
|
CloseHandle(injectThread);
|
|
|
|
CloseHandle(procInfo.hProcess);
|
|
|
|
CloseHandle(procInfo.hThread);
|
|
|
|
|
|
|
|
std::wcout << "Finished injecting." << std::endl;
|
2020-11-02 06:08:10 +01:00
|
|
|
}
|
|
|
|
|
2020-12-03 00:13:44 +01:00
|
|
|
int __cdecl main()
|
2020-11-02 06:08:10 +01:00
|
|
|
{
|
2020-12-03 00:13:44 +01:00
|
|
|
std::wcout << "SpotifyKeyDumperInjector v" << VERSION << std::endl << std::endl;
|
|
|
|
std::wcout << "Attempting to inject \"" << DLL_FILE_PATH << "\" into \"" << PROC_NAME << "\"..." << std::endl;
|
2020-11-02 06:08:10 +01:00
|
|
|
|
2020-12-03 00:13:44 +01:00
|
|
|
StartSuspendedInjection();
|
2020-11-02 06:08:10 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|