From 4d8a2bc67e675fddd0260e3f21064945cca4e55e Mon Sep 17 00:00:00 2001 From: Ji O Date: Fri, 31 May 2024 00:10:30 +0900 Subject: [PATCH] MonoIO related fix #13 --- src/hook.cpp | 102 +++++++++++++++++++++++++++++++--- src/il2cpp/il2cpp_symbols.hpp | 27 +++++++++ 2 files changed, 121 insertions(+), 8 deletions(-) diff --git a/src/hook.cpp b/src/hook.cpp index 17fa6e9..a7a4105 100644 --- a/src/hook.cpp +++ b/src/hook.cpp @@ -149,6 +149,8 @@ namespace { } + void PrintStackTrace(); + void* Application_Quit_orig; void Application_Quit_hook(int exitCode) @@ -174,7 +176,15 @@ namespace Exit(); } - void PrintStackTrace(); + void* UpdateDispatcher_Initialize_orig = nullptr; + void UpdateDispatcher_Initialize_hook() + { + auto klass = il2cpp_symbols::get_class("Cute.Core.Assembly.dll", "Cute.Core", "UpdateDispatcher"); + auto isQuitField = il2cpp_class_get_field_from_name(klass, "isQuit"); + bool isQuit = false; + + il2cpp_field_static_set_value(isQuitField, &isQuit); + } void* set_resolution_orig; void set_resolution_hook(int width, int height, int fullscreenMode, int perferredRefreshRate); @@ -198,6 +208,10 @@ namespace MH_CreateHook(Application_Quit, Application_Quit_hook, &Application_Quit_orig); MH_EnableHook(Application_Quit); + auto UpdateDispatcher_Initialize_addr = il2cpp_symbols::get_method_pointer("Cute.Core.Assembly.dll", "Cute.Core", "UpdateDispatcher", "Initialize", -1); + MH_CreateHook(UpdateDispatcher_Initialize_addr, UpdateDispatcher_Initialize_hook, &UpdateDispatcher_Initialize_orig); + MH_EnableHook(UpdateDispatcher_Initialize_addr); + il2cpp_symbols::get_method_pointer("UnityEngine.SubsystemsModule.dll", "UnityEngine", "SubsystemManager", ".cctor", -1)(); il2cpp_symbols::get_method_pointer("UnityEngine.SubsystemsModule.dll", "UnityEngine.SubsystemsImplementation", "SubsystemDescriptorStore", ".cctor", -1)(); @@ -631,14 +645,14 @@ namespace if (textList) { FieldInfo* itemsField = il2cpp_class_get_field_from_name_wrap(textList->klass, "_items"); - Il2CppArraySize* textArr; + Il2CppArraySize_t* textArr; il2cpp_field_get_value(textList, itemsField, &textArr); if (textArr) { for (int i = 0; i < textArr->max_length; i++) { - auto elem = reinterpret_cast(textArr->vector[i]); + auto elem = textArr->vector[i]; if (elem) { auto elemCueIdField = il2cpp_class_get_field_from_name_wrap(elem->klass, "CueId"); @@ -13090,9 +13104,14 @@ BOOL InternetCrackUrlW_hook( return reinterpret_cast(InternetCrackUrlW_orig)(lpszUrl, dwUrlLength, dwFlags, lpUrlComponents); } +constexpr int MAX_DLL_COUNT = 23; +constexpr int MAX_ROOT_FILE_COUNT = 8 + /* self (.) */1 + /* parent (..) */1; + HANDLE currentFindHandle; +HANDLE currentRootFindHandle; int dllCount; +int rootFileCount; void* FindNextFileW_orig = nullptr; BOOL @@ -13102,22 +13121,68 @@ FindNextFileW_hook( _Out_ LPWIN32_FIND_DATAW lpFindFileData ) { - if (currentFindHandle == hFindFile && dllCount >= 23) + if (currentFindHandle == hFindFile && dllCount >= MAX_DLL_COUNT) { - *lpFindFileData = WIN32_FIND_DATAW{}; + lpFindFileData = nullptr; + SetLastError(ERROR_NO_MORE_FILES); + return FALSE; + } + + if (currentRootFindHandle == hFindFile && rootFileCount >= MAX_ROOT_FILE_COUNT) + { + lpFindFileData = nullptr; SetLastError(ERROR_NO_MORE_FILES); return FALSE; } auto result = reinterpret_cast(FindNextFileW_orig)(hFindFile, lpFindFileData); - if (currentFindHandle == hFindFile && lpFindFileData && lpFindFileData->cFileName) + + if (currentRootFindHandle == hFindFile) { - if (result) + if (lpFindFileData && lpFindFileData->cFileName) + { + rootFileCount++; + + if (!result && rootFileCount <= MAX_ROOT_FILE_COUNT && GetLastError() == ERROR_NO_MORE_FILES) + { + SetLastError(ERROR_SUCCESS); + return TRUE; + } + } + else if (rootFileCount < MAX_ROOT_FILE_COUNT && GetLastError() == ERROR_NO_MORE_FILES) + { + if (lpFindFileData) + { + *lpFindFileData = WIN32_FIND_DATAW{}; + } + SetLastError(ERROR_SUCCESS); + return TRUE; + } + } + + if (currentFindHandle == hFindFile) + { + if (lpFindFileData && lpFindFileData->cFileName) { if (wstring(lpFindFileData->cFileName).ends_with(L".dll")) { dllCount++; + + if (!result && dllCount <= MAX_DLL_COUNT && GetLastError() == ERROR_NO_MORE_FILES) + { + SetLastError(ERROR_SUCCESS); + return TRUE; + } + } + } + else if (dllCount < MAX_DLL_COUNT && GetLastError() == ERROR_NO_MORE_FILES) + { + if (lpFindFileData) + { + *lpFindFileData = WIN32_FIND_DATAW{}; } + SetLastError(ERROR_SUCCESS); + return TRUE; } } return result; @@ -13145,8 +13210,28 @@ FindFirstFileExW_hook( auto result = reinterpret_cast(FindFirstFileExW_orig)(lpFileName, fInfoLevelId, lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags); + if (filesystem::current_path().native() + L"\\*.dll" == lpFileName) + { + // reset count + dllCount = 0; + } + + if (filesystem::current_path().native() + L"\\*.*" == lpFileName) + { + currentRootFindHandle = result; + rootFileCount = 1; + } + if (wstring(lpFileName).find(L"*.dll") != wstring::npos) { + if (dllCount >= MAX_DLL_COUNT) + { + CloseHandle(result); + lpFindFileData = nullptr; + SetLastError(ERROR_FILE_NOT_FOUND); + return INVALID_HANDLE_VALUE; + } + currentFindHandle = result; if (lpFindFileData && result != INVALID_HANDLE_VALUE) @@ -13156,7 +13241,7 @@ FindFirstFileExW_hook( dllCount++; } - if (dllCount > 23) + if (dllCount > MAX_DLL_COUNT) { CloseHandle(result); lpFindFileData = nullptr; @@ -13194,6 +13279,7 @@ bool init_hook_base() MH_CreateHook(InternetCrackUrlW, InternetCrackUrlW_hook, &InternetCrackUrlW_orig); MH_EnableHook(InternetCrackUrlW); #endif + } MH_CreateHook(FindFirstFileExW, FindFirstFileExW_hook, &FindFirstFileExW_orig); MH_EnableHook(FindFirstFileExW); diff --git a/src/il2cpp/il2cpp_symbols.hpp b/src/il2cpp/il2cpp_symbols.hpp index 6d9af95..8d5b52f 100644 --- a/src/il2cpp/il2cpp_symbols.hpp +++ b/src/il2cpp/il2cpp_symbols.hpp @@ -649,6 +649,33 @@ typedef struct Il2CppDelegate bool method_is_virtual; } Il2CppDelegate; +template +struct Il2CppDelegate_t +{ + Il2CppObject object; + /* The compiled code of the target method */ + T method_ptr; + /* The invoke code */ + InvokerMethod invoke_impl; + Il2CppObject* target; + const MethodInfo* method; + + void* delegate_trampoline; + + intptr_t extraArg; + + /* + * If non-NULL, this points to a memory location which stores the address of + * the compiled code of the method, or NULL if it is not yet compiled. + */ + uint8_t** method_code; + Il2CppReflectionMethod* method_info; + Il2CppReflectionMethod* original_method_info; + Il2CppObject* data; + + bool method_is_virtual; +}; + typedef struct MulticastDelegate : Il2CppDelegate { Il2CppArraySize* delegates; } MulticastDelegate;