diff --git a/SpotifyKeyDumperInjector/SpotifyKeyDumperInjector.cpp b/SpotifyKeyDumperInjector/SpotifyKeyDumperInjector.cpp index f3ab783..6c14ab3 100644 --- a/SpotifyKeyDumperInjector/SpotifyKeyDumperInjector.cpp +++ b/SpotifyKeyDumperInjector/SpotifyKeyDumperInjector.cpp @@ -1,11 +1,13 @@ #include -#include #include #include +// 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='*'\"") + static const char* VERSION = "1.0.1"; -static const char* DLL_FILE_PATH = "SpotifyKeyDumper.dll"; +static const wchar_t* DLL_FILE_PATH = L"SpotifyKeyDumper.dll"; static const wchar_t* PROC_NAME = L"Spotify.exe"; DWORD GetProcId(const wchar_t* procName) @@ -36,57 +38,98 @@ DWORD GetProcId(const wchar_t* procName) return procId; } -void StartDllInjection() +void StartSuspendedInjection() { - const char* dllPath = DLL_FILE_PATH; - const wchar_t* procName = PROC_NAME; - DWORD procId = GetProcId(procName); + 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); if (procId) { - std::wstring procNameW = std::wstring(procName); + std::wstring procNameW = std::wstring(PROC_NAME); 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); - //return; + return; } - while (!procId) + 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)) { - procId = GetProcId(procName); - Sleep(50); + std::wcout << "Error: Could not start " << PROC_NAME << " (could not create process)" << std::endl; + return; } - // Possibly injecting too fast resulting in an error, so delay? - Sleep(50); + std::cout << "Injecting DLL..." << std::endl; - HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, procId); - - if (hProc && hProc != INVALID_HANDLE_VALUE) + if (GetFileAttributes(PROC_NAME) == INVALID_FILE_ATTRIBUTES) { - void* loc = VirtualAllocEx(hProc, 0, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); - - if (loc == NULL) - return; - - WriteProcessMemory(hProc, loc, dllPath, strlen(dllPath) + 1, 0); - - HANDLE hThread = CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, loc, 0, 0); - if (hThread) - CloseHandle(hThread); + std::wcout << "Error: DLL injection failed (could not find " << PROC_NAME << ")" << std::endl; + return; } - if (hProc) - CloseHandle(hProc); + if (GetFileAttributes(DLL_FILE_PATH) == INVALID_FILE_ATTRIBUTES) + { + std::wcout << "Error: DLL injection failed (could not find " << DLL_FILE_PATH << ")" << std::endl; + return; + } + + tmpPage = VirtualAllocEx(procInfo.hProcess, NULL, dllPathLen, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + if (tmpPage == NULL) + { + std::wcout << "Error: DLL injection failed (could not allocate memory)" << std::endl; + return; + } + + 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; + } + + if (WaitForSingleObject(injectThread, UINT_MAX) == WAIT_FAILED) + { + std::wcout << "Error: DLL injection failed (could not wait for thread to return)" << std::endl; + return; + } + + if (ResumeThread(procInfo.hThread) == -1) + { + std::wcout << "Error: DLL injection failed (could not resume thread)" << std::endl; + return; + } + + VirtualFreeEx(procInfo.hProcess, tmpPage, 0, MEM_RELEASE); + CloseHandle(injectThread); + CloseHandle(procInfo.hProcess); + CloseHandle(procInfo.hThread); + + std::wcout << "Finished injecting." << std::endl; } -int main() +int __cdecl main() { - std::cout << "SpotifyKeyDumperInjector v" << VERSION << std::endl << std::endl; + std::wcout << "SpotifyKeyDumperInjector v" << VERSION << std::endl << std::endl; + std::wcout << "Attempting to inject \"" << DLL_FILE_PATH << "\" into \"" << PROC_NAME << "\"..." << std::endl; - std::wcout << "Waiting to inject \"" << DLL_FILE_PATH << "\" into \"" << std::wstring(PROC_NAME) << "\"..." << std::endl; - StartDllInjection(); - std::cout << "Injected." << std::endl; + StartSuspendedInjection(); return 0; } \ No newline at end of file