aboutsummaryrefslogtreecommitdiff
path: root/SpotifyKeyDumperInjector/SpotifyKeyDumperInjector.cpp
blob: d74737d22e8b8924884e7720de223cf26b0a6ce4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include <iostream>
#include <Windows.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.1.2";

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)
{
    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;
}

void StartSuspendedInjection()
{
    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(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;
    }

    std::wcout << "Starting " << PROC_NAME << "..." << std::endl;

    ZeroMemory(&startupInfo, sizeof(startupInfo));
    startupInfo.cb = sizeof(STARTUPINFOA);
    ZeroMemory(&procInfo, sizeof(procInfo));

    if (!CreateProcessW(PROC_NAME, NULL, NULL, NULL, false, CREATE_SUSPENDED, NULL, NULL, &startupInfo, &procInfo))
    {
        std::wcout << "Error: Could not start " << PROC_NAME << " (could not create process): " << GetLastError()
            << std::endl;
        return;
    }

    std::cout << "Injecting DLL..." << std::endl;

    if (GetFileAttributesW(PROC_NAME) == INVALID_FILE_ATTRIBUTES)
    {
        std::wcout << "Error: DLL injection failed (could not find " << PROC_NAME << ")" << std::endl;
        return;
    }

	if (GetFileAttributesW(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): " << GetLastError() << std::endl;
        return;
    }

    if (!WriteProcessMemory(procInfo.hProcess, tmpPage, (PVOID) DLL_FILE_PATH, dllPathLen, NULL))
    {
        std::wcout << "Error: DLL injection failed (could not write memory): " << GetLastError() << 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): " << GetLastError() << std::endl;
        return;
    }

    if (WaitForSingleObject(injectThread, UINT_MAX) == WAIT_FAILED)
    {
        std::wcout << "Error: DLL injection failed (could not wait for thread to return): " << GetLastError()
            << std::endl;
        return;
    }

    if (ResumeThread(procInfo.hThread) == -1)
    {
        std::wcout << "Error: DLL injection failed (could not resume thread): " << GetLastError() << 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 __cdecl main()
{
    std::wcout << "SpotifyKeyDumperInjector v" << VERSION << std::endl << std::endl;
    std::wcout << "Attempting to inject \"" << DLL_FILE_PATH << "\" into \"" << PROC_NAME << "\"..." << std::endl;

    StartSuspendedInjection();

    return 0;
}