diff --git a/.gitmodules b/.gitmodules
index 6274b5410..3860651bd 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -6,4 +6,7 @@
url = https://github.com/goatcorp/FFXIVClientStructs.git
[submodule "lib/Nomade040-nmd"]
path = lib/Nomade040-nmd
- url = https://github.com/Nomade040/nmd
+ url = https://github.com/Nomade040/nmd.git
+[submodule "lib/TsudaKageyu-minhook"]
+ path = lib/TsudaKageyu-minhook
+ url = https://github.com/TsudaKageyu/minhook.git
diff --git a/Dalamud.Boot/Dalamud.Boot.vcxproj b/Dalamud.Boot/Dalamud.Boot.vcxproj
index 993b2caa2..0366155e4 100644
--- a/Dalamud.Boot/Dalamud.Boot.vcxproj
+++ b/Dalamud.Boot/Dalamud.Boot.vcxproj
@@ -59,6 +59,7 @@
false
_DEBUG;%(PreprocessorDefinitions)
Use
+ 26812
false
@@ -71,6 +72,7 @@
true
NDEBUG;%(PreprocessorDefinitions)
Use
+ 26812
true
@@ -127,6 +129,11 @@
+
+
+ {f142a341-5ee0-442d-a15f-98ae9b48dbae}
+
+
diff --git a/Dalamud.Boot/dllmain.cpp b/Dalamud.Boot/dllmain.cpp
index 243779926..9bf871e80 100644
--- a/Dalamud.Boot/dllmain.cpp
+++ b/Dalamud.Boot/dllmain.cpp
@@ -24,12 +24,7 @@ DllExport DWORD WINAPI Initialize(LPVOID lpParam, HANDLE hMainThreadContinue) {
if (bootconfig::is_wait_messagebox())
MessageBoxW(nullptr, L"Press OK to continue", L"Dalamud Boot", MB_OK);
- try {
- xivfixes::apply_all(true);
- } catch (const std::exception& e) {
- logging::print("Failed to do general fixups. Some things might not work.");
- logging::print("Error: {}", e.what());
- }
+ xivfixes::apply_all(true);
if (bootconfig::is_wait_debugger()) {
logging::print("Waiting for debugger to attach...");
@@ -89,9 +84,24 @@ BOOL APIENTRY DllMain(const HMODULE hModule, const DWORD dwReason, LPVOID lpRese
switch (dwReason) {
case DLL_PROCESS_ATTACH:
g_hModule = hModule;
+ if (const auto mhStatus = MH_Initialize(); MH_OK != mhStatus) {
+ logging::print("Failed to initialize MinHook (status={})", static_cast(mhStatus));
+ return FALSE;
+ }
+
+ logging::update_dll_load_status(true);
break;
+
case DLL_PROCESS_DETACH:
+ logging::update_dll_load_status(false);
+
xivfixes::apply_all(false);
+
+ if (const auto mhStatus = MH_Uninitialize(); MH_OK != mhStatus) {
+ logging::print("Failed to uninitialize MinHook (status={})", static_cast(mhStatus));
+ __fastfail(logging::MinHookUnload);
+ }
+
veh::remove_handler();
//logging::log_file.close();
break;
diff --git a/Dalamud.Boot/hooks.h b/Dalamud.Boot/hooks.h
index ac8f93b21..3ad907495 100644
--- a/Dalamud.Boot/hooks.h
+++ b/Dalamud.Boot/hooks.h
@@ -71,45 +71,31 @@ namespace hooks {
}
};
- template
- class export_hook : public base_hook {
+ template
+ class direct_hook;
+
+ template
+ class direct_hook : public base_hook {
+ using TFn = TReturn(TArgs...);
using Base = base_hook;
- static constexpr uint8_t DetouringThunkTemplate[12]{
- 0x48, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // movabs rax, 0x0000000000000000
- 0xFF, 0xE0, // jmp rax
- };
-
- TFn* const m_pfnExportThunk;
- uint8_t s_originalThunk[sizeof DetouringThunkTemplate]{};
+ TFn* m_pfnMinHookBridge;
public:
- export_hook(TFn* pfnExportThunk)
- : Base(reinterpret_cast(utils::resolve_unconditional_jump_target(pfnExportThunk)))
- , m_pfnExportThunk(pfnExportThunk) {
- auto pExportThunk = reinterpret_cast(pfnExportThunk);
+ direct_hook(TFn* pfnFunction)
+ : Base(pfnFunction) {
+ if (const auto mhStatus = MH_CreateHook(pfnFunction, Base::get_thunk(), reinterpret_cast(&m_pfnMinHookBridge)); mhStatus != MH_OK)
+ throw std::runtime_error(std::format("MH_CreateHook(0x{:X}, ...) failure: {}", reinterpret_cast(pfnFunction), static_cast(mhStatus)));
- // Make it writeable.
- const utils::memory_tenderizer tenderizer(pfnExportThunk, sizeof DetouringThunkTemplate, PAGE_EXECUTE_READWRITE);
-
- // Back up original thunk bytes.
- memcpy(s_originalThunk, pExportThunk, sizeof s_originalThunk);
-
- // Write thunk template.
- memcpy(pExportThunk, DetouringThunkTemplate, sizeof DetouringThunkTemplate);
-
- // Write target address.
- *reinterpret_cast(&pExportThunk[2]) = Base::get_thunk();
+ MH_EnableHook(Base::get_original());
}
- ~export_hook() override {
- const utils::memory_tenderizer tenderizer(m_pfnExportThunk, sizeof DetouringThunkTemplate, PAGE_EXECUTE_READWRITE);
+ ~direct_hook() override {
+ MH_DisableHook(Base::get_original());
+ }
- // Restore original thunk bytes.
- memcpy(m_pfnExportThunk, s_originalThunk, sizeof s_originalThunk);
-
- // Clear state.
- memset(s_originalThunk, 0, sizeof s_originalThunk);
+ TReturn call_original(TArgs... args) override {
+ return m_pfnMinHookBridge(std::forward(args)...);
}
};
diff --git a/Dalamud.Boot/logging.cpp b/Dalamud.Boot/logging.cpp
index 7d977eaa3..73c5a02f0 100644
--- a/Dalamud.Boot/logging.cpp
+++ b/Dalamud.Boot/logging.cpp
@@ -1,6 +1,8 @@
#include "pch.h"
#include "logging.h"
+static bool s_bLoaded = false;
+
void logging::print(Level level, const char* s) {
SYSTEMTIME st;
GetLocalTime(&st);
@@ -30,12 +32,21 @@ void logging::print(Level level, const char* s) {
break;
}
- DWORD wr;
- WriteFile(GetStdHandle(STD_ERROR_HANDLE), &estr[0], static_cast(estr.size()), &wr, nullptr);
+ OutputDebugStringW(unicode::convert(estr).c_str());
- if (log_file.is_open())
- {
- log_file << estr;
- log_file.flush();
+ // Handle accesses should not be done during DllMain process attach/detach calls
+ if (s_bLoaded) {
+ DWORD wr{};
+ WriteFile(GetStdHandle(STD_ERROR_HANDLE), &estr[0], static_cast(estr.size()), &wr, nullptr);
+
+ if (log_file.is_open())
+ {
+ log_file << estr;
+ log_file.flush();
+ }
}
}
+
+void logging::update_dll_load_status(bool loaded) {
+ s_bLoaded = loaded;
+}
diff --git a/Dalamud.Boot/logging.h b/Dalamud.Boot/logging.h
index 3b2204ee8..e661cac17 100644
--- a/Dalamud.Boot/logging.h
+++ b/Dalamud.Boot/logging.h
@@ -25,6 +25,11 @@ namespace logging {
F = 5,
};
+ enum FastFailErrorCode : int {
+ Unspecified = 12345,
+ MinHookUnload,
+ };
+
void print(Level level, const char* s);
inline void print(Level level, const wchar_t* s) {
@@ -59,4 +64,6 @@ namespace logging {
inline void print(const T* pcszFormat, Arg arg1, Args...args) {
print(level, std::format(pcszFormat, std::forward(arg1), std::forward(args)...));
}
+
+ void update_dll_load_status(bool loaded);
};
diff --git a/Dalamud.Boot/pch.h b/Dalamud.Boot/pch.h
index 01cb992a0..f217f439b 100644
--- a/Dalamud.Boot/pch.h
+++ b/Dalamud.Boot/pch.h
@@ -40,6 +40,9 @@
// https://www.akenotsuki.com/misc/srell/en/
#include "../lib/srell3_009/single-header/srell.hpp"
+// https://github.com/TsudaKageyu/minhook
+#include "../lib/TsudaKageyu-minhook/include/MinHook.h"
+
// https://github.com/Nomade040/nmd
#include "../lib/Nomade040-nmd/nmd_assembly.h"
diff --git a/Dalamud.Boot/utils.cpp b/Dalamud.Boot/utils.cpp
index 7294fab08..f7551b149 100644
--- a/Dalamud.Boot/utils.cpp
+++ b/Dalamud.Boot/utils.cpp
@@ -229,17 +229,6 @@ std::shared_ptr utils::allocate_executable_heap(size_t len) {
};
}
-void* utils::resolve_unconditional_jump_target(void* pfn) {
- const auto bytes = reinterpret_cast(pfn);
-
- // JMP QWORD PTR [RIP + int32]
- // 48 FF 25 ?? ?? ?? ??
- if (bytes[0] == 0x48 && bytes[1] == 0xFF && bytes[2] == 0x25)
- return *reinterpret_cast(&bytes[7 + *reinterpret_cast(&bytes[3])]);
-
- throw std::runtime_error("Unexpected thunk bytes.");
-}
-
template
static bool find_imported_function_pointer_helper(const char* pcBaseAddress, const IMAGE_IMPORT_DESCRIPTOR& desc, const IMAGE_DATA_DIRECTORY& dir, std::string_view reqFunc, uint32_t hintOrOrdinal, void*& ppFunctionAddress) {
const auto importLookupsOversizedSpan = std::span(reinterpret_cast(&pcBaseAddress[desc.OriginalFirstThunk]), (dir.Size - desc.OriginalFirstThunk) / sizeof TEntryType);
diff --git a/Dalamud.Boot/utils.h b/Dalamud.Boot/utils.h
index 9180e0c8e..6a56809ca 100644
--- a/Dalamud.Boot/utils.h
+++ b/Dalamud.Boot/utils.h
@@ -57,8 +57,6 @@ namespace utils {
~memory_tenderizer();
};
- void* resolve_unconditional_jump_target(void* pfn);
-
bool find_imported_function_pointer(HMODULE hModule, const char* pcszDllName, const char* pcszFunctionName, uint32_t hintOrOrdinal, void*& ppFunctionAddress);
void* get_imported_function_pointer(HMODULE hModule, const char* pcszDllName, const char* pcszFunctionName, uint32_t hintOrOrdinal);
diff --git a/Dalamud.Boot/xivfixes.cpp b/Dalamud.Boot/xivfixes.cpp
index 0c29e7d10..cc5c8a0b4 100644
--- a/Dalamud.Boot/xivfixes.cpp
+++ b/Dalamud.Boot/xivfixes.cpp
@@ -108,11 +108,11 @@ void xivfixes::disable_game_openprocess_access_check(bool bApply) {
void xivfixes::redirect_openprocess(bool bApply) {
static const char* LogTag = "[xivfixes:redirect_openprocess]";
- static std::optional> hook;
+ static std::optional> hook;
if (bApply) {
logging::print("{} Enable", LogTag);
- hook.emplace(::OpenProcess);
+ hook.emplace(OpenProcess);
hook->set_detour([](DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)->HANDLE {
if (dwProcessId == GetCurrentProcessId()) {
logging::print("{} OpenProcess(0{:08X}, {}, {}) was invoked by thread {}. Redirecting to DuplicateHandle.", LogTag, dwDesiredAccess, bInheritHandle, dwProcessId, GetCurrentThreadId());
@@ -130,3 +130,30 @@ void xivfixes::redirect_openprocess(bool bApply) {
hook.reset();
}
}
+
+void xivfixes::apply_all(bool bApply) {
+ for (const auto& [taskName, taskFunction] : std::initializer_list>
+ {
+ { "prevent_devicechange_crashes", &prevent_devicechange_crashes },
+ { "disable_game_openprocess_access_check", &disable_game_openprocess_access_check },
+ { "redirect_openprocess", &redirect_openprocess },
+ }
+ ) {
+ try {
+ taskFunction(bApply);
+
+ } catch (const std::exception& e) {
+ if (bApply)
+ logging::print("Error trying to activate fixup [{}]: {}", taskName, e.what());
+ else
+ logging::print("Error trying to deactivate fixup [{}]: {}", taskName, e.what());
+
+ continue;
+ }
+
+ if (bApply)
+ logging::print("Fixup [{}] activated.", taskName);
+ else
+ logging::print("Fixup [{}] deactivated.", taskName);
+ }
+}
diff --git a/Dalamud.Boot/xivfixes.h b/Dalamud.Boot/xivfixes.h
index ff617bee8..c4a6f3666 100644
--- a/Dalamud.Boot/xivfixes.h
+++ b/Dalamud.Boot/xivfixes.h
@@ -5,9 +5,5 @@ namespace xivfixes {
void disable_game_openprocess_access_check(bool bApply);
void redirect_openprocess(bool bApply);
- inline void apply_all(bool bApply) {
- prevent_devicechange_crashes(bApply);
- disable_game_openprocess_access_check(bApply);
- redirect_openprocess(bApply);
- }
+ void apply_all(bool bApply);
}
diff --git a/Dalamud.sln b/Dalamud.sln
index bdb771989..f4167f9ed 100644
--- a/Dalamud.sln
+++ b/Dalamud.sln
@@ -34,110 +34,172 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FFXIVClientStructs", "lib\F
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FFXIVClientStructs.Generators", "lib\FFXIVClientStructs\FFXIVClientStructs.Generators\FFXIVClientStructs.Generators.csproj", "{05AB2F46-268B-4915-806F-DDF813E2D59D}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libMinHook", "lib\TsudaKageyu-minhook\build\VC16\libMinHook.vcxproj", "{F142A341-5EE0-442D-A15F-98AE9B48DBAE}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
+ Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{94E5B016-02B1-459B-97D9-E783F28764B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{94E5B016-02B1-459B-97D9-E783F28764B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{94E5B016-02B1-459B-97D9-E783F28764B2}.Debug|x64.ActiveCfg = Debug|Any CPU
{94E5B016-02B1-459B-97D9-E783F28764B2}.Debug|x64.Build.0 = Debug|Any CPU
+ {94E5B016-02B1-459B-97D9-E783F28764B2}.Debug|x86.ActiveCfg = Debug|Any CPU
{94E5B016-02B1-459B-97D9-E783F28764B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{94E5B016-02B1-459B-97D9-E783F28764B2}.Release|Any CPU.Build.0 = Release|Any CPU
{94E5B016-02B1-459B-97D9-E783F28764B2}.Release|x64.ActiveCfg = Release|Any CPU
{94E5B016-02B1-459B-97D9-E783F28764B2}.Release|x64.Build.0 = Release|Any CPU
+ {94E5B016-02B1-459B-97D9-E783F28764B2}.Release|x86.ActiveCfg = Release|Any CPU
{B92DAB43-2279-4A2C-96E3-D9D5910EDBEA}.Debug|Any CPU.ActiveCfg = Debug|x64
{B92DAB43-2279-4A2C-96E3-D9D5910EDBEA}.Debug|Any CPU.Build.0 = Debug|x64
{B92DAB43-2279-4A2C-96E3-D9D5910EDBEA}.Debug|x64.ActiveCfg = Debug|x64
{B92DAB43-2279-4A2C-96E3-D9D5910EDBEA}.Debug|x64.Build.0 = Debug|x64
+ {B92DAB43-2279-4A2C-96E3-D9D5910EDBEA}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B92DAB43-2279-4A2C-96E3-D9D5910EDBEA}.Debug|x86.Build.0 = Debug|Any CPU
{B92DAB43-2279-4A2C-96E3-D9D5910EDBEA}.Release|Any CPU.ActiveCfg = Release|x64
{B92DAB43-2279-4A2C-96E3-D9D5910EDBEA}.Release|Any CPU.Build.0 = Release|x64
{B92DAB43-2279-4A2C-96E3-D9D5910EDBEA}.Release|x64.ActiveCfg = Release|x64
{B92DAB43-2279-4A2C-96E3-D9D5910EDBEA}.Release|x64.Build.0 = Release|x64
+ {B92DAB43-2279-4A2C-96E3-D9D5910EDBEA}.Release|x86.ActiveCfg = Release|Any CPU
+ {B92DAB43-2279-4A2C-96E3-D9D5910EDBEA}.Release|x86.Build.0 = Release|Any CPU
{55198DC3-A03D-408E-A8EB-2077780C8576}.Debug|Any CPU.ActiveCfg = Debug|x64
{55198DC3-A03D-408E-A8EB-2077780C8576}.Debug|Any CPU.Build.0 = Debug|x64
{55198DC3-A03D-408E-A8EB-2077780C8576}.Debug|x64.ActiveCfg = Debug|x64
{55198DC3-A03D-408E-A8EB-2077780C8576}.Debug|x64.Build.0 = Debug|x64
+ {55198DC3-A03D-408E-A8EB-2077780C8576}.Debug|x86.ActiveCfg = Debug|x64
+ {55198DC3-A03D-408E-A8EB-2077780C8576}.Debug|x86.Build.0 = Debug|x64
{55198DC3-A03D-408E-A8EB-2077780C8576}.Release|Any CPU.ActiveCfg = Release|x64
{55198DC3-A03D-408E-A8EB-2077780C8576}.Release|Any CPU.Build.0 = Release|x64
{55198DC3-A03D-408E-A8EB-2077780C8576}.Release|x64.ActiveCfg = Release|x64
{55198DC3-A03D-408E-A8EB-2077780C8576}.Release|x64.Build.0 = Release|x64
+ {55198DC3-A03D-408E-A8EB-2077780C8576}.Release|x86.ActiveCfg = Release|x64
+ {55198DC3-A03D-408E-A8EB-2077780C8576}.Release|x86.Build.0 = Release|x64
{5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Debug|Any CPU.ActiveCfg = Debug|x64
{5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Debug|Any CPU.Build.0 = Debug|x64
{5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Debug|x64.ActiveCfg = Debug|x64
{5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Debug|x64.Build.0 = Debug|x64
+ {5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Debug|x86.Build.0 = Debug|Any CPU
{5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Release|Any CPU.ActiveCfg = Release|x64
{5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Release|Any CPU.Build.0 = Release|x64
{5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Release|x64.ActiveCfg = Release|x64
{5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Release|x64.Build.0 = Release|x64
+ {5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Release|x86.ActiveCfg = Release|Any CPU
+ {5B832F73-5F54-4ADC-870F-D0095EF72C9A}.Release|x86.Build.0 = Release|Any CPU
{8874326B-E755-4D13-90B4-59AB263A3E6B}.Debug|Any CPU.ActiveCfg = Debug|x64
{8874326B-E755-4D13-90B4-59AB263A3E6B}.Debug|Any CPU.Build.0 = Debug|x64
{8874326B-E755-4D13-90B4-59AB263A3E6B}.Debug|x64.ActiveCfg = Debug|x64
{8874326B-E755-4D13-90B4-59AB263A3E6B}.Debug|x64.Build.0 = Debug|x64
+ {8874326B-E755-4D13-90B4-59AB263A3E6B}.Debug|x86.ActiveCfg = Debug|x64
+ {8874326B-E755-4D13-90B4-59AB263A3E6B}.Debug|x86.Build.0 = Debug|x64
{8874326B-E755-4D13-90B4-59AB263A3E6B}.Release|Any CPU.ActiveCfg = Release|x64
{8874326B-E755-4D13-90B4-59AB263A3E6B}.Release|Any CPU.Build.0 = Release|x64
{8874326B-E755-4D13-90B4-59AB263A3E6B}.Release|x64.ActiveCfg = Release|x64
{8874326B-E755-4D13-90B4-59AB263A3E6B}.Release|x64.Build.0 = Release|x64
+ {8874326B-E755-4D13-90B4-59AB263A3E6B}.Release|x86.ActiveCfg = Release|x64
+ {8874326B-E755-4D13-90B4-59AB263A3E6B}.Release|x86.Build.0 = Release|x64
{C8004563-1806-4329-844F-0EF6274291FC}.Debug|Any CPU.ActiveCfg = Debug|x64
{C8004563-1806-4329-844F-0EF6274291FC}.Debug|Any CPU.Build.0 = Debug|x64
{C8004563-1806-4329-844F-0EF6274291FC}.Debug|x64.ActiveCfg = Debug|x64
{C8004563-1806-4329-844F-0EF6274291FC}.Debug|x64.Build.0 = Debug|x64
+ {C8004563-1806-4329-844F-0EF6274291FC}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C8004563-1806-4329-844F-0EF6274291FC}.Debug|x86.Build.0 = Debug|Any CPU
{C8004563-1806-4329-844F-0EF6274291FC}.Release|Any CPU.ActiveCfg = Release|x64
{C8004563-1806-4329-844F-0EF6274291FC}.Release|Any CPU.Build.0 = Release|x64
{C8004563-1806-4329-844F-0EF6274291FC}.Release|x64.ActiveCfg = Release|x64
{C8004563-1806-4329-844F-0EF6274291FC}.Release|x64.Build.0 = Release|x64
+ {C8004563-1806-4329-844F-0EF6274291FC}.Release|x86.ActiveCfg = Release|Any CPU
+ {C8004563-1806-4329-844F-0EF6274291FC}.Release|x86.Build.0 = Release|Any CPU
{0483026E-C6CE-4B1A-AA68-46544C08140B}.Debug|Any CPU.ActiveCfg = Debug|x64
{0483026E-C6CE-4B1A-AA68-46544C08140B}.Debug|Any CPU.Build.0 = Debug|x64
{0483026E-C6CE-4B1A-AA68-46544C08140B}.Debug|x64.ActiveCfg = Debug|x64
{0483026E-C6CE-4B1A-AA68-46544C08140B}.Debug|x64.Build.0 = Debug|x64
+ {0483026E-C6CE-4B1A-AA68-46544C08140B}.Debug|x86.ActiveCfg = Debug|x64
+ {0483026E-C6CE-4B1A-AA68-46544C08140B}.Debug|x86.Build.0 = Debug|x64
{0483026E-C6CE-4B1A-AA68-46544C08140B}.Release|Any CPU.ActiveCfg = Release|x64
{0483026E-C6CE-4B1A-AA68-46544C08140B}.Release|Any CPU.Build.0 = Release|x64
{0483026E-C6CE-4B1A-AA68-46544C08140B}.Release|x64.ActiveCfg = Release|x64
{0483026E-C6CE-4B1A-AA68-46544C08140B}.Release|x64.Build.0 = Release|x64
+ {0483026E-C6CE-4B1A-AA68-46544C08140B}.Release|x86.ActiveCfg = Release|x64
+ {0483026E-C6CE-4B1A-AA68-46544C08140B}.Release|x86.Build.0 = Release|x64
{C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Debug|Any CPU.ActiveCfg = Debug|x64
{C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Debug|Any CPU.Build.0 = Debug|x64
{C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Debug|x64.ActiveCfg = Debug|x64
{C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Debug|x64.Build.0 = Debug|x64
+ {C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Debug|x86.ActiveCfg = Debug|x64
+ {C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Debug|x86.Build.0 = Debug|x64
{C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Release|Any CPU.ActiveCfg = Release|x64
{C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Release|Any CPU.Build.0 = Release|x64
{C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Release|x64.ActiveCfg = Release|x64
{C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Release|x64.Build.0 = Release|x64
+ {C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Release|x86.ActiveCfg = Release|x64
+ {C0E7E797-4FBF-4F46-BC57-463F3719BA7A}.Release|x86.Build.0 = Release|x64
{2F7FF0A8-B619-4572-86C7-71E46FE22FB8}.Debug|Any CPU.ActiveCfg = Debug|x64
{2F7FF0A8-B619-4572-86C7-71E46FE22FB8}.Debug|Any CPU.Build.0 = Debug|x64
{2F7FF0A8-B619-4572-86C7-71E46FE22FB8}.Debug|x64.ActiveCfg = Debug|x64
{2F7FF0A8-B619-4572-86C7-71E46FE22FB8}.Debug|x64.Build.0 = Debug|x64
+ {2F7FF0A8-B619-4572-86C7-71E46FE22FB8}.Debug|x86.ActiveCfg = Debug|x64
+ {2F7FF0A8-B619-4572-86C7-71E46FE22FB8}.Debug|x86.Build.0 = Debug|x64
{2F7FF0A8-B619-4572-86C7-71E46FE22FB8}.Release|Any CPU.ActiveCfg = Release|x64
{2F7FF0A8-B619-4572-86C7-71E46FE22FB8}.Release|Any CPU.Build.0 = Release|x64
{2F7FF0A8-B619-4572-86C7-71E46FE22FB8}.Release|x64.ActiveCfg = Release|x64
{2F7FF0A8-B619-4572-86C7-71E46FE22FB8}.Release|x64.Build.0 = Release|x64
+ {2F7FF0A8-B619-4572-86C7-71E46FE22FB8}.Release|x86.ActiveCfg = Release|x64
+ {2F7FF0A8-B619-4572-86C7-71E46FE22FB8}.Release|x86.Build.0 = Release|x64
{4AFDB34A-7467-4D41-B067-53BC4101D9D0}.Debug|Any CPU.ActiveCfg = Debug|x64
{4AFDB34A-7467-4D41-B067-53BC4101D9D0}.Debug|Any CPU.Build.0 = Debug|x64
{4AFDB34A-7467-4D41-B067-53BC4101D9D0}.Debug|x64.ActiveCfg = Debug|x64
{4AFDB34A-7467-4D41-B067-53BC4101D9D0}.Debug|x64.Build.0 = Debug|x64
+ {4AFDB34A-7467-4D41-B067-53BC4101D9D0}.Debug|x86.ActiveCfg = Debug|x64
+ {4AFDB34A-7467-4D41-B067-53BC4101D9D0}.Debug|x86.Build.0 = Debug|x64
{4AFDB34A-7467-4D41-B067-53BC4101D9D0}.Release|Any CPU.ActiveCfg = Release|x64
{4AFDB34A-7467-4D41-B067-53BC4101D9D0}.Release|Any CPU.Build.0 = Release|x64
{4AFDB34A-7467-4D41-B067-53BC4101D9D0}.Release|x64.ActiveCfg = Release|x64
{4AFDB34A-7467-4D41-B067-53BC4101D9D0}.Release|x64.Build.0 = Release|x64
+ {4AFDB34A-7467-4D41-B067-53BC4101D9D0}.Release|x86.ActiveCfg = Release|x64
+ {4AFDB34A-7467-4D41-B067-53BC4101D9D0}.Release|x86.Build.0 = Release|x64
{C9B87BD7-AF49-41C3-91F1-D550ADEB7833}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C9B87BD7-AF49-41C3-91F1-D550ADEB7833}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C9B87BD7-AF49-41C3-91F1-D550ADEB7833}.Debug|x64.ActiveCfg = Debug|Any CPU
{C9B87BD7-AF49-41C3-91F1-D550ADEB7833}.Debug|x64.Build.0 = Debug|Any CPU
+ {C9B87BD7-AF49-41C3-91F1-D550ADEB7833}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C9B87BD7-AF49-41C3-91F1-D550ADEB7833}.Debug|x86.Build.0 = Debug|Any CPU
{C9B87BD7-AF49-41C3-91F1-D550ADEB7833}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C9B87BD7-AF49-41C3-91F1-D550ADEB7833}.Release|Any CPU.Build.0 = Release|Any CPU
{C9B87BD7-AF49-41C3-91F1-D550ADEB7833}.Release|x64.ActiveCfg = Release|Any CPU
{C9B87BD7-AF49-41C3-91F1-D550ADEB7833}.Release|x64.Build.0 = Release|Any CPU
+ {C9B87BD7-AF49-41C3-91F1-D550ADEB7833}.Release|x86.ActiveCfg = Release|Any CPU
+ {C9B87BD7-AF49-41C3-91F1-D550ADEB7833}.Release|x86.Build.0 = Release|Any CPU
{05AB2F46-268B-4915-806F-DDF813E2D59D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{05AB2F46-268B-4915-806F-DDF813E2D59D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{05AB2F46-268B-4915-806F-DDF813E2D59D}.Debug|x64.ActiveCfg = Debug|Any CPU
{05AB2F46-268B-4915-806F-DDF813E2D59D}.Debug|x64.Build.0 = Debug|Any CPU
+ {05AB2F46-268B-4915-806F-DDF813E2D59D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {05AB2F46-268B-4915-806F-DDF813E2D59D}.Debug|x86.Build.0 = Debug|Any CPU
{05AB2F46-268B-4915-806F-DDF813E2D59D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{05AB2F46-268B-4915-806F-DDF813E2D59D}.Release|Any CPU.Build.0 = Release|Any CPU
{05AB2F46-268B-4915-806F-DDF813E2D59D}.Release|x64.ActiveCfg = Release|Any CPU
{05AB2F46-268B-4915-806F-DDF813E2D59D}.Release|x64.Build.0 = Release|Any CPU
+ {05AB2F46-268B-4915-806F-DDF813E2D59D}.Release|x86.ActiveCfg = Release|Any CPU
+ {05AB2F46-268B-4915-806F-DDF813E2D59D}.Release|x86.Build.0 = Release|Any CPU
+ {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|Any CPU.Build.0 = Debug|x64
+ {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|x64.ActiveCfg = Debug|x64
+ {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|x64.Build.0 = Debug|x64
+ {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|x86.ActiveCfg = Debug|Win32
+ {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|x86.Build.0 = Debug|Win32
+ {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|Any CPU.ActiveCfg = Release|x64
+ {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|Any CPU.Build.0 = Release|x64
+ {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|x64.ActiveCfg = Release|x64
+ {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|x64.Build.0 = Release|x64
+ {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|x86.ActiveCfg = Release|Win32
+ {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -148,6 +210,7 @@ Global
{2F7FF0A8-B619-4572-86C7-71E46FE22FB8} = {E15BDA6D-E881-4482-94BA-BE5527E917FF}
{C9B87BD7-AF49-41C3-91F1-D550ADEB7833} = {E15BDA6D-E881-4482-94BA-BE5527E917FF}
{05AB2F46-268B-4915-806F-DDF813E2D59D} = {E15BDA6D-E881-4482-94BA-BE5527E917FF}
+ {F142A341-5EE0-442D-A15F-98AE9B48DBAE} = {E15BDA6D-E881-4482-94BA-BE5527E917FF}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {79B65AC9-C940-410E-AB61-7EA7E12C7599}
diff --git a/lib/TsudaKageyu-minhook b/lib/TsudaKageyu-minhook
new file mode 160000
index 000000000..4a455528f
--- /dev/null
+++ b/lib/TsudaKageyu-minhook
@@ -0,0 +1 @@
+Subproject commit 4a455528f61b5a375b1f9d44e7d296d47f18bb18