From 10dd03335f6561a15dbcc928aeee76a1af5ca080 Mon Sep 17 00:00:00 2001 From: HolographicHat Date: Fri, 12 Aug 2022 23:34:04 +0800 Subject: [PATCH] lib update --- lib/YaeAchievementLib.vcxproj | 1 + lib/src/dllmain.cpp | 29 ++++++++++++++++++++++++++--- lib/src/il2cpp-appdata.h | 6 ++++++ lib/src/il2cpp-functions.h | 3 +++ lib/src/il2cpp-init.cpp | 12 +++++++++++- lib/src/il2cpp-unity-functions.h | 3 +++ lib/src/util.cpp | 8 ++++++++ lib/src/util.h | 9 +++++++++ 8 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 lib/src/il2cpp-unity-functions.h diff --git a/lib/YaeAchievementLib.vcxproj b/lib/YaeAchievementLib.vcxproj index 82d6bb4..3a11d92 100644 --- a/lib/YaeAchievementLib.vcxproj +++ b/lib/YaeAchievementLib.vcxproj @@ -115,6 +115,7 @@ + diff --git a/lib/src/dllmain.cpp b/lib/src/dllmain.cpp index 0b9d04f..5b01c0f 100644 --- a/lib/src/dllmain.cpp +++ b/lib/src/dllmain.cpp @@ -8,7 +8,7 @@ using std::to_string; HWND unityWnd = 0; HANDLE hPipe = 0; -std::set PacketWhitelist = { 172, 198, 112, 2676, 7, 21 }; // ping, token, loginreq +std::set PacketWhitelist = { 172, 198, 112, 2676, 7, 21, 135 }; // ping, token, loginreq bool OnPacket(KcpPacket* pkt) { if (pkt->data == nullptr) return true; @@ -22,12 +22,13 @@ bool OnPacket(KcpPacket* pkt) { return true; } if (!PacketWhitelist.contains(ReadMapped(data->vector, 2))) { - #ifdef _DEBUG + //ifdef _DEBUG printf("Blocked cmdid: %d\n", ReadMapped(data->vector, 2)); - #endif + //endif delete[] data; return false; } + printf("Passed cmdid: %d\n", ReadMapped(data->vector, 2)); if (ReadMapped(data->vector, 2) == 2676) { auto headLength = ReadMapped(data->vector, 4); auto dataLength = ReadMapped(data->vector, 6); @@ -47,6 +48,12 @@ namespace Hook { return OnPacket(pkt) ? CALL_ORIGIN(Kcp_Send, client, pkt, method) : 0; } + void MonoLoginMainPage__set_version(void* obj, Il2CppString* value, void* method) { + auto version = IlStringToString(value); + value = string_new(version + " YaeAchievement"); + CALL_ORIGIN(MonoLoginMainPage__set_version, obj, value, method); + } + bool Kcp_Recv(void* client, ClientKcpEvent* evt, void* method) { auto result = CALL_ORIGIN(Kcp_Recv, client, evt, method); if (result == 0 || evt->fields.type != KcpEventType::EventRecvMsg) { @@ -54,6 +61,17 @@ namespace Hook { } return OnPacket(evt->fields.packet) ? result : false; } + + std::map signatures; + + ByteArray* UnityEngine_RecordUserData(INT type) { + if (signatures.count(type)) { + return GCHandle_GetObject(signatures[type]); + } + auto result = CALL_ORIGIN(UnityEngine_RecordUserData, type); + signatures[type] = GCHandle_New(result, true); + return result; + } } void Run(HMODULE* phModule) { @@ -66,8 +84,13 @@ void Run(HMODULE* phModule) { Sleep(1000); } InitIL2CPP(); + HookManager::install(Genshin::UnityEngine_RecordUserData, Hook::UnityEngine_RecordUserData); + for (int i = 0; i < 4; i++) { + Genshin::Application_RecordUserData(i, nullptr); + } HookManager::install(Genshin::Kcp_Send, Hook::Kcp_Send); HookManager::install(Genshin::Kcp_Recv, Hook::Kcp_Recv); + HookManager::install(Genshin::MonoLoginMainPage__set_version, Hook::MonoLoginMainPage__set_version); 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 33e17b3..66f1fc2 100644 --- a/lib/src/il2cpp-appdata.h +++ b/lib/src/il2cpp-appdata.h @@ -12,3 +12,9 @@ namespace Genshin { #include "il2cpp-functions.h" } #undef DO_APP_FUNC + +#define DO_UNI_FUNC(ca, oa, r, n, p) extern r (*n) p +namespace Genshin { +#include "il2cpp-unity-functions.h" +} +#undef DO_UNI_FUNC diff --git a/lib/src/il2cpp-functions.h b/lib/src/il2cpp-functions.h index cdfdefd..685d0e0 100644 --- a/lib/src/il2cpp-functions.h +++ b/lib/src/il2cpp-functions.h @@ -3,5 +3,8 @@ using namespace Genshin; DO_APP_FUNC(0x05E24240, 0x04EA10F0, Il2CppString*, Convert_ToBase64String, (ByteArray* value, int offset, int length, void* method)); DO_APP_FUNC(0x018280A0, 0x018293F0, void, Packet_Xor, (ByteArray** data, int length, void* method)); +DO_APP_FUNC(0X00E83770, 0x00E83990, void, MonoLoginMainPage__set_version, (void* obj, Il2CppString* value, void* method)); +DO_APP_FUNC(0x0688D860, 0x058838C0, ByteArray*, Application_RecordUserData, (int32_t nType, void* method)); + DO_APP_FUNC(0x0193BA70, 0x0193C7D0, int, Kcp_Send, (void* client, KcpPacket* pkt, void* method)); DO_APP_FUNC(0x029EF820, 0x029F05C0, bool, Kcp_Recv, (void* client, ClientKcpEvent* evt, void* method)); diff --git a/lib/src/il2cpp-init.cpp b/lib/src/il2cpp-init.cpp index 635e011..7499310 100644 --- a/lib/src/il2cpp-init.cpp +++ b/lib/src/il2cpp-init.cpp @@ -12,6 +12,12 @@ namespace Genshin { } #undef DO_APP_FUNC +#define DO_UNI_FUNC(ca, oa, r, n, p) r (*n) p +namespace Genshin { +#include "il2cpp-unity-functions.h" +} +#undef DO_UNI_FUNC + using std::string; UINT64 GetAddressByExports(HMODULE base, const char* name) { @@ -22,13 +28,17 @@ UINT64 GetAddressByExports(HMODULE base, const char* name) { void InitIL2CPP() { TCHAR szFileName[MAX_PATH]; GetModuleFileName(NULL, szFileName, MAX_PATH); - auto isCN = string(szFileName).contains("YuanShen.exe"); + 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_API(r, n, p) n = (r (*) p) GetAddressByExports(hBase, #n); #include "il2cpp-api-functions.h" #undef DO_API #define DO_APP_FUNC(ca, oa, r, n, p) n = (r (*) p)(bAddr + (isCN ? ca : oa)) #include "il2cpp-functions.h" #undef DO_APP_FUNC + #define DO_UNI_FUNC(ca, oa, r, n, p) n = (r (*) p)(cAddr + (isCN ? ca : oa)) + #include "il2cpp-unity-functions.h" + #undef DO_UNI_FUNC } diff --git a/lib/src/il2cpp-unity-functions.h b/lib/src/il2cpp-unity-functions.h new file mode 100644 index 0000000..d229dd1 --- /dev/null +++ b/lib/src/il2cpp-unity-functions.h @@ -0,0 +1,3 @@ +using namespace Genshin; + +DO_UNI_FUNC(0x00B7B980, 0x00B7B980, ByteArray*, UnityEngine_RecordUserData, (int32_t nType)); diff --git a/lib/src/util.cpp b/lib/src/util.cpp index 01b1003..3467a8e 100644 --- a/lib/src/util.cpp +++ b/lib/src/util.cpp @@ -13,6 +13,14 @@ string IlStringToString(Il2CppString* str, UINT codePage) { #pragma endregion +#pragma region GC + +UINT32 GCHandle_New(void* object, bool pinned) { + return il2cpp_gchandle_new((Il2CppObject*)object, pinned); +} + +#pragma endregion + #pragma region ByteUtils bool IsLittleEndian() { diff --git a/lib/src/util.h b/lib/src/util.h index 83959be..10ca5c5 100644 --- a/lib/src/util.h +++ b/lib/src/util.h @@ -4,8 +4,12 @@ using std::string; bool IsLittleEndian(); HWND FindMainWindowByPID(DWORD pid); +UINT32 GCHandle_New(LPVOID object, bool pinned); string IlStringToString(Il2CppString* str, UINT codePage = CP_ACP); +#define cstring_new(str) il2cpp_string_new(str) +#define string_new(str) cstring_new((str).c_str()) + #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()) @@ -22,3 +26,8 @@ static T ReadMapped(void* data, int offset, bool littleEndian = false) { memcpy(&result, cData + offset, sizeof(result)); return result; } + +template +static T* GCHandle_GetObject(UINT handle) { + return (T*) il2cpp_gchandle_get_target(handle); +}