-
-
Save blastrock/6958033f03a0bdffa52c6dfa2ce0e60a to your computer and use it in GitHub Desktop.
#include <windows.h> | |
#include <tlhelp32.h> | |
#include <iostream> | |
#include <string> | |
#define LOG_LINE(x, msg) std::cout << msg << std::endl; | |
DWORD GetProcessID64(std::wstring processName) | |
{ | |
PROCESSENTRY32 processInfo; | |
processInfo.dwSize = sizeof(processInfo); | |
HANDLE processesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); | |
if (processesSnapshot == INVALID_HANDLE_VALUE) | |
return 0; | |
Process32First(processesSnapshot, &processInfo); | |
if (_wcsicmp(processName.c_str(), processInfo.szExeFile) == 0) | |
{ | |
BOOL iswow64 = FALSE; | |
// https://stackoverflow.com/questions/14184137/how-can-i-determine-whether-a-process-is-32-or-64-bit | |
// If IsWow64Process() reports true, the process is 32-bit running on a | |
// 64-bit OS So we want it to return false (32 bit on 32 bit os, or 64 bit on | |
// 64 bit OS, since we build x64 the first condition will never satisfy since | |
// they can't run this exe) | |
auto hProcess = | |
OpenProcess(PROCESS_ALL_ACCESS, FALSE, processInfo.th32ProcessID); | |
if (hProcess == NULL) | |
{ | |
LOG_LINE(INFO, "Error on OpenProcess to check bitness"); | |
} | |
else | |
{ | |
if (IsWow64Process(hProcess, &iswow64)) | |
{ | |
// LOG_LINE(INFO, "Rocket league process ID is " << | |
// processInfo.th32ProcessID << " | " << " has the WOW factor: " << | |
// iswow64); | |
if (!iswow64) | |
{ | |
CloseHandle(processesSnapshot); | |
return processInfo.th32ProcessID; | |
} | |
} | |
else | |
{ | |
LOG_LINE(INFO, "IsWow64Process failed bruv " << GetLastError()); | |
} | |
CloseHandle(hProcess); | |
} | |
} | |
while (Process32Next(processesSnapshot, &processInfo)) | |
{ | |
if (_wcsicmp(processName.c_str(), processInfo.szExeFile) == 0) | |
{ | |
BOOL iswow64 = FALSE; | |
auto hProcess = | |
OpenProcess(PROCESS_ALL_ACCESS, FALSE, processInfo.th32ProcessID); | |
if (hProcess == NULL) | |
{ | |
LOG_LINE(INFO, "Error on OpenProcess to check bitness"); | |
} | |
else | |
{ | |
if (IsWow64Process(hProcess, &iswow64)) | |
{ | |
// LOG_LINE(INFO, "Rocket league process ID is " << | |
// processInfo.th32ProcessID << " | " << " has the WOW factor: " << | |
// iswow64); | |
if (!iswow64) | |
{ | |
CloseHandle(processesSnapshot); | |
return processInfo.th32ProcessID; | |
} | |
} | |
else | |
{ | |
LOG_LINE(INFO, "IsWow64Process failed bruv " << GetLastError()); | |
} | |
CloseHandle(hProcess); | |
} | |
} | |
// CloseHandle(processesSnapshot); | |
} | |
CloseHandle(processesSnapshot); | |
return 0; | |
} | |
int wmain(int argc, wchar_t* argv[]) | |
{ | |
DWORD processID; | |
while (true) | |
{ | |
processID = GetProcessID64(L"RocketLeague.exe"); | |
if (processID != 0) | |
break; | |
Sleep(100); | |
} | |
HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, false, processID); | |
if (h) | |
{ | |
LPVOID LoadLibAddr = (LPVOID)GetProcAddress( | |
GetModuleHandleW(L"kernel32.dll"), "LoadLibraryW"); | |
auto ws = L"C:\\users\\steamuser\\Application Data\\bakkesmod\\bakkesmod/dll\\bakkesmod.dll"; | |
auto wslen = (std::wcslen(ws) + 1) * sizeof(WCHAR); | |
LPVOID dereercomp = VirtualAllocEx( | |
h, NULL, wslen, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); | |
WriteProcessMemory(h, dereercomp, ws, wslen, NULL); | |
HANDLE asdc = CreateRemoteThread( | |
h, | |
NULL, | |
NULL, | |
(LPTHREAD_START_ROUTINE)LoadLibAddr, | |
dereercomp, | |
0, | |
NULL); | |
WaitForSingleObject(asdc, INFINITE); | |
DWORD res = 0; | |
GetExitCodeThread(asdc, &res); | |
LOG_LINE(INFO, "GetExitCodeThread(): " << (int)res); | |
LOG_LINE(INFO, "Last error: " << GetLastError()); | |
VirtualFreeEx(h, dereercomp, wslen, MEM_RELEASE); | |
CloseHandle(asdc); | |
CloseHandle(h); | |
return res == 0; | |
} | |
return 1; | |
} |
I didn't actually write that. I initially wanted to debug the official bakkesmod injector, and to understand why it didn't work, I tried copy pasting the code from the injector so that I could edit and debug it.
This code is a straight copy paste from https://github.com/bakkesmodorg/BakkesModInjectorCpp/blob/06749bc1064da608df5ab44da185aaf9ab546342/BakkesModInjectorC++/BakkesModInjectorCpp.cpp and https://github.com/bakkesmodorg/BakkesModInjectorCpp/blob/06749bc1064da608df5ab44da185aaf9ab546342/BakkesModInjectorC++/DllInjector.cpp IIRC. (clang-format changed the indentation though)
In the end, I didn't edit or debug it, it worked right away, so I can't understand why the official injector doesn't. So this program is more like a proof that the exact code bakkesmod uses should definitely work and there's something else that prevents it. I still have the hope that the official injector gets fixed and that I delete this gist ^^
Then, to answer your question, in my opinion, warnings should be fixed, I definitely like it when there are none. Even if these warnings are harmless, I'd fix them in a serious project. But since in the end this has just become a hack to load bakkesmod, I don't bother maintaining it as it just works. I would argue that these warnings should be fixed in the upstream project. Also, I'm lazy ^^
Understandable if it doesn't matter too much/is hard to work around, but on Linux I get two warnings when compiling. Could you write the code to avoid those? It would be better practice, no? At least, when I was learning C, we were failed for having warnings. (-Werr turns all warnings into errors, and we were failed for any errors.) Is writing around these warnings unnecessary? This a genuine question about style and how you wrote this. Did you ignore the warnings because they were stupid, and it's clear to humans what you meant, and the warnings mean seriously nothing? Or, have you just ignored them? Personally I think it would be better if it were written in such a way that there were no warnings, but having only a scholarly background I wonder if people who code in the real world ignore redundant warnings.
Here are the warnings that I am referring to.