So I'm studying cyber security and a topic we've come across is DLL injection. So as a little experiment i've taken the time to create my own DLL injection on a game I have.
so syntax wise everything runs smoothly, as well with the compiler, Im doing just as the documentation says for createRemoteThread, connecting to the DLLMAIN api, I've even added a message box to alert me the DLL Attachment was successful, yet nothing. here is my source code
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        MessageBoxA(NULL, "Successfully connected to DLL!", "DLL Injector", MB_OK);
        break;
    case DLL_THREAD_ATTACH:
        MessageBoxA(NULL, "it worked", "k", MB_OK);
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
int getProcId(const char* target){
    DWORD pID = 0;
    PROCESSENTRY32 pe32;
    pe32.dwSize = sizeof(PROCESSENTRY32);
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    wchar_t wideTarget[MAX_PATH];
    MultiByteToWideChar(CP_UTF8, 0, target, -1, wideTarget, MAX_PATH);
    do {
        wchar_t wideExeFile[MAX_PATH];
        MultiByteToWideChar(CP_UTF8, 0, pe32.szExeFile, -1, wideExeFile, MAX_PATH);
        if (wcscmp(wideExeFile, wideTarget) == 0) {
            CloseHandle(hSnapshot);
            pID = pe32.th32ProcessID;
            break;
        }
    } while (Process32Next(hSnapshot, &pe32));
    CloseHandle(hSnapshot);
    return pID;
}
int injectDLL(int pID, const char* dllPath) {
    HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, pID);
    if (hProcess == NULL) {
        return 1;
    }
    LPVOID pRemotePath = VirtualAllocEx(hProcess, NULL, strlen(dllPath) + 1, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    if (pRemotePath == NULL) {
        CloseHandle(hProcess);
        return 2;
    }
    if (!WriteProcessMemory(hProcess, pRemotePath, dllPath, strlen(dllPath) + 1, NULL)) {
        VirtualFreeEx(hProcess, pRemotePath, 0, MEM_RELEASE);
        CloseHandle(hProcess);
        return 3;
    }
    HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
    FARPROC pLoadLibraryA = GetProcAddress(hKernel32, "LoadLibraryA");
    HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pLoadLibraryA, pRemotePath, 0, NULL);
    if (hRemoteThread == NULL) {
        VirtualFreeEx(hProcess, pRemotePath, 0, MEM_RELEASE);
        CloseHandle(hProcess);
        return 4;
    }
    WaitForSingleObject(hRemoteThread, INFINITE);
    VirtualFreeEx(hProcess, pRemotePath, 0, MEM_RELEASE);
    CloseHandle(hRemoteThread);
    CloseHandle(hProcess);
    return 0;
}
int main(int argc, char* argv[]) {
    const char* process = "Left 4 dead 2 - Direct3D 9";
    const char* dllPath = "Engine.dll";
    int pID = getProcId(process);
    if (pID == 0) {
        // Process not found
        return 1;
    }
    int result = injectDLL(pID, dllPath);
    if (result == 0) {
        printf("success");// Injection succeeded
    } else {
        printf("not successful"); // Injection failed
    }
    return 0;
}