159 lines
4.4 KiB
C++
Raw Normal View History

// host.cc
// 8/24/2013 jichi
// Branch IHF/main.cpp, rev 111
#include "host.h"
2018-07-19 00:46:52 -04:00
#include "pipe.h"
2018-07-20 16:26:27 -04:00
#include "../vnrhook/include/const.h"
#include "../vnrhook/include/defs.h"
#include "../vnrhook/include/types.h"
2018-07-17 17:01:56 -04:00
HANDLE preventDuplicationMutex;
2018-07-17 17:01:56 -04:00
HookManager* man;
HWND dummyWindow;
2018-07-17 17:01:56 -04:00
bool running;
2018-07-19 00:09:58 -04:00
namespace
{ // unnamed
2018-07-19 00:09:58 -04:00
void GetDebugPrivileges() // Artikash 5/19/2018: Is it just me or is this function 100% superfluous?
{
HANDLE processToken;
2018-07-18 23:40:44 -04:00
TOKEN_PRIVILEGES Privileges = { 1, {0x14, 0, SE_PRIVILEGE_ENABLED} };
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &processToken);
AdjustTokenPrivileges(processToken, FALSE, &Privileges, 0, nullptr, nullptr);
CloseHandle(processToken);
}
} // unnamed namespace
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID unused)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hinstDLL);
GetDebugPrivileges();
// jichi 8/24/2013: Create hidden window so that ITH can access timer and events
dummyWindow = CreateWindowW(L"Button", L"InternalWindow", 0, 0, 0, 0, 0, 0, 0, hinstDLL, 0);
break;
case DLL_PROCESS_DETACH:
2018-07-19 00:09:58 -04:00
CloseHost();
DestroyWindow(dummyWindow);
break;
default:
break;
}
return true;
}
2018-07-17 17:01:56 -04:00
DLLEXPORT bool StartHost()
{
preventDuplicationMutex = CreateMutexW(nullptr, TRUE, ITH_SERVER_MUTEX);
if (GetLastError() == ERROR_ALREADY_EXISTS || ::running)
{
2018-07-19 00:09:58 -04:00
MessageBoxW(nullptr, L"I am sorry that this game is attached by some other VNR ><\nPlease restart the game and try again!", L"Error", MB_ICONERROR);
2018-07-17 17:01:56 -04:00
return false;
}
else
{
::running = true;
::man = new HookManager;
2018-07-17 17:01:56 -04:00
return true;
}
}
2018-07-17 17:01:56 -04:00
DLLEXPORT void OpenHost()
{
CreateNewPipe();
}
2018-07-17 17:01:56 -04:00
DLLEXPORT void CloseHost()
{
if (::running)
{
2018-05-20 16:10:07 -04:00
::running = false;
delete man;
CloseHandle(preventDuplicationMutex);
}
}
2018-07-17 17:01:56 -04:00
DLLEXPORT bool InjectProcessById(DWORD processId, DWORD timeout)
{
2018-07-18 23:40:44 -04:00
if (processId == GetCurrentProcessId()) return false;
2018-06-12 20:02:41 -04:00
CloseHandle(CreateMutexW(nullptr, FALSE, (ITH_HOOKMAN_MUTEX_ + std::to_wstring(processId)).c_str()));
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
man->AddConsoleOutput(L"already locked");
2018-07-17 17:01:56 -04:00
return false;
}
2018-05-20 13:11:55 -04:00
HMODULE textHooker = LoadLibraryExW(ITH_DLL, nullptr, DONT_RESOLVE_DLL_REFERENCES);
wchar_t textHookerPath[MAX_PATH];
unsigned int textHookerPathSize = GetModuleFileNameW(textHooker, textHookerPath, MAX_PATH) * 2 + 2;
FreeLibrary(textHooker);
2018-07-17 17:01:56 -04:00
if (HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId))
if (LPVOID remoteData = VirtualAllocEx(processHandle, nullptr, textHookerPathSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE))
if (WriteProcessMemory(processHandle, remoteData, textHookerPath, textHookerPathSize, nullptr))
2018-07-17 17:01:56 -04:00
if (HANDLE thread = CreateRemoteThread(processHandle, nullptr, 0, (LPTHREAD_START_ROUTINE)LoadLibraryW, remoteData, 0, nullptr))
{
WaitForSingleObject(thread, timeout);
CloseHandle(thread);
2018-07-19 23:22:55 -04:00
VirtualFreeEx(processHandle, remoteData, 0, MEM_RELEASE);
2018-07-17 17:01:56 -04:00
CloseHandle(processHandle);
return true;
}
2018-07-19 00:09:58 -04:00
2018-07-17 17:01:56 -04:00
man->AddConsoleOutput(L"couldn't inject dll");
return false;
}
2018-07-17 17:01:56 -04:00
DLLEXPORT bool DetachProcessById(DWORD processId)
{
2018-05-20 16:10:07 -04:00
DWORD command = HOST_COMMAND_DETACH;
2018-07-13 20:51:09 -04:00
DWORD unused;
2018-07-17 17:01:56 -04:00
return WriteFile(man->GetHostPipe(processId), &command, sizeof(command), &unused, nullptr);
}
2018-07-20 17:18:27 -04:00
DLLEXPORT HookManager* GetHostHookManager()
{
2018-07-20 17:18:27 -04:00
return man;
}
2018-07-20 17:18:27 -04:00
DLLEXPORT bool InsertHook(DWORD pid, HookParam hp, std::string name)
{
2018-07-19 00:09:58 -04:00
HANDLE commandPipe = man->GetHostPipe(pid);
if (commandPipe == nullptr) return false;
BYTE buffer[PIPE_BUFFER_SIZE] = {};
*(DWORD*)buffer = HOST_COMMAND_NEW_HOOK;
2018-07-20 17:18:27 -04:00
*(HookParam*)(buffer + sizeof(DWORD)) = hp;
2018-07-19 00:09:58 -04:00
if (name.size()) strcpy((char*)buffer + sizeof(DWORD) + sizeof(HookParam), name.c_str());
DWORD unused;
2018-07-19 00:46:52 -04:00
return WriteFile(commandPipe, buffer, sizeof(DWORD) + sizeof(HookParam) + name.size(), &unused, nullptr);
}
2018-07-19 00:09:58 -04:00
DLLEXPORT bool RemoveHook(DWORD pid, DWORD addr)
{
2018-07-17 17:01:56 -04:00
HANDLE commandPipe = man->GetHostPipe(pid);
2018-07-19 00:09:58 -04:00
if (commandPipe == nullptr) return false;
2018-07-12 13:59:05 -04:00
HANDLE hookRemovalEvent = CreateEventW(nullptr, TRUE, FALSE, ITH_REMOVEHOOK_EVENT);
2018-07-19 00:09:58 -04:00
BYTE buffer[sizeof(DWORD) * 2] = {};
2018-07-12 13:59:05 -04:00
*(DWORD*)buffer = HOST_COMMAND_REMOVE_HOOK;
*(DWORD*)(buffer + sizeof(DWORD)) = addr;
2018-07-13 20:51:09 -04:00
DWORD unused;
2018-07-19 00:09:58 -04:00
WriteFile(commandPipe, buffer, sizeof(DWORD) * 2, &unused, nullptr);
WaitForSingleObject(hookRemovalEvent, 1000);
CloseHandle(hookRemovalEvent);
man->RemoveSingleHook(pid, addr);
return true;
}
// EOF