Skip to content

Instantly share code, notes, and snippets.

@blastrock
Last active September 5, 2022 09:50
Show Gist options
  • Save blastrock/6958033f03a0bdffa52c6dfa2ce0e60a to your computer and use it in GitHub Desktop.
Save blastrock/6958033f03a0bdffa52c6dfa2ce0e60a to your computer and use it in GitHub Desktop.
dll injector
#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;
}
@blastrock
Copy link
Author

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 ^^

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment