From deccc86441608c574eb04f95fa7275df466e2217 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Tue, 29 Nov 2016 18:30:56 +0100 Subject: [PATCH] Add own injector --- GloSC.sln | 10 ++ GloSC_GameLauncher/GloSC_GameLauncher.cpp | 4 +- Injector/Injector.cpp | 132 ++++++++++++++++++ Injector/Injector.h | 20 +++ Injector/Injector.vcxproj | 156 ++++++++++++++++++++++ Injector/Injector.vcxproj.filters | 30 +++++ Injector/main.cpp | 99 ++++++++++++++ SteamTarget/SteamTargetRenderer.cpp | 4 +- 8 files changed, 450 insertions(+), 5 deletions(-) create mode 100644 Injector/Injector.cpp create mode 100644 Injector/Injector.h create mode 100644 Injector/Injector.vcxproj create mode 100644 Injector/Injector.vcxproj.filters create mode 100644 Injector/main.cpp diff --git a/GloSC.sln b/GloSC.sln index e84654c..f46cc65 100644 --- a/GloSC.sln +++ b/GloSC.sln @@ -11,6 +11,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GloSC_GameLauncher", "GloSC EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EnforceBindingDLL", "EnforceBindingDLL\EnforceBindingDLL.vcxproj", "{AFA0047E-7DEE-472A-AF4B-436A30459905}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Injector", "Injector\Injector.vcxproj", "{0F6DB076-7345-487C-BA8C-E659EBB05962}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -51,6 +53,14 @@ Global {AFA0047E-7DEE-472A-AF4B-436A30459905}.Release|x64.Build.0 = Release|Win32 {AFA0047E-7DEE-472A-AF4B-436A30459905}.Release|x86.ActiveCfg = Release|Win32 {AFA0047E-7DEE-472A-AF4B-436A30459905}.Release|x86.Build.0 = Release|Win32 + {0F6DB076-7345-487C-BA8C-E659EBB05962}.Debug|x64.ActiveCfg = Debug|Win32 + {0F6DB076-7345-487C-BA8C-E659EBB05962}.Debug|x64.Build.0 = Debug|Win32 + {0F6DB076-7345-487C-BA8C-E659EBB05962}.Debug|x86.ActiveCfg = Debug|Win32 + {0F6DB076-7345-487C-BA8C-E659EBB05962}.Debug|x86.Build.0 = Debug|Win32 + {0F6DB076-7345-487C-BA8C-E659EBB05962}.Release|x64.ActiveCfg = Release|Win32 + {0F6DB076-7345-487C-BA8C-E659EBB05962}.Release|x64.Build.0 = Release|Win32 + {0F6DB076-7345-487C-BA8C-E659EBB05962}.Release|x86.ActiveCfg = Release|Win32 + {0F6DB076-7345-487C-BA8C-E659EBB05962}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/GloSC_GameLauncher/GloSC_GameLauncher.cpp b/GloSC_GameLauncher/GloSC_GameLauncher.cpp index 4420955..b8f34e4 100644 --- a/GloSC_GameLauncher/GloSC_GameLauncher.cpp +++ b/GloSC_GameLauncher/GloSC_GameLauncher.cpp @@ -20,8 +20,6 @@ GloSC_GameLauncher::GloSC_GameLauncher(QWidget *parent) { ui.setupUi(this); - //SetDebugPrivilege(); - QTimer::singleShot(0, this, SLOT(hide())); sharedMemInstance.setKey("GloSC_GameLauncher"); @@ -190,7 +188,7 @@ bool GloSC_GameLauncher::IsProcessRunning(DWORD pid) void GloSC_GameLauncher::unhookBindings() { QProcess proc; - proc.setNativeArguments(" --process-name Steam.exe --module-name \"EnforceBindingDLL.dll\" --eject "); + proc.setNativeArguments(" --eject "); proc.start("Injector.exe", QIODevice::ReadOnly); proc.waitForFinished(); bHookedSteam = false; diff --git a/Injector/Injector.cpp b/Injector/Injector.cpp new file mode 100644 index 0000000..afc3822 --- /dev/null +++ b/Injector/Injector.cpp @@ -0,0 +1,132 @@ +#include "Injector.h" + +#include + +void Injector::TakeDebugPrivilege() +{ + HANDLE hProcess = GetCurrentProcess(), hToken; + TOKEN_PRIVILEGES priv; + LUID luid = { NULL }; + + OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken); + LookupPrivilegeValue(0, SE_DEBUG_NAME, &luid); + + priv.PrivilegeCount = 1; + priv.Privileges[0].Luid = luid; + priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + AdjustTokenPrivileges(hToken, false, &priv, sizeof(priv), NULL, NULL); + + CloseHandle(hToken); + CloseHandle(hProcess); +} + +int Injector::Inject(DWORD pid, std::wstring &libPath) +{ + HANDLE hProcess = NULL, allocAddress = NULL, hRemoteThread = NULL; + LPTHREAD_START_ROUTINE pfnThreadRtn = NULL; + + size_t pathSize = (libPath.length() + 1) * sizeof(wchar_t); + + hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, false, pid); + + if (!hProcess) + return 1; + + allocAddress = VirtualAllocEx(hProcess, NULL, pathSize, MEM_COMMIT, PAGE_READWRITE); + + if (!allocAddress) + { + CloseHandle(hProcess); + return 2; + } + + if (!WriteProcessMemory(hProcess, (LPVOID)allocAddress, libPath.c_str(), pathSize, NULL)) + { + VirtualFreeEx(hProcess, allocAddress, pathSize, MEM_DECOMMIT); + CloseHandle(hProcess); + return 3; + } + + pfnThreadRtn = reinterpret_cast(GetProcAddress(GetModuleHandle(L"Kernel32"), "LoadLibraryW")); + if (!pfnThreadRtn) + { + VirtualFreeEx(hProcess, allocAddress, pathSize, MEM_DECOMMIT); + CloseHandle(hProcess); + return 4; + } + + hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, pfnThreadRtn, allocAddress, 0, NULL); + + if (!hRemoteThread) + { + VirtualFreeEx(hProcess, allocAddress, pathSize, MEM_DECOMMIT); + CloseHandle(hProcess); + return 5; + } + + WaitForSingleObject(hRemoteThread, INFINITE); + + CloseHandle(hRemoteThread); + VirtualFreeEx(hProcess, allocAddress, pathSize, MEM_DECOMMIT); + CloseHandle(hProcess); + + return 0; +} + +int Injector::Eject(DWORD pid, std::wstring &libPath) +{ + HANDLE hProcess = NULL, hRemoteThread = NULL; + HMODULE hLibMod = NULL; + LPTHREAD_START_ROUTINE pfnThreadRtn = NULL; + + + if (!findModule(pid, libPath, hLibMod)) + return 2; + + hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION, false, pid); + if (!hProcess) + return 1; + + pfnThreadRtn = (PTHREAD_START_ROUTINE) GetProcAddress(GetModuleHandle(L"Kernel32"), "FreeLibrary"); + + if (!pfnThreadRtn) + { + CloseHandle(hProcess); + return 3; + } + + hRemoteThread = CreateRemoteThread(hProcess, NULL, NULL, pfnThreadRtn, hLibMod, NULL, NULL); + + if (!hRemoteThread) + return 4; + + WaitForSingleObject(hRemoteThread, INFINITE); + + CloseHandle(hProcess); + + return 0; +} + +bool Injector::findModule(DWORD pid, std::wstring &libPath, HMODULE &hMod) +{ + MODULEENTRY32W entry = { sizeof(entry) }; + HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid); + + if (Module32FirstW(snapshot, &entry) == TRUE) + { + while (Module32NextW(snapshot, &entry) == TRUE) + { + std::wstring ModuleName(entry.szModule); + std::wstring ExePath(entry.szExePath); + if (ModuleName == libPath || ExePath == libPath) + { + hMod = (HMODULE)entry.modBaseAddr; + CloseHandle(snapshot); + return true; + } + } + } + CloseHandle(snapshot); + return false; +} + diff --git a/Injector/Injector.h b/Injector/Injector.h new file mode 100644 index 0000000..8c98e48 --- /dev/null +++ b/Injector/Injector.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include +#include + +class Injector { + + +public: + static void TakeDebugPrivilege(); + static int Inject(DWORD pid, std::wstring &libPath); + static int Eject(DWORD pid, std::wstring &libPath); + +private: + + static bool findModule(DWORD pid, std::wstring &libPath, HMODULE &hMod); + + +}; \ No newline at end of file diff --git a/Injector/Injector.vcxproj b/Injector/Injector.vcxproj new file mode 100644 index 0000000..ed926f7 --- /dev/null +++ b/Injector/Injector.vcxproj @@ -0,0 +1,156 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {0F6DB076-7345-487C-BA8C-E659EBB05962} + Win32Proj + Injector + 8.1 + + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDebug + + + Console + true + + + + + + + Level3 + Disabled + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + + + Console + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/Injector/Injector.vcxproj.filters b/Injector/Injector.vcxproj.filters new file mode 100644 index 0000000..e3cfb05 --- /dev/null +++ b/Injector/Injector.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Quelldateien + + + Quelldateien + + + + + Headerdateien + + + \ No newline at end of file diff --git a/Injector/main.cpp b/Injector/main.cpp new file mode 100644 index 0000000..877d04d --- /dev/null +++ b/Injector/main.cpp @@ -0,0 +1,99 @@ +#include +#include +#include +#include "Injector.h" + +#define dllName L"EnforceBindingDLL.dll"; + +int wmain(int argc, wchar_t* argv[]) +{ + + if (argc < 2) + { + std::wcout << "Missing arguments" << std::endl; + return 1; + } + + Injector::TakeDebugPrivilege(); + + wchar_t wcPath[MAX_PATH]; + GetModuleFileName(GetModuleHandle(NULL), wcPath, MAX_PATH); + std::wstring path(wcPath); + std::wstring libPath = path.substr(0, path.find_last_of(L"\\")+1) + dllName; + + DWORD pid = NULL; + + PROCESSENTRY32 entry; + entry.dwSize = sizeof(PROCESSENTRY32); + HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); + if (Process32First(snapshot, &entry) == TRUE) + { + while (Process32Next(snapshot, &entry) == TRUE) + { + if (wcsicmp(entry.szExeFile, L"steam.exe") == 0) + { + pid = entry.th32ProcessID; + } + } + } + CloseHandle(snapshot); + + if (pid == NULL) + { + std::wcout << "Can't detect Steam.exe running" << std::endl; + return 1; + } + + + if (std::wstring(argv[1]) == L"--inject") + { + int result = Injector::Inject(pid, libPath); + switch (result) + { + case 0: + std::wcout << "Inject success!" << std::endl; + break; + case 1: + std::wcout << "Error: Couldn't open process" << std::endl; + break; + case 2: + std::wcout << "Error: Couldn't allocate memory" << std::endl; + break; + case 3: + std::wcout << "Error: Couldn't write memory" << std::endl; + break; + case 4: + std::wcout << "Error: Couldn't get pointer ro LoadLibraryW" << std::endl; + break; + case 5: + std::wcout << "Error: Couldn't start remote thread" << std::endl; + break; + } + } + else if (std::wstring(argv[1]) == L"--eject") + { + int result = Injector::Eject(pid, libPath); + switch (result) + { + case 0: + std::wcout << "Eject success!" << std::endl; + break; + case 1: + std::wcout << "Error: Couldn't open process" << std::endl; + break; + case 2: + std::wcout << "Error: Couldn't find module in process" << std::endl; + break; + case 3: + std::wcout << "Error: Couldn't get pointer ro FreeLibrary" << std::endl; + break; + case 4: + std::wcout << "Error: Couldn't start remote thread" << std::endl; + break; + } + } + + + + return 0; +} \ No newline at end of file diff --git a/SteamTarget/SteamTargetRenderer.cpp b/SteamTarget/SteamTargetRenderer.cpp index f6a01af..a0f7b0f 100644 --- a/SteamTarget/SteamTargetRenderer.cpp +++ b/SteamTarget/SteamTargetRenderer.cpp @@ -254,10 +254,10 @@ void SteamTargetRenderer::hookBindings() dir = dir.mid(0, dir.lastIndexOf("\\")); QProcess proc; - proc.setNativeArguments(" --process-name Steam.exe --module-name \"" + dir + "\\EnforceBindingDLL.dll\" --inject "); + proc.setNativeArguments(" --inject "); proc.start(dir + "\\Injector.exe", QIODevice::ReadOnly); proc.waitForFinished(); - if (QString::fromStdString(proc.readAll().toStdString()).contains("Successfully injected module!")) //if we have injected (and patched the function) + if (QString::fromStdString(proc.readAll().toStdString()).contains("Inject success!")) //if we have injected (and patched the function) { std::cout << "Successfully hooked Steam!" << std::endl;