diff --git a/kuffix.sln b/kuffix.sln new file mode 100644 index 0000000..a997079 --- /dev/null +++ b/kuffix.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30907.101 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kuffix", "kuffix\kuffix.vcxproj", "{22A53769-F926-42F2-969D-337C3D257CC8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {22A53769-F926-42F2-969D-337C3D257CC8}.Debug|x86.ActiveCfg = Debug|Win32 + {22A53769-F926-42F2-969D-337C3D257CC8}.Debug|x86.Build.0 = Debug|Win32 + {22A53769-F926-42F2-969D-337C3D257CC8}.Release|x86.ActiveCfg = Release|Win32 + {22A53769-F926-42F2-969D-337C3D257CC8}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {397FC045-611B-415B-AD8D-7516974F702B} + EndGlobalSection +EndGlobal diff --git a/kuffix/code_patcher.cc b/kuffix/code_patcher.cc new file mode 100644 index 0000000..2f07075 --- /dev/null +++ b/kuffix/code_patcher.cc @@ -0,0 +1,38 @@ +// Copyright 2016 jeonghun + +#include "code_patcher.h" + +bool code_patcher::apply(void *addr_ptr, const void *code_ptr, uint32_t length) { + bool apply = false; + + if (addr_ptr != nullptr && code_ptr != nullptr && length > 0) { + DWORD protect_flag = 0; + if (VirtualProtect(addr_ptr, length, PAGE_EXECUTE_READWRITE, &protect_flag) != FALSE) { + protect_flag_ = protect_flag; + addr_ptr_ = addr_ptr; + backup_.resize(length); + memcpy(backup_.data(), addr_ptr_, length); + memcpy(addr_ptr, code_ptr, length); + apply = true; + } + } + + return apply; +} + +bool code_patcher::undo() { + bool undo = false; + + if (protect_flag_ != 0) { + memcpy(addr_ptr_, backup_.data(), backup_.size()); + DWORD protect_flag = 0; + if (VirtualProtect(addr_ptr_, backup_.size(), protect_flag_, &protect_flag) != FALSE) { + backup_.clear(); + addr_ptr_ = nullptr; + protect_flag_ = 0; + undo = true; + } + } + + return undo; +} diff --git a/kuffix/code_patcher.h b/kuffix/code_patcher.h new file mode 100644 index 0000000..72375ff --- /dev/null +++ b/kuffix/code_patcher.h @@ -0,0 +1,23 @@ +// Copyright 2016 jeonghun + +#ifndef CODE_PATCHER_H_ +#define CODE_PATCHER_H_ + +#include +#include + +class code_patcher final { + public: + code_patcher() = default; + ~code_patcher() = default; + + bool apply(void *addr_ptr, const void *code_ptr, uint32_t length); + bool undo(); + + private: + std::vector backup_; + void *addr_ptr_ = nullptr; + uint32_t protect_flag_ = 0; +}; + +#endif // CODE_PATCHER_H_ diff --git a/kuffix/dinput8.def b/kuffix/dinput8.def new file mode 100644 index 0000000..02b758c --- /dev/null +++ b/kuffix/dinput8.def @@ -0,0 +1,3 @@ +LIBRARY DINPUT8 +EXPORTS + DirectInput8Create diff --git a/kuffix/dll_loader.h b/kuffix/dll_loader.h new file mode 100644 index 0000000..cd78e0d --- /dev/null +++ b/kuffix/dll_loader.h @@ -0,0 +1,57 @@ +// Copyright 2015 jeonghun +#ifndef DLL_LOADER_H_ +#define DLL_LOADER_H_ + +#include +#include +#include +#include + +#pragma comment(lib, "shlwapi") + +class dll_loader final { + public: + explicit dll_loader(const wchar_t *dll_name, bool load_from_system = false) { + module_ = load_from_system ? NULL : GetModuleHandle(dll_name); + if (module_ == NULL) { + if (load_from_system) { + wchar_t sys_path[MAX_PATH] = { 0 }; + GetSystemDirectory(sys_path, _countof(sys_path)); + PathCombine(sys_path, sys_path, dll_name); + module_ = LoadLibrary(sys_path); + } else { + module_ = LoadLibrary(dll_name); + } + use_loadlib = module_ != NULL; + } + assert(module_ != NULL); + } + + ~dll_loader() { + if (use_loadlib) { + FreeLibrary(module_); + } + } + + dll_loader(const dll_loader&) = delete; + void operator=(const dll_loader&) = delete; + + template + inline T get_func_ptr(const char* api_name) const { + assert(api_name != nullptr); + return reinterpret_cast(GetProcAddress(module_, api_name)); + } + + template + inline std::result_of_t call(const char *api_name, ARGS ...args) const { + auto func_ptr = get_func_ptr(api_name); + assert(func_ptr != nullptr); + return func_ptr(args...); + } + + private: + HMODULE module_ = NULL; + bool use_loadlib = false; +}; + +#endif // DLL_LOADER_H_ diff --git a/kuffix/fps_unlock.cc b/kuffix/fps_unlock.cc new file mode 100644 index 0000000..72b82e5 --- /dev/null +++ b/kuffix/fps_unlock.cc @@ -0,0 +1,27 @@ +// Copyright 2020 jeonghun + +#include "fps_unlock.h" +#include "code_patcher.h" + +namespace fps_unlock { + +code_patcher skip_delay; +code_patcher skip_eval; + +void apply() { + DWORD hinst = reinterpret_cast(GetModuleHandle(NULL)); + const unsigned char nop_5[] = { 0x90, 0x90, 0x90, 0x90, 0x90 }; // NOP NOP NOP NOP NOP + + void* skip_delay_addr = reinterpret_cast(0x001C2239 + hinst); + skip_delay.apply(skip_delay_addr, nop_5, sizeof(nop_5)); + + void* skip_eval_addr = reinterpret_cast(0x001C2241 + hinst); + skip_eval.apply(skip_eval_addr, nop_5, sizeof(nop_5)); +} + +void undo() { + skip_delay.undo(); + skip_eval.undo(); +} + +} // namespace fps_unlock diff --git a/kuffix/fps_unlock.h b/kuffix/fps_unlock.h new file mode 100644 index 0000000..7f5dbcb --- /dev/null +++ b/kuffix/fps_unlock.h @@ -0,0 +1,13 @@ +// Copyright 2020 jeonghun + +#ifndef KUFFIX_FPS_UNLOCK_H_ +#define KUFFIX_FPS_UNLOCK_H_ + +namespace fps_unlock { + +void apply(); +void undo(); + +} // namespace fps_unlock + +#endif // KUFFIX_FPS_UNLOCK_H_ diff --git a/kuffix/kuffix.rc b/kuffix/kuffix.rc new file mode 100644 index 0000000..f7ff203 --- /dev/null +++ b/kuffix/kuffix.rc @@ -0,0 +1,97 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Korean (Korea) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_KOR) +LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT +#pragma code_page(949) + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 0,0,1,0 + PRODUCTVERSION 0,0,1,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "041204b0" + BEGIN + VALUE "FileVersion", "0.0.1.0" + VALUE "LegalCopyright", "Copyright (C) 2020" + VALUE "OriginalFilename", "kuffix.dll" + VALUE "ProductName", "kuffix" + VALUE "ProductVersion", "0.0.1.0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x412, 1200 + END +END + +#endif // Korean (Korea) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/kuffix/kuffix.vcxproj b/kuffix/kuffix.vcxproj new file mode 100644 index 0000000..4611305 --- /dev/null +++ b/kuffix/kuffix.vcxproj @@ -0,0 +1,119 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + 16.0 + Win32Proj + {22a53769-f926-42f2-969d-337c3d257cc8} + kuffix + 10.0 + + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + + + + + + + + + + + + + true + dinput8 + + + false + dinput8 + + + + Level3 + true + WIN32;_DEBUG;KUFFIX_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + precompile.h + precompile.h + MultiThreadedDebug + + + Windows + true + false + dinput8.def + + + + + Level3 + true + true + true + WIN32;NDEBUG;KUFFIX_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + precompile.h + precompile.h + MultiThreaded + + + Windows + true + true + true + false + dinput8.def + + + + + + + + Create + Create + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kuffix/kuffix.vcxproj.filters b/kuffix/kuffix.vcxproj.filters new file mode 100644 index 0000000..59f2ca7 --- /dev/null +++ b/kuffix/kuffix.vcxproj.filters @@ -0,0 +1,58 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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 + + + + + Source Files + + + Source Files + + + Header Files + + + Source Files + + + + + Source Files + + + Source Files + + + Header Files + + + Source Files + + + Resource Files + + + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/kuffix/main.cc b/kuffix/main.cc new file mode 100644 index 0000000..20f97ba --- /dev/null +++ b/kuffix/main.cc @@ -0,0 +1,27 @@ +// Copyright 2020 jeonghun + +#include +#include +#include "dll_loader.h" +#include "fps_unlock.h" + + +static dll_loader dinput8(L"dinput8", true); +HRESULT WINAPI DirectInput8Create(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter) { + return dinput8.call("DirectInput8Create", hinst, dwVersion, riidltf, ppvOut, punkOuter); +} + + +int APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved) { + switch (Reason) { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(hDLL); + fps_unlock::apply(); + break; + + case DLL_PROCESS_DETACH: + break; + } + + return TRUE; +} diff --git a/kuffix/precompile.cc b/kuffix/precompile.cc new file mode 100644 index 0000000..d6fa871 --- /dev/null +++ b/kuffix/precompile.cc @@ -0,0 +1 @@ +// Copyright 2016 jeonghun diff --git a/kuffix/precompile.h b/kuffix/precompile.h new file mode 100644 index 0000000..3cb0718 --- /dev/null +++ b/kuffix/precompile.h @@ -0,0 +1,15 @@ +// Copyright 2016 jeonghun + +#ifndef PRECOMPILE_H_ +#define PRECOMPILE_H_ + +#define _WIN32_WINNT 0x0602 +#define NTDDI_VERSION 0x06020000 +#define DIRECTINPUT_VERSION 0x0800 + +#include +#include +#include +#include + +#endif // PRECOMPILE_H_ diff --git a/kuffix/resource.h b/kuffix/resource.h new file mode 100644 index 0000000..28af58f --- /dev/null +++ b/kuffix/resource.h @@ -0,0 +1,14 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by kuffix.rc + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif