Code:
#include <Windows.h>
#include <TlHelp32.h>
#include <cstdio>
HMODULE GetRemoteModuleHandleA(DWORD dwProcessId, const char* szModule)
{
HANDLE tlh = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
MODULEENTRY32 modEntry;
modEntry.dwSize = sizeof(MODULEENTRY32);
Module32First(tlh, &modEntry);
do
{
if (_stricmp(szModule, modEntry.szModule) == 0)
{
CloseHandle(tlh);
return modEntry.hModule;
}
} while (Module32Next(tlh, &modEntry));
CloseHandle(tlh);
return NULL;
}
DWORD GetProcessIdFromProcessName(const char* szProcessName)
{
HANDLE tlh = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
PROCESSENTRY32 procEntry;
procEntry.dwSize = sizeof(PROCESSENTRY32);
Process32First(tlh, &procEntry);
do
{
if (_stricmp(szProcessName, procEntry.szExeFile) == 0) {
CloseHandle(tlh);
return procEntry.th32ProcessID;
}
} while (Process32Next(tlh, &procEntry));
CloseHandle(tlh);
return GetCurrentProcessId();
}
int injectDllIntoPID(const char * szModuleName, const DWORD dwProcessId)
{
HMODULE hKernel = LoadLibraryA("kernel32.dll");
DWORD64 dwLoadLibraryA = (DWORD64)GetProcAddress(hKernel, "LoadLibraryA") - (DWORD64)hKernel;
char szCurrentModulePath[MAX_PATH] = { 0 };
GetModuleFileNameA(GetModuleHandle(NULL), szCurrentModulePath, MAX_PATH);
for (size_t i = strlen(szCurrentModulePath); i > 0; i--) {
if (szCurrentModulePath[i] == '\\') {
szCurrentModulePath[i + 1] = 0;
break;
}
}
strcat_s(szCurrentModulePath, szModuleName);
DWORD dwFileAttributes = GetFileAttributesA(szCurrentModulePath);
if (dwFileAttributes == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND) {
return 0;
}
HMODULE hRemoteKernel = GetRemoteModuleHandleA(dwProcessId, "kernel32.dll");
if (hRemoteKernel == NULL) {
return 0;
}
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if (hProcess == INVALID_HANDLE_VALUE) {
return 0;
}
LPVOID lpModuleName = VirtualAllocEx(hProcess, NULL, strlen(szCurrentModulePath) + 1, MEM_COMMIT, PAGE_READWRITE);
if (lpModuleName == NULL) {
return 0;
}
if (WriteProcessMemory(hProcess, lpModuleName, szCurrentModulePath, strlen(szCurrentModulePath), NULL) == FALSE) {
return 0;
}
DWORD64 dwRemoteLoadLibraryAddress = ((DWORD64)hRemoteKernel + dwLoadLibraryA);
HANDLE hThread = CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE)dwRemoteLoadLibraryAddress, lpModuleName, 0, 0);
WaitForSingleObject(hThread, INFINITE);
return 1;
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
char GTALauncherPath[64] = "C:\\Program Files\\Rockstar Games\\Grand Theft Auto V\\PlayGTAV.exe";
char GTAProcessName[9] = "GTA5.exe";
char Core[9] = "Core.dll";
DWORD GTAProcessId = GetCurrentProcessId();
// Launch Launcher
STARTUPINFOA startupInfo;
PROCESS_INFORMATION processInformation;
ZeroMemory(&startupInfo, sizeof(startupInfo));
CreateProcessA(0, GTALauncherPath, 0, 0, 1, DETACHED_PROCESS, 0, 0, &startupInfo, &processInformation);
// TODO : (IF NEED) We have to CREATE_SUSPENDED GTA5.exe
bool moduleInjected = false;
while (!moduleInjected)
{
GTAProcessId = GetProcessIdFromProcessName(GTAProcessName);
if (GTAProcessId == GetCurrentProcessId())
{
Sleep(100);
}
else
{
moduleInjected = injectDllIntoPID(Core, GTAProcessId);
}
}
return 0;
}