From a9415e540558b31824bbc7361aad229c0de85003 Mon Sep 17 00:00:00 2001 From: ThirteenAG Date: Fri, 27 Oct 2023 00:46:46 +0800 Subject: [PATCH] extended versioninfo, bugfixes --- .github/funding.yml | 4 ++ appveyor.yml | 2 +- premake5.lua | 56 ++++++++++++++++----- source/dllmain.cpp | 84 ++++++++++++++++++++++++++++++-- source/resources/Versioninfo.rc | Bin 2968 -> 3312 bytes 5 files changed, 131 insertions(+), 15 deletions(-) create mode 100644 .github/funding.yml diff --git a/.github/funding.yml b/.github/funding.yml new file mode 100644 index 0000000..3827534 --- /dev/null +++ b/.github/funding.yml @@ -0,0 +1,4 @@ +github: ThirteenAG +ko_fi: thirteenag +patreon: ThirteenAG +custom: [https://paypal.me/SergeyP13, https://boosty.to/thirteenag/donate] \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index 0edc30b..9119457 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 6.{build} +version: 6.{build}.0 skip_tags: true image: Visual Studio 2022 configuration: Release diff --git a/premake5.lua b/premake5.lua index 59aa06c..0741090 100644 --- a/premake5.lua +++ b/premake5.lua @@ -14,14 +14,31 @@ workspace "Ultimate-ASI-Loader-Win32" defines { "rsc_CompanyName=\"ThirteenAG\"" } defines { "rsc_LegalCopyright=\"MIT License\""} - if(_OPTIONS["with-version"]) then - defines { "rsc_FileVersion=\"" .. _OPTIONS["with-version"] .. "\"", "rsc_ProductVersion=\"" .. _OPTIONS["with-version"] .. "\"" } - else - defines { "rsc_FileVersion=\"1.0.0.0\"", "rsc_ProductVersion=\"1.0.0.0\"" } - end defines { "rsc_InternalName=\"%{prj.name}\"", "rsc_ProductName=\"%{prj.name}\"", "rsc_OriginalFilename=\"%{prj.name}.dll\"" } defines { "rsc_FileDescription=\"Ultimate ASI Loader\"" } defines { "rsc_UpdateUrl=\"https://github.com/ThirteenAG/Ultimate-ASI-Loader\"" } + + local major = 1 + local minor = 0 + local build = 0 + local revision = 0 + if(_OPTIONS["with-version"]) then + local t = {} + for i in _OPTIONS["with-version"]:gmatch("([^.]+)") do + t[#t + 1], _ = i:gsub("%D+", "") + end + while #t < 4 do t[#t + 1] = 0 end + major = math.min(tonumber(t[1]), 255) + minor = math.min(tonumber(t[2]), 255) + build = math.min(tonumber(t[3]), 65535) + revision = math.min(tonumber(t[4]), 65535) + end + defines { "rsc_FileVersion_MAJOR=" .. major } + defines { "rsc_FileVersion_MINOR=" .. minor } + defines { "rsc_FileVersion_BUILD=" .. build } + defines { "rsc_FileVersion_REVISION=" .. revision } + defines { "rsc_FileVersion=\"" .. major .. "." .. minor .. "." .. build .. "\"" } + defines { "rsc_ProductVersion=\"" .. major .. "." .. minor .. "." .. build .. "\"" } project "Ultimate-ASI-Loader-Win32" kind "SharedLib" @@ -159,15 +176,32 @@ workspace "Ultimate-ASI-Loader-x64" defines { "rsc_CompanyName=\"ThirteenAG\"" } defines { "rsc_LegalCopyright=\"MIT License\""} - if(_OPTIONS["with-version"]) then - defines { "rsc_FileVersion=\"" .. _OPTIONS["with-version"] .. "\"", "rsc_ProductVersion=\"" .. _OPTIONS["with-version"] .. "\"" } - else - defines { "rsc_FileVersion=\"1.0.0.0\"", "rsc_ProductVersion=\"1.0.0.0\"" } - end defines { "rsc_InternalName=\"%{prj.name}\"", "rsc_ProductName=\"%{prj.name}\"", "rsc_OriginalFilename=\"%{prj.name}.dll\"" } defines { "rsc_FileDescription=\"Ultimate ASI Loader\"" } defines { "rsc_UpdateUrl=\"https://github.com/ThirteenAG/Ultimate-ASI-Loader\"" } - + + local major = 1 + local minor = 0 + local build = 0 + local revision = 0 + if(_OPTIONS["with-version"]) then + local t = {} + for i in _OPTIONS["with-version"]:gmatch("([^.]+)") do + t[#t + 1], _ = i:gsub("%D+", "") + end + while #t < 4 do t[#t + 1] = 0 end + major = math.min(tonumber(t[1]), 255) + minor = math.min(tonumber(t[2]), 255) + build = math.min(tonumber(t[3]), 65535) + revision = math.min(tonumber(t[4]), 65535) + end + defines { "rsc_FileVersion_MAJOR=" .. major } + defines { "rsc_FileVersion_MINOR=" .. minor } + defines { "rsc_FileVersion_BUILD=" .. build } + defines { "rsc_FileVersion_REVISION=" .. revision } + defines { "rsc_FileVersion=\"" .. major .. "." .. minor .. "." .. build .. "\"" } + defines { "rsc_ProductVersion=\"" .. major .. "." .. minor .. "." .. build .. "\"" } + defines { "X64" } project "Ultimate-ASI-Loader-x64" diff --git a/source/dllmain.cpp b/source/dllmain.cpp index aab2cba..0b91f19 100644 --- a/source/dllmain.cpp +++ b/source/dllmain.cpp @@ -193,7 +193,15 @@ enum Kernel32ExportsData Kernel32ExportsDataCount }; +enum OLE32ExportsNames +{ + eCoCreateInstance, + + OLE32ExportsNamesCount +}; + size_t Kernel32Data[Kernel32ExportsNamesCount][Kernel32ExportsDataCount]; +size_t OLE32Data[OLE32ExportsNamesCount][Kernel32ExportsDataCount]; #if !X64 #define IDR_VORBISF 101 @@ -749,12 +757,61 @@ std::filesystem::path GetFileName(auto lpFilename) return str1.starts_with(str2); }; + static auto lexicallyRelativeCaseIns = [](const std::filesystem::path& path, const std::filesystem::path& base) -> std::filesystem::path + { + class input_iterator_range + { + public: + input_iterator_range(const std::filesystem::path::const_iterator& first, const std::filesystem::path::const_iterator& last) + : _first(first) + , _last(last) + {} + std::filesystem::path::const_iterator begin() const { return _first; } + std::filesystem::path::const_iterator end() const { return _last; } + private: + std::filesystem::path::const_iterator _first; + std::filesystem::path::const_iterator _last; + }; + + if (!iequals(path.root_name().wstring(), base.root_name().wstring()) || path.is_absolute() != base.is_absolute() || (!path.has_root_directory() && base.has_root_directory())) { + return std::filesystem::path(); + } + std::filesystem::path::const_iterator a = path.begin(), b = base.begin(); + while (a != path.end() && b != base.end() && iequals(a->wstring(), b->wstring())) { + ++a; + ++b; + } + if (a == path.end() && b == base.end()) { + return std::filesystem::path("."); + } + int count = 0; + for (const auto& element : input_iterator_range(b, base.end())) { + if (element != "." && element != "" && element != "..") { + ++count; + } + else if (element == "..") { + --count; + } + } + if (count < 0) { + return std::filesystem::path(); + } + std::filesystem::path result; + for (int i = 0; i < count; ++i) { + result /= ".."; + } + for (const auto& element : input_iterator_range(a, path.end())) { + result /= element; + } + return result; + }; + if (gamePath.empty()) gamePath = std::filesystem::path(GetExeModulePath()); auto filePath = std::filesystem::path(lpFilename); auto absolutePath = std::filesystem::absolute(filePath, ec); - auto relativePath = std::filesystem::canonical(absolutePath, ec).lexically_relative(gamePath); + auto relativePath = lexicallyRelativeCaseIns(absolutePath, gamePath); auto commonPath = gamePath; if (starts_with(relativePath, "..")) @@ -899,7 +956,7 @@ HRESULT WINAPI CustomCoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWOR else if (rclsid == CLSID_WinInet) hDll = ::LoadLibrary(L"wininet.dll"); - if (hDll == NULL) + if (hDll == NULL || GetProcAddress(hDll, "IsUltimateASILoader") != NULL) return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv); typedef HRESULT(__stdcall *pDllGetClassObject)(IN REFCLSID rclsid, IN REFIID riid, OUT LPVOID FAR* ppv); @@ -1157,6 +1214,9 @@ bool HookKernel32IAT(HMODULE mod, bool exe) auto PatchCoCreateInstance = [&](size_t start, size_t end, size_t exe_end) { + if (iequals(GetSelfName(), L"dinput8.dll") || iequals(GetSelfName(), L"dinput.dll") || iequals(GetSelfName(), L"wininet.dll")) + return; + for (size_t i = 0; i < nNumImports; i++) { if (hExecutableInstance + (pImports + i)->FirstThunk > start && !(end && hExecutableInstance + (pImports + i)->FirstThunk > end)) @@ -1170,6 +1230,9 @@ bool HookKernel32IAT(HMODULE mod, bool exe) end = exe_end; } + if (exe) + OLE32Data[eCoCreateInstance][ProcAddress] = (size_t)GetProcAddress(GetModuleHandle(TEXT("OLE32.DLL")), "CoCreateInstance"); + for (auto i = start; i < end; i += sizeof(size_t)) { DWORD dwProtect[2]; @@ -1179,8 +1242,9 @@ bool HookKernel32IAT(HMODULE mod, bool exe) if (!ptr) continue; - if (ptr == (size_t)GetProcAddress(GetModuleHandle(TEXT("OLE32.DLL")), "CoCreateInstance")) + if (ptr == OLE32Data[eCoCreateInstance][ProcAddress]) { + if (exe) OLE32Data[eCoCreateInstance][IATPtr] = i; *(size_t*)i = (size_t)CustomCoCreateInstance; VirtualProtect((size_t*)i, sizeof(size_t), dwProtect[0], &dwProtect[1]); break; @@ -1866,5 +1930,19 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID /*lpReserved*/) hm = hModule; Init(); } + else if (reason == DLL_PROCESS_DETACH) + { + for (size_t i = 0; i < OLE32ExportsNamesCount; i++) + { + if (OLE32Data[i][IATPtr] && OLE32Data[i][ProcAddress]) + { + auto ptr = (size_t*)OLE32Data[i][IATPtr]; + DWORD dwProtect[2]; + VirtualProtect(ptr, sizeof(size_t), PAGE_EXECUTE_READWRITE, &dwProtect[0]); + *ptr = OLE32Data[i][ProcAddress]; + VirtualProtect(ptr, sizeof(size_t), dwProtect[0], &dwProtect[1]); + } + } + } return TRUE; } diff --git a/source/resources/Versioninfo.rc b/source/resources/Versioninfo.rc index b108ee0695b5636d91dc7d443adb55d95b6e1c0b..6f5d6c685690e61df303a23070e5d21489919f84 100644 GIT binary patch delta 160 zcmbOs{y}ns7|Ub}b~)~N244n81}_GGhM>vD?8;!iCxagn--#iV!IQyGHE`G