From 917870a19db65d1c319dd67708b48d1e74e347fc Mon Sep 17 00:00:00 2001 From: momo5502 <mauriceheumann@gmail.com> Date: Sat, 10 Jun 2017 20:23:24 +0200 Subject: [PATCH 01/10] [Cache] Re-enable .to domain --- src/Utils/Cache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utils/Cache.cpp b/src/Utils/Cache.cpp index efeeb8d7..8b51d856 100644 --- a/src/Utils/Cache.cpp +++ b/src/Utils/Cache.cpp @@ -18,7 +18,7 @@ namespace Utils // Dead //"https://iw4xcachep26muba.onion.link", - //"https://iw4xcachep26muba.onion.to", + "https://iw4xcachep26muba.onion.to", // Not registered yet //"https://iw4xcachejnetuln.onion.to", From 7a0261ccbd599b23c73e2eeac1d0ed744c8744a7 Mon Sep 17 00:00:00 2001 From: momo5502 <mauriceheumann@gmail.com> Date: Sat, 10 Jun 2017 20:24:42 +0200 Subject: [PATCH 02/10] [AntiCheat] Prevent dll injection - Hook native LdrLoadDll to prevent injection - Hook native LdrpLoadDll to prevent injection - Hook NtCreateThreadEx to log threads created by this process and kill remote threads --- src/Components/Modules/AntiCheat.cpp | 204 +++++++++++++++++++++++++-- src/Components/Modules/AntiCheat.hpp | 14 +- src/Main.cpp | 10 ++ src/Utils/Utils.cpp | 31 ++++ src/Utils/Utils.hpp | 8 +- 5 files changed, 256 insertions(+), 11 deletions(-) diff --git a/src/Components/Modules/AntiCheat.cpp b/src/Components/Modules/AntiCheat.cpp index 76195560..a8228db2 100644 --- a/src/Components/Modules/AntiCheat.cpp +++ b/src/Components/Modules/AntiCheat.cpp @@ -4,10 +4,15 @@ namespace Components { Utils::Time::Interval AntiCheat::LastCheck; std::string AntiCheat::Hash; - Utils::Hook AntiCheat::LoadLibHook[4]; + Utils::Hook AntiCheat::CreateThreadHook; + Utils::Hook AntiCheat::LoadLibHook[6]; Utils::Hook AntiCheat::VirtualProtectHook[2]; unsigned long AntiCheat::Flags = NO_FLAG; + std::mutex AntiCheat::ThreadMutex; + std::vector<DWORD> AntiCheat::OwnThreadIds; + std::map<DWORD, std::shared_ptr<Utils::Hook>> AntiCheat::ThreadHookMap; + // This function does nothing, it only adds the two passed variables and returns the value // The only important thing it does is to clean the first parameter, and then return // By returning, the crash procedure will be called, as it hasn't been cleaned from the stack @@ -70,9 +75,9 @@ namespace Components void AntiCheat::InitLoadLibHook() { - static uint8_t kernel32Str[] = {0xB4, 0x9A, 0x8D, 0xB1, 0x9A, 0x93, 0xCC, 0xCD, 0xD1, 0x9B, 0x93, 0x93}; // KerNel32.dll - static uint8_t loadLibAStr[] = {0xB3, 0x90, 0x9E, 0x9B, 0xB3, 0x96, 0x9D, 0x8D, 0x9E, 0x8D, 0x86, 0xBE}; // LoadLibraryA - static uint8_t loadLibWStr[] = {0xB3, 0x90, 0x9E, 0x9B, 0xB3, 0x96, 0x9D, 0x8D, 0x9E, 0x8D, 0x86, 0xA8}; // LoadLibraryW + static uint8_t kernel32Str[] = { 0xB4, 0x9A, 0x8D, 0xB1, 0x9A, 0x93, 0xCC, 0xCD, 0xD1, 0x9B, 0x93, 0x93 }; // KerNel32.dll + static uint8_t loadLibAStr[] = { 0xB3, 0x90, 0x9E, 0x9B, 0xB3, 0x96, 0x9D, 0x8D, 0x9E, 0x8D, 0x86, 0xBE }; // LoadLibraryA + static uint8_t loadLibWStr[] = { 0xB3, 0x90, 0x9E, 0x9B, 0xB3, 0x96, 0x9D, 0x8D, 0x9E, 0x8D, 0x86, 0xA8 }; // LoadLibraryW HMODULE kernel32 = GetModuleHandleA(Utils::String::XOR(std::string(reinterpret_cast<char*>(kernel32Str), sizeof kernel32Str), -1).data()); if (kernel32) @@ -109,6 +114,26 @@ namespace Components #endif } } + + static uint8_t ldrLoadDllStub[] = { 0x33, 0xC0, 0xC2, 0x10, 0x00 }; + static uint8_t ldrLoadDll[] = { 0xB3, 0x9B, 0x8D, 0xB3, 0x90, 0x9E, 0x9B, 0xBB, 0x93, 0x93 }; // LdrLoadDll + + HMODULE ntdll = Utils::GetNTDLL(); + AntiCheat::LoadLibHook[4].initialize(GetProcAddress(ntdll, Utils::String::XOR(std::string(reinterpret_cast<char*>(ldrLoadDll), sizeof ldrLoadDll), -1).data()), ldrLoadDllStub, HOOK_JUMP); + + // Patch LdrpLoadDll + Utils::Hook::Signature::Container container; + container.signature = "\x8B\xFF\x55\x8B\xEC\x83\xE4\xF8\x81\xEC\x00\x00\x00\x00\xA1\x00\x00\x00\x00\x33\xC4\x89\x84\x24\x00\x00\x00\x00\x53\x8B\x5D\x10\x56\x57"; + container.mask = "xxxxxxxxxx????x????xxxxx????xxxxxx"; + container.callback = [](char* addr) + { + static uint8_t ldrpLoadDllStub[] = { 0x33, 0xC0, 0xC2, 0x0C, 0x00 }; + AntiCheat::LoadLibHook[5].initialize(addr, ldrpLoadDllStub, HOOK_JUMP); + }; + + Utils::Hook::Signature signature(ntdll, Utils::GetModuleSize(ntdll)); + signature.add(container); + signature.process(); } void AntiCheat::ReadIntegrityCheck() @@ -254,10 +279,10 @@ namespace Components void AntiCheat::InstallLibHook() { - AntiCheat::LoadLibHook[0].install(); - AntiCheat::LoadLibHook[1].install(); - AntiCheat::LoadLibHook[2].install(); - AntiCheat::LoadLibHook[3].install(); + for(int i = 0; i < ARRAYSIZE(AntiCheat::LoadLibHook); ++i) + { + AntiCheat::LoadLibHook[i].install(); + } } void AntiCheat::PatchWinAPI() @@ -389,7 +414,7 @@ namespace Components BOOL WINAPI AntiCheat::VirtualProtectExStub(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpflOldProtect) { - if (GetCurrentProcess() == hProcess && !AntiCheat::IsPageChangeAllowed(_ReturnAddress(), lpAddress, dwSize)) return FALSE; + if (GetCurrentProcessId() == GetProcessId(hProcess) && !AntiCheat::IsPageChangeAllowed(_ReturnAddress(), lpAddress, dwSize)) return FALSE; AntiCheat::VirtualProtectHook[1].uninstall(false); BOOL result = VirtualProtectEx(hProcess, lpAddress, dwSize, flNewProtect, lpflOldProtect); @@ -562,6 +587,164 @@ namespace Components AntiCheat::VirtualProtectHook[0].initialize(vp, AntiCheat::VirtualProtectStub, HOOK_JUMP)->install(true, true); } + NTSTATUS NTAPI AntiCheat::NtCreateThreadExStub(PHANDLE phThread,ACCESS_MASK desiredAccess,LPVOID objectAttributes,HANDLE processHandle,LPTHREAD_START_ROUTINE startAddress,LPVOID parameter,BOOL createSuspended,DWORD stackZeroBits,DWORD sizeOfStackCommit,DWORD sizeOfStackReserve,LPVOID bytesBuffer) + { + HANDLE hThread = nullptr; + std::lock_guard<std::mutex> _(AntiCheat::ThreadMutex); + + AntiCheat::CreateThreadHook.uninstall(); + NTSTATUS result = NtCreateThreadEx_t(AntiCheat::CreateThreadHook.getAddress())(&hThread, desiredAccess, objectAttributes, processHandle, startAddress, parameter, createSuspended, stackZeroBits, sizeOfStackCommit, sizeOfStackReserve, bytesBuffer); + AntiCheat::CreateThreadHook.install(); + + if (phThread) *phThread = hThread; + + if (GetProcessId(processHandle) == GetCurrentProcessId()) + { + AntiCheat::OwnThreadIds.push_back(GetThreadId(hThread)); + } + + return result; + } + + void AntiCheat::PatchThreadCreation() + { + HMODULE ntdll = Utils::GetNTDLL(); + if (ntdll) + { + static uint8_t ntCreateThreadEx[] = { 0xB1, 0x8B, 0xBC, 0x8D, 0x9A, 0x9E, 0x8B, 0x9A, 0xAB, 0x97, 0x8D, 0x9A, 0x9E, 0x9B, 0xBA, 0x87 }; // NtCreateThreadEx + FARPROC createThread = GetProcAddress(ntdll, Utils::String::XOR(std::string(reinterpret_cast<char*>(ntCreateThreadEx), sizeof ntCreateThreadEx), -1).data()); + if (createThread) + { + AntiCheat::CreateThreadHook.initialize(createThread, AntiCheat::NtCreateThreadExStub, HOOK_JUMP)->install(); + } + } + } + + int AntiCheat::ValidateThreadTermination(void* addr) + { + { + std::lock_guard<std::mutex> _(AntiCheat::ThreadMutex); + + DWORD id = GetCurrentThreadId(); + auto threadHook = AntiCheat::ThreadHookMap.find(id); + if (threadHook != AntiCheat::ThreadHookMap.end()) + { + threadHook->second->uninstall(false); + AntiCheat::ThreadHookMap.erase(threadHook); // Uninstall and delete the hook + return 1; // Kill + } + } + + while(true) + { + std::lock_guard<std::mutex> _(AntiCheat::ThreadMutex); + + // It would be better to wait for the thread + // but we don't know if there are multiple hooks at the same address + bool found = false; + for (auto threadHook : AntiCheat::ThreadHookMap) + { + if (threadHook.second->getAddress() == addr) + { + found = true; + break; + } + } + + if (!found) break; + std::this_thread::sleep_for(10ms); + } + + return 0; // Don't kill + } + + __declspec(naked) void AntiCheat::ThreadEntryPointStub() + { + __asm + { + push eax + push eax + pushad + + // Reinitialize the return address + mov eax, [esp + 28h] + sub eax, 5 + mov [esp + 28h], eax + + push eax + call AntiCheat::ValidateThreadTermination + add esp, 4h + + mov [esp + 20h], eax + + popad + + pop eax + + test eax, eax + jz dontKill + + pop eax + add esp, 4h // Remove return address (simulate a jump hook) + retn + + dontKill: + pop eax + retn + } + } + + void AntiCheat::VerifyThreadIntegrity() + { + bool kill = true; + { + std::lock_guard<std::mutex> _(AntiCheat::ThreadMutex); + + auto threadHook = std::find(AntiCheat::OwnThreadIds.begin(), AntiCheat::OwnThreadIds.end(), GetCurrentThreadId()); + if (threadHook != AntiCheat::OwnThreadIds.end()) + { + AntiCheat::OwnThreadIds.erase(threadHook); + kill = false; + } + } + + if (kill) + { + static bool first = true; + if (first) first = false; // We can't control the main thread, as it's spawned externally + else + { + std::lock_guard<std::mutex> _(AntiCheat::ThreadMutex); + + HMODULE ntdll = Utils::GetNTDLL(), targetModule; + if (!ntdll) return; // :( + + void* address = Utils::GetThreadStartAddress(GetCurrentThread()); + if (address) + { + GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, reinterpret_cast<char*>(address), &targetModule); + if (targetModule == ntdll) return; // Better not kill kernel threads + + DWORD id = GetCurrentThreadId(); + { + auto threadHook = AntiCheat::ThreadHookMap.find(id); + if (threadHook != AntiCheat::ThreadHookMap.end()) + { + threadHook->second->uninstall(false); + AntiCheat::ThreadHookMap.erase(threadHook); + } + } + + std::shared_ptr<Utils::Hook> hook = std::make_shared<Utils::Hook>(); + AntiCheat::ThreadHookMap[id] = hook; + + // Hook the entry point of the thread to properly terminate it + hook->initialize(address, AntiCheat::ThreadEntryPointStub, HOOK_CALL)->install(true, true); + } + } + } + } + AntiCheat::AntiCheat() { time(nullptr); @@ -611,6 +794,9 @@ namespace Components AntiCheat::Flags = NO_FLAG; AntiCheat::Hash.clear(); + AntiCheat::OwnThreadIds.clear(); + AntiCheat::ThreadHookMap.clear(); + for (int i = 0; i < ARRAYSIZE(AntiCheat::LoadLibHook); ++i) { AntiCheat::LoadLibHook[i].uninstall(); diff --git a/src/Components/Modules/AntiCheat.hpp b/src/Components/Modules/AntiCheat.hpp index 82149cc2..ce82edc3 100644 --- a/src/Components/Modules/AntiCheat.hpp +++ b/src/Components/Modules/AntiCheat.hpp @@ -27,6 +27,9 @@ namespace Components static unsigned long ProtectProcess(); static void PatchVirtualProtect(void* vp, void* vpex); + static void PatchThreadCreation(); + + static void VerifyThreadIntegrity(); private: enum IntergrityFlag @@ -79,7 +82,16 @@ namespace Components static void AcquireDebugPriviledge(HANDLE hToken); - static Utils::Hook LoadLibHook[4]; + static NTSTATUS NTAPI NtCreateThreadExStub(PHANDLE hThread, ACCESS_MASK desiredAccess, LPVOID objectAttributes, HANDLE processHandle, LPTHREAD_START_ROUTINE startAddress, LPVOID parameter, BOOL createSuspended, DWORD stackZeroBits, DWORD sizeOfStackCommit, DWORD sizeOfStackReserve, LPVOID bytesBuffer); + static int ValidateThreadTermination(void* addr); + static void ThreadEntryPointStub(); + + static std::mutex ThreadMutex; + static std::vector<DWORD> OwnThreadIds; + static std::map<DWORD, std::shared_ptr<Utils::Hook>> ThreadHookMap; + + static Utils::Hook CreateThreadHook; + static Utils::Hook LoadLibHook[6]; static Utils::Hook VirtualProtectHook[2]; }; } diff --git a/src/Main.cpp b/src/Main.cpp index f0c535f2..899dc4c5 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -72,6 +72,7 @@ BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*l []() { Components::AntiCheat::ProtectProcess(); + Components::AntiCheat::PatchThreadCreation(); }(); #endif @@ -87,6 +88,15 @@ BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*l { Main::Uninitialize(); } + else if(ul_reason_for_call == DLL_THREAD_ATTACH) + { +#if !defined(DEBUG) && !defined(DISABLE_ANTICHEAT) + []() + { + Components::AntiCheat::VerifyThreadIntegrity(); + }(); +#endif + } return TRUE; } diff --git a/src/Utils/Utils.cpp b/src/Utils/Utils.cpp index c0cf82e3..6601ee8e 100644 --- a/src/Utils/Utils.cpp +++ b/src/Utils/Utils.cpp @@ -79,6 +79,37 @@ namespace Utils return ntHeader->OptionalHeader.SizeOfImage; } + void* GetThreadStartAddress(HANDLE hThread) + { + HMODULE ntdll = Utils::GetNTDLL(); + if (!ntdll) return nullptr; + + + static uint8_t ntQueryInformationThread[] = { 0xB1, 0x8B, 0xAE, 0x8A, 0x9A, 0x8D, 0x86, 0xB6, 0x91, 0x99, 0x90, 0x8D, 0x92, 0x9E, 0x8B, 0x96, 0x90, 0x91, 0xAB, 0x97, 0x8D, 0x9A, 0x9E, 0x9B }; // NtQueryInformationThread + NtQueryInformationThread_t NtQueryInformationThread = NtQueryInformationThread_t(GetProcAddress(ntdll, Utils::String::XOR(std::string(reinterpret_cast<char*>(ntQueryInformationThread), sizeof ntQueryInformationThread), -1).data())); + if (!NtQueryInformationThread) return nullptr; + + HANDLE dupHandle, currentProcess = GetCurrentProcess(); + if (!DuplicateHandle(currentProcess, hThread, currentProcess, &dupHandle, THREAD_QUERY_INFORMATION, FALSE, 0)) + { + SetLastError(ERROR_ACCESS_DENIED); + return nullptr; + } + + void* address = nullptr; + NTSTATUS status = NtQueryInformationThread(dupHandle, ThreadQuerySetWin32StartAddress, &address, sizeof(address), nullptr); + CloseHandle(dupHandle); + + if (status != 0) return nullptr; + return address; + } + + HMODULE GetNTDLL() + { + static uint8_t ntdll[] = { 0x91, 0x8B, 0x9B, 0x93, 0x93, 0xD1, 0x9B, 0x93, 0x93 }; // ntdll.dll + return GetModuleHandleA(Utils::String::XOR(std::string(reinterpret_cast<char*>(ntdll), sizeof ntdll), -1).data()); + } + bool HasIntercection(unsigned int base1, unsigned int len1, unsigned int base2, unsigned int len2) { return !(base1 + len1 <= base2 || base2 + len2 <= base1); diff --git a/src/Utils/Utils.hpp b/src/Utils/Utils.hpp index 6c0bcbe4..7ae60034 100644 --- a/src/Utils/Utils.hpp +++ b/src/Utils/Utils.hpp @@ -1,5 +1,10 @@ #pragma once +typedef LONG NTSTATUS; +typedef NTSTATUS(NTAPI *NtCreateThreadEx_t)(PHANDLE hThread, ACCESS_MASK DesiredAccess, LPVOID ObjectAttributes, HANDLE ProcessHandle, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, BOOL CreateSuspended, DWORD StackZeroBits, DWORD SizeOfStackCommit, DWORD SizeOfStackReserve, LPVOID lpBytesBuffer); +typedef NTSTATUS(NTAPI* NtQueryInformationThread_t)(HANDLE ThreadHandle, LONG ThreadInformationClass, PVOID ThreadInformation, ULONG ThreadInformationLength, PULONG ReturnLength); +#define ThreadQuerySetWin32StartAddress 9 + namespace Utils { std::string GetMimeType(std::string url); @@ -10,8 +15,9 @@ namespace Utils bool IsWineEnvironment(); unsigned long GetParentProcessId(); - size_t GetModuleSize(HMODULE module); + void* GetThreadStartAddress(HANDLE hThread); + HMODULE GetNTDLL(); bool HasIntercection(unsigned int base1, unsigned int len1, unsigned int base2, unsigned int len2); From 29ef5d63793ae76d2c7c4217548375e73efa6e52 Mon Sep 17 00:00:00 2001 From: momo5502 <mauriceheumann@gmail.com> Date: Sun, 11 Jun 2017 21:24:32 +0200 Subject: [PATCH 03/10] [AntiCheat] Add redundant code scanners --- src/Components/Modules/AntiCheat.cpp | 40 ++++++++++++++++++++++++++++ src/Components/Modules/AntiCheat.hpp | 4 +++ src/Components/Modules/Changelog.cpp | 4 +++ src/Components/Modules/Menus.cpp | 4 +++ 4 files changed, 52 insertions(+) diff --git a/src/Components/Modules/AntiCheat.cpp b/src/Components/Modules/AntiCheat.cpp index a8228db2..4c23ae0d 100644 --- a/src/Components/Modules/AntiCheat.cpp +++ b/src/Components/Modules/AntiCheat.cpp @@ -229,6 +229,46 @@ namespace Components AntiCheat::Flags |= AntiCheat::IntergrityFlag::MEMORY_SCAN; } + void AntiCheat::QuickCodeScanner_1() + { + static Utils::Time::Interval interval; + static Utils::Value<std::string> hashVal; + + if (!interval.elapsed(11s)) return; + interval.update(); + + // Hash .text segment + // Add 1 to each value, so searching in memory doesn't reveal anything + size_t textSize = 0x2D5FFF; + uint8_t* textBase = reinterpret_cast<uint8_t*>(0x400FFF); + std::string hash = Utils::Cryptography::SHA256::Compute(textBase + 1, textSize + 1, false); + + if (hashVal.isValid() && hash != hashVal.get()) + { + Utils::Hook::Set<BYTE>(0x42A667, 0x90); // Crash + } + + hashVal.set(hash); + } + + void AntiCheat::QuickCodeScanner_2() + { + static Utils::Time::Interval interval; + static Utils::Value<std::string> hashVal; + + if (!interval.elapsed(12s)) return; + interval.update(); + + // Hash .text segment + std::string hash = Utils::Cryptography::SHA1::Compute(reinterpret_cast<uint8_t*>(0x401000), 0x2D6000, false); + if (hashVal.isValid() && hash != hashVal.get()) + { + Utils::Hook::Set<BYTE>(0x40797C, 0x90); // Crash + } + + hashVal.set(hash); + } + #ifdef DEBUG_LOAD_LIBRARY HANDLE AntiCheat::LoadLibary(std::wstring library, HANDLE file, DWORD flags, void* callee) { diff --git a/src/Components/Modules/AntiCheat.hpp b/src/Components/Modules/AntiCheat.hpp index ce82edc3..5c0b5279 100644 --- a/src/Components/Modules/AntiCheat.hpp +++ b/src/Components/Modules/AntiCheat.hpp @@ -31,6 +31,10 @@ namespace Components static void VerifyThreadIntegrity(); + static void QuickCodeScanner_1(); + static void QuickCodeScanner_2(); + static void QuickCodeScanner_3(); + private: enum IntergrityFlag { diff --git a/src/Components/Modules/Changelog.cpp b/src/Components/Modules/Changelog.cpp index 6dc2d719..e45e937f 100644 --- a/src/Components/Modules/Changelog.cpp +++ b/src/Components/Modules/Changelog.cpp @@ -55,6 +55,10 @@ namespace Components // Changelog UIFeeder::Add(62.0f, Changelog::GetChangelogCount, Changelog::GetChangelogText, Changelog::SelectChangelog); + +#if !defined(DEBUG) && !defined(DISABLE_ANTICHEAT) + Scheduler::OnFrame(AntiCheat::QuickCodeScanner_1); +#endif } Changelog::~Changelog() diff --git a/src/Components/Modules/Menus.cpp b/src/Components/Modules/Menus.cpp index 68ba3277..2d8d8ad9 100644 --- a/src/Components/Modules/Menus.cpp +++ b/src/Components/Modules/Menus.cpp @@ -766,6 +766,10 @@ namespace Components } }); +#if !defined(DEBUG) && !defined(DISABLE_ANTICHEAT) + Scheduler::OnFrame(AntiCheat::QuickCodeScanner_2); +#endif + Command::Add("mp_QuickMessage", [] (Command::Params*) { Command::Execute("openmenu quickmessage"); From a327915008e72491861ed0e459241da783afd117 Mon Sep 17 00:00:00 2001 From: momo5502 <mauriceheumann@gmail.com> Date: Sun, 11 Jun 2017 21:25:00 +0200 Subject: [PATCH 04/10] [Command] Don't crash on shell execute --- src/Components/Modules/Command.cpp | 2 +- src/Components/Modules/News.cpp | 4 ++-- src/Utils/Utils.cpp | 9 +++++++++ src/Utils/Utils.hpp | 2 ++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Components/Modules/Command.cpp b/src/Components/Modules/Command.cpp index 90806c69..b4e770c8 100644 --- a/src/Components/Modules/Command.cpp +++ b/src/Components/Modules/Command.cpp @@ -257,7 +257,7 @@ namespace Components { if (params->length() > 1) { - ShellExecuteA(nullptr, "open", params->get(1), nullptr, nullptr, SW_SHOWNORMAL); + Utils::OpenUrl(params->get(1)); } }); } diff --git a/src/Components/Modules/News.cpp b/src/Components/Modules/News.cpp index 44af50d8..aca4484b 100644 --- a/src/Components/Modules/News.cpp +++ b/src/Components/Modules/News.cpp @@ -201,12 +201,12 @@ namespace Components UIScript::Add("visitWebsite", [](UIScript::Token) { - ShellExecuteA(nullptr, "open", Utils::Cache::GetStaticUrl("").data(), nullptr, nullptr, SW_SHOWNORMAL); + Utils::OpenUrl(Utils::Cache::GetStaticUrl("")); }); UIScript::Add("visitWiki", [](UIScript::Token) { - ShellExecuteA(nullptr, "open", Utils::Cache::GetStaticUrl("/wiki/").data(), nullptr, nullptr, SW_SHOWNORMAL); + Utils::OpenUrl(Utils::Cache::GetStaticUrl("/wiki/")); }); Localization::Set("MPUI_CHANGELOG_TEXT", "Loading..."); diff --git a/src/Utils/Utils.cpp b/src/Utils/Utils.cpp index 6601ee8e..2bca4d44 100644 --- a/src/Utils/Utils.cpp +++ b/src/Utils/Utils.cpp @@ -110,6 +110,15 @@ namespace Utils return GetModuleHandleA(Utils::String::XOR(std::string(reinterpret_cast<char*>(ntdll), sizeof ntdll), -1).data()); } + void OpenUrl(std::string url) + { + try + { + ShellExecuteA(nullptr, "open", url.data(), nullptr, nullptr, SW_SHOWNORMAL); + } + catch (...) {} + } + bool HasIntercection(unsigned int base1, unsigned int len1, unsigned int base2, unsigned int len2) { return !(base1 + len1 <= base2 || base2 + len2 <= base1); diff --git a/src/Utils/Utils.hpp b/src/Utils/Utils.hpp index 7ae60034..31fe5019 100644 --- a/src/Utils/Utils.hpp +++ b/src/Utils/Utils.hpp @@ -19,6 +19,8 @@ namespace Utils void* GetThreadStartAddress(HANDLE hThread); HMODULE GetNTDLL(); + void OpenUrl(std::string url); + bool HasIntercection(unsigned int base1, unsigned int len1, unsigned int base2, unsigned int len2); template <typename T> inline void RotLeft(T& object, size_t bits) From a46daef6f1057d6bbc9326cbc6d2f6a74b9e60e7 Mon Sep 17 00:00:00 2001 From: momo5502 <mauriceheumann@gmail.com> Date: Sun, 11 Jun 2017 21:25:18 +0200 Subject: [PATCH 05/10] [Window] Use better loading cursor --- src/Components/Modules/Window.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Modules/Window.cpp b/src/Components/Modules/Window.cpp index adde2efc..5d7c404d 100644 --- a/src/Components/Modules/Window.cpp +++ b/src/Components/Modules/Window.cpp @@ -127,7 +127,7 @@ namespace Components void Window::ApplyCursor() { bool isLoading = !FastFiles::Ready(); - SetCursor(LoadCursor(nullptr, isLoading ? IDC_WAIT : IDC_ARROW)); + SetCursor(LoadCursor(nullptr, isLoading ? IDC_APPSTARTING : IDC_ARROW)); } BOOL WINAPI Window::MessageHandler(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) From 2a158632300d128212ffdf5fe03cbeab3e62ded9 Mon Sep 17 00:00:00 2001 From: momo5502 <mauriceheumann@gmail.com> Date: Sun, 11 Jun 2017 21:25:31 +0200 Subject: [PATCH 06/10] [QuickPatch] Block upnp spam --- src/Components/Modules/QuickPatch.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Components/Modules/QuickPatch.cpp b/src/Components/Modules/QuickPatch.cpp index 0017f9d9..5788f56e 100644 --- a/src/Components/Modules/QuickPatch.cpp +++ b/src/Components/Modules/QuickPatch.cpp @@ -256,6 +256,7 @@ namespace Components // dont run UPNP stuff on main thread Utils::Hook::Set<BYTE>(0x48A135, 0xC3); Utils::Hook::Set<BYTE>(0x48A151, 0xC3); + Utils::Hook::Nop(0x684080, 5); // Don't spam the console // spawn upnp thread when UPNP_init returns Utils::Hook::Hook(0x47982B, []() From de48b1c694110f50274fa97d61660cafa8e81627 Mon Sep 17 00:00:00 2001 From: momo5502 <mauriceheumann@gmail.com> Date: Sun, 11 Jun 2017 21:25:41 +0200 Subject: [PATCH 07/10] [Submodules] Update libtomcrypt --- deps/libtomcrypt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/libtomcrypt b/deps/libtomcrypt index 2816da42..39228680 160000 --- a/deps/libtomcrypt +++ b/deps/libtomcrypt @@ -1 +1 @@ -Subproject commit 2816da42af88aa1ed4d2d0b958d81021956a6c7e +Subproject commit 39228680827980b0da9a4d38070bb590d2eff983 From 74a39c6e7badd7132301dae3c4311af7c44db056 Mon Sep 17 00:00:00 2001 From: momo5502 <mauriceheumann@gmail.com> Date: Sun, 11 Jun 2017 22:36:28 +0200 Subject: [PATCH 08/10] [AntiCheat] Disable VirtualProtect patch --- src/Components/Modules/AntiCheat.hpp | 1 - src/Components/Modules/Localization.cpp | 12 ++++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Components/Modules/AntiCheat.hpp b/src/Components/Modules/AntiCheat.hpp index 5c0b5279..1285dab3 100644 --- a/src/Components/Modules/AntiCheat.hpp +++ b/src/Components/Modules/AntiCheat.hpp @@ -33,7 +33,6 @@ namespace Components static void QuickCodeScanner_1(); static void QuickCodeScanner_2(); - static void QuickCodeScanner_3(); private: enum IntergrityFlag diff --git a/src/Components/Modules/Localization.cpp b/src/Components/Modules/Localization.cpp index 6c18412a..14b6dbc9 100644 --- a/src/Components/Modules/Localization.cpp +++ b/src/Components/Modules/Localization.cpp @@ -286,12 +286,12 @@ namespace Components } }); -#if !defined(DEBUG) && !defined(DISABLE_ANTICHEAT) - if (!Dedicated::IsEnabled() && !ZoneBuilder::IsEnabled() && !Utils::IsWineEnvironment() && !Loader::PerformingUnitTests()) - { - AntiCheat::PatchVirtualProtect(VirtualProtect, VirtualProtectEx); - } -#endif +// #if !defined(DEBUG) && !defined(DISABLE_ANTICHEAT) +// if (!Dedicated::IsEnabled() && !ZoneBuilder::IsEnabled() && !Utils::IsWineEnvironment() && !Loader::PerformingUnitTests()) +// { +// AntiCheat::PatchVirtualProtect(VirtualProtect, VirtualProtectEx); +// } +// #endif } Localization::~Localization() From 8b38b3990ca9a2b0cd695dcbbf2e04efff9ffd2d Mon Sep 17 00:00:00 2001 From: momo5502 <mauriceheumann@gmail.com> Date: Mon, 12 Jun 2017 19:54:11 +0200 Subject: [PATCH 09/10] [Main] Directly jump to the initialization routine --- src/Components/Loader.cpp | 2 +- src/Main.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/Loader.cpp b/src/Components/Loader.cpp index f4dd91e8..767e2e23 100644 --- a/src/Components/Loader.cpp +++ b/src/Components/Loader.cpp @@ -190,7 +190,7 @@ namespace Components { if (component) { -#ifdef DEBUG +#if defined(DEBUG) || defined(FORCE_UNIT_TESTS) if(!Loader::PerformingUnitTests()) { Logger::Print("Component registered: %s\n", component->getName().data()); diff --git a/src/Main.cpp b/src/Main.cpp index 899dc4c5..c65b5333 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -49,7 +49,7 @@ namespace Main call Main::Initialize popad - push 6BAC14h // Continue init routine + push 6BAA2Fh // Continue init routine push 6CA062h // ___security_init_cookie retn } From 8b7aca48d370e7bb4aa5a3d1e9d774d85186f740 Mon Sep 17 00:00:00 2001 From: momo5502 <mauriceheumann@gmail.com> Date: Mon, 12 Jun 2017 19:54:20 +0200 Subject: [PATCH 10/10] [Submodules] Update libtomcrypt --- deps/libtomcrypt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/libtomcrypt b/deps/libtomcrypt index 39228680..a4671110 160000 --- a/deps/libtomcrypt +++ b/deps/libtomcrypt @@ -1 +1 @@ -Subproject commit 39228680827980b0da9a4d38070bb590d2eff983 +Subproject commit a4671110d5b988161d029eb5001d1516301606dd