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