New better injection mechanism for SpotifyKeyDumperInjector

This commit is contained in:
_ 2020-12-02 16:13:44 -07:00
parent c643d4a6ca
commit 24aaf36de8

View File

@ -1,11 +1,13 @@
#include <iostream> #include <iostream>
#include <sstream>
#include <Windows.h> #include <Windows.h>
#include <TlHelp32.h> #include <TlHelp32.h>
// 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* 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"; static const wchar_t* PROC_NAME = L"Spotify.exe";
DWORD GetProcId(const wchar_t* procName) DWORD GetProcId(const wchar_t* procName)
@ -36,57 +38,98 @@ DWORD GetProcId(const wchar_t* procName)
return procId; return procId;
} }
void StartDllInjection() void StartSuspendedInjection()
{ {
const char* dllPath = DLL_FILE_PATH; STARTUPINFO startupInfo;
const wchar_t* procName = PROC_NAME; PROCESS_INFORMATION procInfo;
DWORD procId = GetProcId(procName); 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) 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" 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); "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); std::wcout << "Error: Could not start " << PROC_NAME << " (could not create process)" << std::endl;
Sleep(50); return;
} }
// Possibly injecting too fast resulting in an error, so delay? std::cout << "Injecting DLL..." << std::endl;
Sleep(50);
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, procId); if (GetFileAttributes(PROC_NAME) == INVALID_FILE_ATTRIBUTES)
if (hProc && hProc != INVALID_HANDLE_VALUE)
{ {
void* loc = VirtualAllocEx(hProc, 0, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); std::wcout << "Error: DLL injection failed (could not find " << PROC_NAME << ")" << std::endl;
return;
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);
} }
if (hProc) if (GetFileAttributes(DLL_FILE_PATH) == INVALID_FILE_ATTRIBUTES)
CloseHandle(hProc); {
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; StartSuspendedInjection();
StartDllInjection();
std::cout << "Injected." << std::endl;
return 0; return 0;
} }