diff --git a/lib/YaeAchievementLib.vcxproj b/lib/YaeAchievementLib.vcxproj index a9c704b..e21d77a 100644 --- a/lib/YaeAchievementLib.vcxproj +++ b/lib/YaeAchievementLib.vcxproj @@ -112,7 +112,6 @@ - diff --git a/lib/src/dllmain.cpp b/lib/src/dllmain.cpp index aa32867..04a91f5 100644 --- a/lib/src/dllmain.cpp +++ b/lib/src/dllmain.cpp @@ -15,19 +15,19 @@ using Genshin::ByteArray; HWND unityWnd = nullptr; HANDLE hPipe = nullptr; +void* baClass; std::string checksum; namespace Hook { ByteArray* UnityEngine_RecordUserData(const INT type) { if (type == 0) { - const auto arr = new ByteArray {}; const auto len = checksum.length(); - arr->max_length = len; + const auto arr = Genshin::il2cpp_array_new_specific(baClass, len); memcpy(&arr->vector[0], checksum.data(), len); return arr; } - return new ByteArray {}; + return Genshin::il2cpp_array_new_specific(baClass, 0); } uint16_t BitConverter_ToUInt16(ByteArray* val, const int startIndex) { @@ -52,13 +52,19 @@ void Run(HMODULE* phModule) { } Sleep(5000); DisableVMProtect(); - InitIL2CPP(); + void* ppRecordUserData = nullptr; + InitIL2CPP(ppRecordUserData); + if (!ppRecordUserData) { + ErrorDialog("ppRecordUserData == nullptr\n"); + ExitProcess(-1); + } for (int i = 0; i < 3; i++) { const auto result = Genshin::RecordUserData(i); checksum += string(reinterpret_cast(&result->vector[0]), result->max_length); + baClass = result->klass; } HookManager::install(Genshin::BitConverter_ToUInt16, Hook::BitConverter_ToUInt16); - HookManager::install(Genshin::UnityEngine_RecordUserData, Hook::UnityEngine_RecordUserData); + *(void**) ppRecordUserData = (void*) &Hook::UnityEngine_RecordUserData; hPipe = CreateFile(R"(\\.\pipe\YaeAchievementPipe)", GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr); if (hPipe == INVALID_HANDLE_VALUE) { Win32ErrorDialog(1001); diff --git a/lib/src/il2cpp-appdata.h b/lib/src/il2cpp-appdata.h index 546829a..ac5ddc8 100644 --- a/lib/src/il2cpp-appdata.h +++ b/lib/src/il2cpp-appdata.h @@ -5,15 +5,7 @@ // Application-specific functions #define DO_APP_FUNC(ca, oa, r, n, p) extern r (*n) p -#define DO_UNI_FUNC(ca, oa, r, n, p) extern r (*n) p namespace Genshin { #include "il2cpp-functions.h" } -#undef DO_UNI_FUNC #undef DO_APP_FUNC - -#define DO_TYPEDEF(ca, oa, n) extern n##__Class **n##__TypeInfo -namespace Genshin { -#include "il2cpp-types-ptr.h" -} -#undef DO_TYPEDEF \ No newline at end of file diff --git a/lib/src/il2cpp-functions.h b/lib/src/il2cpp-functions.h index a0590b9..ab4a9be 100644 --- a/lib/src/il2cpp-functions.h +++ b/lib/src/il2cpp-functions.h @@ -2,10 +2,8 @@ using namespace Genshin; // DO_APP_FUNC(CN_OFFSET, OS_OFFSET, RETURN, FUNC_NAME, (ARGS...)); -DO_APP_FUNC(0x57A390, 0x579D00, LPVOID, il2cpp_object_new, (LPVOID t)); +DO_APP_FUNC(0x00522FD0, 0x00522840, ByteArray*, il2cpp_array_new_specific, (void* arrayTypeInfo, uint64_t length)); DO_APP_FUNC(0x07315A30, 0x0710F580, ByteArray*, RecordUserData, (int32_t nType)); DO_APP_FUNC(0x0D257150, 0x0D244830, uint16_t, BitConverter_ToUInt16, (ByteArray* val, int startIndex)); - -DO_UNI_FUNC(0x10CF80, 0x10CF80, ByteArray*, UnityEngine_RecordUserData, (int32_t nType)); diff --git a/lib/src/il2cpp-init.cpp b/lib/src/il2cpp-init.cpp index bedc197..ef7edf6 100644 --- a/lib/src/il2cpp-init.cpp +++ b/lib/src/il2cpp-init.cpp @@ -1,38 +1,34 @@ +// ReSharper disable CppCStyleCast +// ReSharper disable CppInconsistentNaming // ReSharper disable CppClangTidyBugproneMacroParentheses +// ReSharper disable CppClangTidyClangDiagnosticCastAlign #include "pch.h" #include "il2cpp-init.h" #define DO_APP_FUNC(ca, oa, r, n, p) r (*n) p -#define DO_UNI_FUNC(ca, oa, r, n, p) r (*n) p namespace Genshin { #include "il2cpp-functions.h" } -#undef DO_UNI_FUNC #undef DO_APP_FUNC -#define DO_TYPEDEF(ca, oa, n) n##__Class **n##__TypeInfo -namespace Genshin { -#include "il2cpp-types-ptr.h" -} -#undef DO_TYPEDEF - using std::string; -void InitIL2CPP() { +void InitIL2CPP(void* &ppRecordUserData) { TCHAR szFileName[MAX_PATH]; - GetModuleFileName(NULL, szFileName, MAX_PATH); - auto isCN = strstr(szFileName, "YuanShen.exe");//string(szFileName).contains(); - auto hBase = GetModuleHandle("UserAssembly.dll"); - auto bAddr = (UINT64)hBase; - auto cAddr = (UINT64)GetModuleHandle("UnityPlayer.dll"); - #define DO_APP_FUNC(ca, oa, r, n, p) n = (r (*) p)(bAddr + (isCN ? ca : oa)) - #define DO_UNI_FUNC(ca, oa, r, n, p) n = (r (*) p)(cAddr + (isCN ? ca : oa)) + GetModuleFileName(nullptr, szFileName, MAX_PATH); + const auto isCN = strstr(szFileName, "YuanShen.exe"); + const auto uBase = reinterpret_cast(GetModuleHandle("UserAssembly.dll")); + #define DO_APP_FUNC(ca, oa, r, n, p) n = (r (*) p)(uBase + (isCN ? ca : oa)) #include "il2cpp-functions.h" - #undef DO_UNI_FUNC #undef DO_APP_FUNC - #define DO_TYPEDEF(ca, oa, n) n##__TypeInfo = (n##__Class **)(bAddr + (isCN ? ca : oa)) - #include "il2cpp-types-ptr.h" - #undef DO_TYPEDEF + auto sPtr = reinterpret_cast(RecordUserData); + for (int i = 0; i < 0x64; ++i) { + if ((*(uint32_t*) sPtr & 0xFFFFFF) == 0x25FF48) { // 48 FF 25 ?? + ppRecordUserData = sPtr + 7 + *(int*) (sPtr + 3); + break; + } + sPtr += 1; + } } diff --git a/lib/src/il2cpp-init.h b/lib/src/il2cpp-init.h index d0b0e0d..d1a7363 100644 --- a/lib/src/il2cpp-init.h +++ b/lib/src/il2cpp-init.h @@ -1,4 +1,4 @@ #pragma once // IL2CPP application initializer -void InitIL2CPP(); +void InitIL2CPP(void* &ppRecordUserData); diff --git a/lib/src/il2cpp-types-ptr.h b/lib/src/il2cpp-types-ptr.h deleted file mode 100644 index e69de29..0000000 diff --git a/lib/src/il2cpp-types.h b/lib/src/il2cpp-types.h index dd428c4..0eb9ee7 100644 --- a/lib/src/il2cpp-types.h +++ b/lib/src/il2cpp-types.h @@ -3,43 +3,13 @@ #pragma once -#pragma region IL2CPPInternalTypes - -typedef uint16_t Il2CppChar; -typedef uintptr_t il2cpp_array_size_t; -typedef int32_t il2cpp_array_lower_bound_t; - -typedef struct Il2CppObject { - union { - void* klass; - void* vtable; - } Il2CppClass; - void* monitor; -} Il2CppObject; - -typedef struct Il2CppString { - Il2CppObject object; - int32_t length; - Il2CppChar chars[32]; -} Il2CppString; - -typedef struct Il2CppArrayBounds { - il2cpp_array_size_t length; - il2cpp_array_lower_bound_t lower_bound; -} Il2CppArrayBounds; - -#pragma endregion - namespace Genshin { struct ByteArray { void* klass; void* monitor; - Il2CppArrayBounds* bounds; - il2cpp_array_size_t max_length; + void* bounds; + uint64_t max_length; uint8_t vector[32]; }; - - struct CodedOutputStream__Class { - }; } diff --git a/lib/src/pch.h b/lib/src/pch.h index f0188f9..f87cddb 100644 --- a/lib/src/pch.h +++ b/lib/src/pch.h @@ -14,12 +14,8 @@ // 添加要在此处预编译的标头 #include -#include #include -#include -#include #include -#include #include #include "HookManager.h" #include "il2cpp-appdata.h" diff --git a/lib/src/util.cpp b/lib/src/util.cpp index 51c1997..febc6b8 100644 --- a/lib/src/util.cpp +++ b/lib/src/util.cpp @@ -12,24 +12,12 @@ VOID DisableVMProtect() { VirtualProtect(pNtProtectVirtualMemory, 1, old, &old); } -#pragma region StringConvert - -string ToString(Il2CppString* str, UINT codePage) { - auto chars = reinterpret_cast(str->chars); - auto len = WideCharToMultiByte(codePage, 0, chars, -1, nullptr, 0, nullptr, nullptr); - auto buffer = new char[len]; - WideCharToMultiByte(codePage, 0, chars, -1, buffer, len, nullptr, nullptr); - return string(buffer); -} - -#pragma endregion - #pragma region ByteUtils bool IsLittleEndian() { UINT i = 1; char* c = (char*)&i; - return (*c); + return *c; } #pragma endregion diff --git a/lib/src/util.h b/lib/src/util.h index 9a83192..5458f4d 100644 --- a/lib/src/util.h +++ b/lib/src/util.h @@ -5,10 +5,9 @@ using std::string; VOID DisableVMProtect(); bool IsLittleEndian(); HWND FindMainWindowByPID(DWORD pid); -string ToString(Il2CppString* str, UINT codePage = CP_ACP); std::string base64_encode(BYTE const* buf, unsigned int bufLen); -#define ErrorDialogT(title, msg) MessageBox(unityWnd, msg, title, MB_OK | MB_ICONERROR | MB_SYSTEMMODAL); +#define ErrorDialogT(title, msg) MessageBox(unityWnd, msg, title, MB_OK | MB_ICONERROR | MB_SYSTEMMODAL) #define ErrorDialog(msg) ErrorDialogT("YaeAchievement", msg) #define Win32ErrorDialog(code) ErrorDialogT("YaeAchievement", ("CRITICAL ERROR!\nError code: " + std::to_string(GetLastError()) + "-"#code"\n\nPlease take the screenshot and contact developer by GitHub Issue to solve this problem\nNOT MIHOYO/COGNOSPHERE CUSTOMER SERVICE!").c_str())