diff options
Diffstat (limited to 'libs/usvfs/src/usvfs_dll/hookmanager.cpp')
| -rw-r--r-- | libs/usvfs/src/usvfs_dll/hookmanager.cpp | 333 |
1 files changed, 0 insertions, 333 deletions
diff --git a/libs/usvfs/src/usvfs_dll/hookmanager.cpp b/libs/usvfs/src/usvfs_dll/hookmanager.cpp deleted file mode 100644 index 731b856..0000000 --- a/libs/usvfs/src/usvfs_dll/hookmanager.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* -Userspace Virtual Filesystem - -Copyright (C) 2015 Sebastian Herbord. All rights reserved. - -This file is part of usvfs. - -usvfs is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -usvfs is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with usvfs. If not, see <http://www.gnu.org/licenses/>. -*/ -#include "hookmanager.h" -#include "../thooklib/ttrampolinepool.h" -#include "../thooklib/utility.h" -#include "exceptionex.h" -#include "hooks/kernel32.h" -#include "hooks/ntdll.h" -#include "usvfs.h" -#include <VersionHelpers.h> -#include <directory_tree.h> -#include <logging.h> -#include <shmlogger.h> -#include <usvfsparameters.h> -#include <winapi.h> - -using namespace HookLib; -namespace bf = boost::filesystem; - -namespace usvfs -{ - -HookManager* HookManager::s_Instance = nullptr; - -HookManager::HookManager(const usvfsParameters& params, HMODULE module) - : m_Context(params, module) -{ - if (s_Instance != nullptr) { - throw std::runtime_error("singleton duplicate instantiation (HookManager)"); - } - - s_Instance = this; - - m_Context.registerProcess(::GetCurrentProcessId()); - spdlog::get("usvfs")->info("Process registered in shared process list : {}", - ::GetCurrentProcessId()); - - winapi::ex::OSVersion version = winapi::ex::getOSVersion(); - spdlog::get("usvfs")->info( - "Windows version {}.{}.{} sp {} platform {} ({})", version.major, version.minor, - version.build, version.servicpack, version.platformid, - shared::string_cast<std::string>(winapi::ex::wide::getWindowsBuildLab(true)) - .c_str()); - - initHooks(); - - if (params.debugMode) { - while (!::IsDebuggerPresent()) { - // wait for debugger to attach - ::Sleep(100); - } - } -} - -HookManager::~HookManager() -{ - spdlog::get("hooks")->debug("end hook of process {}", GetCurrentProcessId()); - removeHooks(); - m_Context.unregisterCurrentProcess(); -} - -HookManager& HookManager::instance() -{ - if (s_Instance == nullptr) { - throw std::runtime_error("singleton not instantiated"); - } - - return *s_Instance; -} - -LPVOID HookManager::detour(const char* functionName) -{ - auto iter = m_Hooks.find(functionName); - if (iter != m_Hooks.end()) { - return GetDetour(iter->second); - } else { - return nullptr; - } -} - -void HookManager::removeHook(const std::string& functionName) -{ - auto iter = m_Hooks.find(functionName); - if (iter != m_Hooks.end()) { - try { - RemoveHook(iter->second); - m_Hooks.erase(iter); - spdlog::get("usvfs")->info("removed hook for {}", functionName); - } catch (const std::exception& e) { - spdlog::get("usvfs")->critical("failed to remove hook of {}: {}", functionName, - e.what()); - } - } else { - spdlog::get("usvfs")->info("{} wasn't hooked", functionName); - } -} - -void HookManager::logStubInt(LPVOID address) -{ - if (m_Stubs.find(address) != m_Stubs.end()) { - spdlog::get("hooks")->warn("{0} called", m_Stubs[address]); - } else { - spdlog::get("hooks")->warn("unknown function at {0} called", address); - } -} - -void HookManager::logStub(LPVOID address) -{ - try { - instance().logStubInt(address); - } catch (const std::exception& e) { - spdlog::get("hooks")->debug("function at {0} called after shutdown: {1}", address, - e.what()); - } -} - -void HookManager::installHook(HMODULE module1, HMODULE module2, - const std::string& functionName, LPVOID hook, - LPVOID* fillFuncAddr = nullptr) -{ - BOOST_ASSERT(hook != nullptr); - HOOKHANDLE handle = INVALID_HOOK; - HookError err = ERR_NONE; - LPVOID funcAddr = nullptr; - HMODULE usedModule = nullptr; - // both module1 and module2 are allowed to be null - if (module1 != nullptr) { - funcAddr = MyGetProcAddress(module1, functionName.c_str()); - if (funcAddr != nullptr) { - handle = InstallHook(funcAddr, hook, &err); - } - if (handle != INVALID_HOOK) - usedModule = module1; - } - - if ((handle == INVALID_HOOK) && (module2 != nullptr)) { - funcAddr = MyGetProcAddress(module2, functionName.c_str()); - if (funcAddr != nullptr) { - handle = InstallHook(funcAddr, hook, &err); - } - if (handle != INVALID_HOOK) - usedModule = module2; - } - - if (fillFuncAddr) - *fillFuncAddr = funcAddr; - - if (handle == INVALID_HOOK) { - spdlog::get("usvfs")->error("failed to hook {0}: {1}", functionName, - GetErrorString(err)); - } else { - m_Stubs.insert(make_pair(funcAddr, functionName)); - m_Hooks.insert(make_pair(std::string(functionName), handle)); - spdlog::get("usvfs")->info("hooked {0} ({1}) in {2} type {3}", functionName, - funcAddr, winapi::ansi::getModuleFileName(usedModule), - GetHookType(handle)); - } -} - -void HookManager::installStub(HMODULE module1, HMODULE module2, - const std::string& functionName) -{ - HOOKHANDLE handle = INVALID_HOOK; - HookError err = ERR_NONE; - LPVOID funcAddr = nullptr; - HMODULE usedModule = nullptr; - // both module1 and module2 are allowed to be null - if (module1 != nullptr) { - funcAddr = MyGetProcAddress(module1, functionName.c_str()); - if (funcAddr != nullptr) { - handle = InstallStub(funcAddr, logStub, &err); - } else { - spdlog::get("usvfs")->debug("{} doesn't contain {}", - winapi::ansi::getModuleFileName(module1), - functionName); - } - if (handle != INVALID_HOOK) - usedModule = module1; - } - - if ((handle == INVALID_HOOK) && (module2 != nullptr)) { - funcAddr = MyGetProcAddress(module2, functionName.c_str()); - if (funcAddr != nullptr) { - handle = InstallStub(funcAddr, logStub, &err); - } else { - spdlog::get("usvfs")->debug("{} doesn't contain {}", - winapi::ansi::getModuleFileName(module2), - functionName); - } - if (handle != INVALID_HOOK) - usedModule = module2; - } - - if (handle == INVALID_HOOK) { - spdlog::get("usvfs")->error("failed to stub {0}: {1}", functionName, - GetErrorString(err)); - } else { - m_Stubs.insert(make_pair(funcAddr, functionName)); - m_Hooks.insert(make_pair(std::string(functionName), handle)); - spdlog::get("usvfs")->info("stubbed {0} ({1}) in {2} type {3}", functionName, - funcAddr, winapi::ansi::getModuleFileName(usedModule), - GetHookType(handle)); - } -} - -void HookManager::initHooks() -{ - TrampolinePool::initialize(); - - HookLib::TrampolinePool::instance().setBlock(true); - - HMODULE k32Mod = GetModuleHandleA("kernel32.dll"); - spdlog::get("usvfs")->debug("kernel32.dll at {0:x}", - reinterpret_cast<uintptr_t>(k32Mod)); - // kernelbase.dll contains the actual implementation for functions formerly in - // kernel32.dll and advapi32.dll, starting with Windows 7 - // http://msdn.microsoft.com/en-us/library/windows/desktop/dd371752(v=vs.85).aspx - HMODULE kbaseMod = GetModuleHandleA("kernelbase.dll"); - spdlog::get("usvfs")->debug("kernelbase.dll at {0:x}", - reinterpret_cast<uintptr_t>(kbaseMod)); - - installHook(kbaseMod, k32Mod, "GetFileAttributesExA", hook_GetFileAttributesExA); - installHook(kbaseMod, k32Mod, "GetFileAttributesA", hook_GetFileAttributesA); - installHook(kbaseMod, k32Mod, "GetFileAttributesExW", hook_GetFileAttributesExW); - installHook(kbaseMod, k32Mod, "GetFileAttributesW", hook_GetFileAttributesW); - installHook(kbaseMod, k32Mod, "SetFileAttributesW", hook_SetFileAttributesW); - - installHook(kbaseMod, k32Mod, "CreateDirectoryW", hook_CreateDirectoryW); - installHook(kbaseMod, k32Mod, "RemoveDirectoryW", hook_RemoveDirectoryW); - installHook(kbaseMod, k32Mod, "DeleteFileW", hook_DeleteFileW); - installHook(kbaseMod, k32Mod, "GetCurrentDirectoryA", hook_GetCurrentDirectoryA); - installHook(kbaseMod, k32Mod, "GetCurrentDirectoryW", hook_GetCurrentDirectoryW); - installHook(kbaseMod, k32Mod, "SetCurrentDirectoryA", hook_SetCurrentDirectoryA); - installHook(kbaseMod, k32Mod, "SetCurrentDirectoryW", hook_SetCurrentDirectoryW); - - installHook(kbaseMod, k32Mod, "ExitProcess", hook_ExitProcess); - - installHook(kbaseMod, k32Mod, "CreateProcessInternalW", hook_CreateProcessInternalW, - reinterpret_cast<LPVOID*>(&CreateProcessInternalW)); - - installHook(kbaseMod, k32Mod, "MoveFileA", hook_MoveFileA); - installHook(kbaseMod, k32Mod, "MoveFileW", hook_MoveFileW); - installHook(kbaseMod, k32Mod, "MoveFileExA", hook_MoveFileExA); - installHook(kbaseMod, k32Mod, "MoveFileExW", hook_MoveFileExW); - installHook(kbaseMod, k32Mod, "MoveFileWithProgressA", hook_MoveFileWithProgressA); - installHook(kbaseMod, k32Mod, "MoveFileWithProgressW", hook_MoveFileWithProgressW); - - installHook(kbaseMod, k32Mod, "CopyFileExW", hook_CopyFileExW); - if (IsWindows8OrGreater()) - installHook(kbaseMod, k32Mod, "CopyFile2", hook_CopyFile2, - reinterpret_cast<LPVOID*>(&CopyFile2)); - - installHook(kbaseMod, k32Mod, "GetPrivateProfileStringA", - hook_GetPrivateProfileStringA); - installHook(kbaseMod, k32Mod, "GetPrivateProfileStringW", - hook_GetPrivateProfileStringW); - installHook(kbaseMod, k32Mod, "GetPrivateProfileSectionA", - hook_GetPrivateProfileSectionA); - installHook(kbaseMod, k32Mod, "GetPrivateProfileSectionW", - hook_GetPrivateProfileSectionW); - installHook(kbaseMod, k32Mod, "WritePrivateProfileStringA", - hook_WritePrivateProfileStringA); - installHook(kbaseMod, k32Mod, "WritePrivateProfileStringW", - hook_WritePrivateProfileStringW); - - installHook(kbaseMod, k32Mod, "GetFullPathNameA", hook_GetFullPathNameA); - installHook(kbaseMod, k32Mod, "GetFullPathNameW", hook_GetFullPathNameW); - - installHook(kbaseMod, k32Mod, "FindFirstFileExW", hook_FindFirstFileExW); - - HMODULE ntdllMod = GetModuleHandleA("ntdll.dll"); - spdlog::get("usvfs")->debug("ntdll.dll at {0:x}", - reinterpret_cast<uintptr_t>(ntdllMod)); - installHook(ntdllMod, nullptr, "NtQueryFullAttributesFile", - hook_NtQueryFullAttributesFile); - installHook(ntdllMod, nullptr, "NtQueryAttributesFile", hook_NtQueryAttributesFile); - installHook(ntdllMod, nullptr, "NtQueryDirectoryFile", hook_NtQueryDirectoryFile); - installHook(ntdllMod, nullptr, "NtQueryDirectoryFileEx", hook_NtQueryDirectoryFileEx); - installHook(ntdllMod, nullptr, "NtQueryObject", hook_NtQueryObject); - installHook(ntdllMod, nullptr, "NtQueryInformationFile", hook_NtQueryInformationFile); - installHook(ntdllMod, nullptr, "NtQueryInformationByName", - hook_NtQueryInformationByName); - installHook(ntdllMod, nullptr, "NtOpenFile", hook_NtOpenFile); - installHook(ntdllMod, nullptr, "NtCreateFile", hook_NtCreateFile); - installHook(ntdllMod, nullptr, "NtClose", hook_NtClose); - installHook(ntdllMod, nullptr, "NtTerminateProcess", hook_NtTerminateProcess); - - installHook(kbaseMod, k32Mod, "LoadLibraryExA", hook_LoadLibraryExA); - installHook(kbaseMod, k32Mod, "LoadLibraryExW", hook_LoadLibraryExW); - - // install this hook late as usvfs is calling it itself for debugging purposes - installHook(kbaseMod, k32Mod, "GetModuleFileNameA", hook_GetModuleFileNameA); - installHook(kbaseMod, k32Mod, "GetModuleFileNameW", hook_GetModuleFileNameW); - - spdlog::get("usvfs")->debug("hooks installed"); - HookLib::TrampolinePool::instance().setBlock(false); -} - -void HookManager::removeHooks() -{ - while (m_Hooks.size() > 0) { - auto iter = m_Hooks.begin(); - try { - RemoveHook(iter->second); - spdlog::get("usvfs")->debug("removed hook {}", iter->first); - } catch (const std::exception& e) { - spdlog::get("usvfs")->critical("failed to remove hook: {}", e.what()); - } - - // remove either way, otherwise this is an endless loop - m_Hooks.erase(iter); - } -} - -} // namespace usvfs |
