diff --git a/YaeAchievement.csproj b/YaeAchievement.csproj index 986a23e..134f632 100644 --- a/YaeAchievement.csproj +++ b/YaeAchievement.csproj @@ -2,7 +2,7 @@ Exe - net7.0-windows7 + net7.0-windows enable enable preview diff --git a/lib/YaeAchievementLib.vcxproj b/lib/YaeAchievementLib.vcxproj index a8ae0f5..9f48be0 100644 --- a/lib/YaeAchievementLib.vcxproj +++ b/lib/YaeAchievementLib.vcxproj @@ -105,7 +105,7 @@ detours-x64.lib;%(AdditionalDependencies) - copy $(TargetPath) $(ProjectDir)..\bin\Debug\net6.0\win-x64\YaeAchievementLib.dll /y + copy $(TargetPath) $(ProjectDir)..\bin\Debug\net7.0-windows\win-x64\YaeAchievementLib.dll /y diff --git a/lib/src/dllmain.cpp b/lib/src/dllmain.cpp index fa44fbd..7afe083 100644 --- a/lib/src/dllmain.cpp +++ b/lib/src/dllmain.cpp @@ -8,7 +8,8 @@ using std::to_string; HWND unityWnd = 0; HANDLE hPipe = 0; -std::set PacketWhitelist = { 105, 155, 187, 198, 2688, 20, 74 }; // Allow Protocol: GetPlayerToken, PlayerLogin, AchievementAllDataNotify, Ping +// Allow Protocol: GetPlayerToken, PlayerLogin, AchievementAllDataNotify, Ping +std::set PacketWhitelist = { 167, 175, 154, 164, 2698, 14, 34, 106 }; bool OnPacket(KcpPacket* pkt) { if (pkt->data == nullptr) return true; @@ -29,14 +30,15 @@ bool OnPacket(KcpPacket* pkt) { return false; } printf("Passed cmdid: %d\n", ReadMapped(data->vector, 2)); - if (ReadMapped(data->vector, 2) == 2688) { + if (ReadMapped(data->vector, 2) == 2698) { auto headLength = ReadMapped(data->vector, 4); auto dataLength = ReadMapped(data->vector, 6); auto iStr = Genshin::ToBase64String(data, 10 + headLength, dataLength, nullptr); auto cStr = ToString(iStr) + "\n"; WriteFile(hPipe, cStr.c_str(), cStr.length(), nullptr, nullptr); CloseHandle(hPipe); - ExitProcess(0); + auto manager = Genshin::GetSingletonInstance(Genshin::GetSingletonManager(), il2cpp_string_new("GameManager")); + Genshin::ForceQuit(manager); } delete[] data; return true; diff --git a/lib/src/il2cpp-api-functions.h b/lib/src/il2cpp-api-functions.h index a0f72a5..9fab6a6 100644 --- a/lib/src/il2cpp-api-functions.h +++ b/lib/src/il2cpp-api-functions.h @@ -1 +1 @@ -DO_API(0x02D2E840, 0x02D2C0A0, Il2CppString*, il2cpp_string_new, (const char* str)); +DO_API(0x991b10, 0x99ad10, Il2CppString*, il2cpp_string_new, (const char* str)); diff --git a/lib/src/il2cpp-functions.h b/lib/src/il2cpp-functions.h index ce3cfc6..eaea7b7 100644 --- a/lib/src/il2cpp-functions.h +++ b/lib/src/il2cpp-functions.h @@ -2,36 +2,30 @@ using namespace Genshin; // DO_APP_FUNC(CN_OFFSET, OS_OFFSET, RETURN, FUNC_NAME, (ARGS...)); -// N: System.Convert$ToBase64String -// L: mscorlib -DO_APP_FUNC(0x08F056A0, 0x08F1A0F0, Il2CppString*, ToBase64String, (ByteArray* value, int offset, int length, void* method)); +DO_APP_FUNC(0x728c160, 0x71cc2e0, Il2CppString*, ToBase64String, (ByteArray* value, int offset, int length, void* method)); -// N: MoleMole.MonoLoginMainPage.version$set -// L: Assembly-CSharp -DO_APP_FUNC(0X05265A70, 0x052704C0, void, SetVersion, (void* obj, Il2CppString* value, void* method)); +DO_APP_FUNC(0x2e2c930, 0x2dc4b90, void, SetVersion, (void* obj, Il2CppString* value, void* method)); -// N: UnityEngine.Application$RecordUserData -// L: UnityEngine.CoreModule -DO_APP_FUNC(0x09932F30, 0x09947590, ByteArray*, RecordUserData, (int32_t nType)); +DO_APP_FUNC(0x7c318d0, 0x7b69060, ByteArray*, RecordUserData, (int32_t nType)); -// N: MoleMole.Packet$XorEncrypt [Obfuscated] -// L: Assembly-CSharp -DO_APP_FUNC(0x054B3120, 0x054BD670, void, XorEncrypt, (ByteArray** data, int length, void* method)); // OHOBJBNAMJM +DO_APP_FUNC(0x1ba7d30, 0x1b7b9f0, void, XorEncrypt, (ByteArray** data, int length, void* method)); -// N: Kcp.KcpNative$kcp_client_send_packet [Obfuscated] -// L: Assembly-CSharp -DO_APP_FUNC(0x050BB390, 0x050C5AC0, int, KcpSend, (void* client, KcpPacket* pkt, void* method)); // CKKPANHPFAP +DO_APP_FUNC(0xc3fe80, 0xc47280, int, KcpSend, (void* client, KcpPacket* pkt, void* method)); -// N: MoleMole.KcpClient$TryDequeueEvent [Obfuscated] -// L: Assembly-CSharp -DO_APP_FUNC(0x04496B50, 0x0449DBF0, bool, KcpRecv, (void* client, ClientKcpEvent* evt, void* method)); // GFFOOBHMCOJ +DO_APP_FUNC(0xf1ec70, 0xf1bca0, bool, KcpRecv, (void* client, ClientKcpEvent* evt, void* method)); -DO_APP_FUNC(0x09254010, 0x09269550, LPVOID, GetDefaultEncoding, ()); +DO_APP_FUNC(0x75a6880, 0x74e4b80, LPVOID, GetDefaultEncoding, ()); -DO_APP_FUNC(0x092538C0, 0x09268DE0, Il2CppString*, GetString, (LPVOID encoding, LPVOID bytes)); +DO_APP_FUNC(0x75a6130, 0x74e4420, Il2CppString*, GetString, (LPVOID encoding, LPVOID bytes)); -DO_APP_FUNC(0x09252750, 0x09267C60, ByteArray*, GetBytes, (LPVOID encoding, LPVOID str)); +DO_APP_FUNC(0x75a4fc0, 0x74e32b0, ByteArray*, GetBytes, (LPVOID encoding, LPVOID str)); -DO_APP_FUNC(0X05069690, 0X05073B60, VOID, RequestLogin, (LPVOID obj, LPVOID token, UINT uid)); +DO_APP_FUNC(0x1bf31f0, 0x1bc5f60, VOID, RequestLogin, (LPVOID obj, LPVOID token, UINT uid)); -DO_APP_FUNC(0x03C751A0, 0x0500F3D0, VOID, SetChecksum, (LPVOID obj, Il2CppString* value)); +DO_APP_FUNC(0x4922d40, 0x4879590, VOID, SetChecksum, (LPVOID obj, Il2CppString* value)); + +DO_APP_FUNC(0x34780d0, 0x3401460, VOID, ForceQuit, (LPVOID obj)); + +DO_APP_FUNC(0x57df820, 0x5727410, LPVOID, GetSingletonManager, ()); + +DO_APP_FUNC(0x57df550, 0x5727140, LPVOID, GetSingletonInstance, (LPVOID obj, Il2CppString* value)); diff --git a/lib/src/il2cpp-unity-functions.h b/lib/src/il2cpp-unity-functions.h index 88a3fc8..00ad432 100644 --- a/lib/src/il2cpp-unity-functions.h +++ b/lib/src/il2cpp-unity-functions.h @@ -1,3 +1,3 @@ using namespace Genshin; -DO_UNI_FUNC(0x00100550, 0x00100550, ByteArray*, UnityEngine_RecordUserData, (int32_t nType)); +DO_UNI_FUNC(0x00100570, 0x00100570, ByteArray*, UnityEngine_RecordUserData, (int32_t nType)); diff --git a/src/AppCenterSDK/DeviceHelper.cs b/src/AppCenterSDK/DeviceHelper.cs index fa102dd..37547d9 100644 --- a/src/AppCenterSDK/DeviceHelper.cs +++ b/src/AppCenterSDK/DeviceHelper.cs @@ -2,7 +2,6 @@ using Windows.Win32; using Windows.Win32.Foundation; using Windows.Win32.Graphics.Gdi; -//using YaeAchievement.Win32; namespace YaeAchievement.AppCenterSDK; @@ -26,7 +25,7 @@ public static class DeviceHelper { public static string GetScreenSize() { var desktop = Native.GetDC(HWND.Null); var size = $"{Native.GetDeviceCaps(desktop, GET_DEVICE_CAPS_INDEX.DESKTOPHORZRES)}x{Native.GetDeviceCaps(desktop, GET_DEVICE_CAPS_INDEX.DESKTOPVERTRES)}"; - Native.ReleaseDC(HWND.Null, desktop); + _ = Native.ReleaseDC(HWND.Null, desktop); return size; } diff --git a/src/Export.cs b/src/Export.cs index 9039de7..3533b91 100644 --- a/src/Export.cs +++ b/src/Export.cs @@ -1,10 +1,11 @@ -using System.Diagnostics; +using System.ComponentModel; +using System.Diagnostics; using System.Net; -using System.Runtime.Versioning; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using Microsoft.Win32; +using YaeAchievement.AppCenterSDK; using YaeAchievement.res; using static AchievementAllDataNotify.Types.Achievement.Types; @@ -213,4 +214,11 @@ public static class Export { var b = Utils.GetBucketFileAsByteArray("schicksal/metadata"); return AchievementInfo.Parser.ParseFrom(b); } + + public static int PrintMsgAndReturnErrCode(this Win32Exception ex, string msg) { + // ReSharper disable once LocalizableElement + Console.WriteLine($"{msg}: {ex.Message}"); + AppCenter.TrackCrash(ex, false); + return ex.NativeErrorCode; + } } diff --git a/src/Injector.cs b/src/Injector.cs index 5b37ac5..814551a 100644 --- a/src/Injector.cs +++ b/src/Injector.cs @@ -1,19 +1,17 @@ -using Microsoft.Win32.SafeHandles; -using System.ComponentModel; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; +using System.ComponentModel; using Windows.Win32; using Windows.Win32.Foundation; using Windows.Win32.System.Memory; using Windows.Win32.System.Threading; -using YaeAchievement.Win32; namespace YaeAchievement; public static class Injector { public static unsafe bool CreateProcess(string path, out HANDLE hProc, out HANDLE hThread, out uint pid) { Span cmdLines = stackalloc char[1]; // "\0" - var si = new STARTUPINFOW() { cb = unchecked((uint)sizeof(STARTUPINFOW)) }; + var si = new STARTUPINFOW { + cb = unchecked((uint)sizeof(STARTUPINFOW)) + }; var dir = Path.GetDirectoryName(path)!; var result = Native.CreateProcess( path, ref cmdLines, default, default, false, @@ -26,52 +24,38 @@ public static class Injector { } // todo: refactor - public static unsafe int LoadLibraryAndInject(HANDLE hProc, ReadOnlySpan libPath) - { - fixed (char* lpModelName = "kernel32.dll") - { - HINSTANCE hKernel = Native.GetModuleHandle(lpModelName); - - if (hKernel.IsNull) - { + public static unsafe int LoadLibraryAndInject(HANDLE hProc, ReadOnlySpan libPath) { + fixed (char* lpModelName = "kernel32.dll") { + var hKernel = Native.GetModuleHandle(lpModelName); + if (hKernel.IsNull) { return new Win32Exception().PrintMsgAndReturnErrCode("GetModuleHandle fail"); } - - fixed(byte* lpProcName = "LoadLibraryA"u8) - { + fixed(byte* lpProcName = "LoadLibraryA"u8) { var pLoadLibrary = Native.GetProcAddress(hKernel, (PCSTR)lpProcName); - if (pLoadLibrary.IsNull) - { + if (pLoadLibrary.IsNull) { return new Win32Exception().PrintMsgAndReturnErrCode("GetProcAddress fail"); } var pBase = Native.VirtualAllocEx(hProc, default, unchecked((uint)libPath.Length + 1), VIRTUAL_ALLOCATION_TYPE.MEM_RESERVE | VIRTUAL_ALLOCATION_TYPE.MEM_COMMIT, PAGE_PROTECTION_FLAGS.PAGE_READWRITE); - if ((nint)pBase == 0) - { + if ((nint)pBase == 0) { return new Win32Exception().PrintMsgAndReturnErrCode("VirtualAllocEx fail"); } - fixed (void* lpBuffer = libPath) - { - if (!Native.WriteProcessMemory(hProc, pBase, lpBuffer, unchecked((uint)libPath.Length), default)) - { + fixed (void* lpBuffer = libPath) { + if (!Native.WriteProcessMemory(hProc, pBase, lpBuffer, unchecked((uint)libPath.Length))) { return new Win32Exception().PrintMsgAndReturnErrCode("WriteProcessMemory fail"); } } - var lpStartAddress = pLoadLibrary.CreateDelegate(); - var hThread = Native.CreateRemoteThread(hProc, default, 0, lpStartAddress, pBase, 0, default); - - if (hThread.IsNull) - { + var hThread = Native.CreateRemoteThread(hProc, default, 0, lpStartAddress, pBase, 0); + if (hThread.IsNull) { var e = new Win32Exception(); Native.VirtualFreeEx(hProc, pBase, 0, VIRTUAL_FREE_TYPE.MEM_RELEASE); return e.PrintMsgAndReturnErrCode("CreateRemoteThread fail"); } - if (Native.WaitForSingleObject(hThread, 2000) == 0) - { + if (Native.WaitForSingleObject(hThread, 2000) == 0) { Native.VirtualFreeEx(hProc, pBase, 0, VIRTUAL_FREE_TYPE.MEM_RELEASE); } return !Native.CloseHandle(hThread) ? new Win32Exception().PrintMsgAndReturnErrCode("CloseHandle fail") : 0; } } } -} \ No newline at end of file +} diff --git a/src/Proto/AchievementAllDataNotify.cs b/src/Proto/AchievementAllDataNotify.cs index 637464c..012b417 100644 --- a/src/Proto/AchievementAllDataNotify.cs +++ b/src/Proto/AchievementAllDataNotify.cs @@ -23,10 +23,10 @@ public static partial class AchievementAllDataNotifyReflection { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( "Ch5BY2hpZXZlbWVudEFsbERhdGFOb3RpZnkucHJvdG8iowIKGEFjaGlldmVt", - "ZW50QWxsRGF0YU5vdGlmeRIzCgRsaXN0GAQgAygLMiUuQWNoaWV2ZW1lbnRB", + "ZW50QWxsRGF0YU5vdGlmeRIzCgRsaXN0GA8gAygLMiUuQWNoaWV2ZW1lbnRB", "bGxEYXRhTm90aWZ5LkFjaGlldmVtZW50GtEBCgtBY2hpZXZlbWVudBIRCgl0", - "aW1lc3RhbXAYBiABKA0SDwoHY3VycmVudBgKIAEoDRINCgV0b3RhbBgOIAEo", - "DRIKCgJpZBgNIAEoDRI8CgZzdGF0dXMYBSABKA4yLC5BY2hpZXZlbWVudEFs", + "aW1lc3RhbXAYDSABKA0SDwoHY3VycmVudBgCIAEoDRINCgV0b3RhbBgFIAEo", + "DRIKCgJpZBgJIAEoDRI8CgZzdGF0dXMYBiABKA4yLC5BY2hpZXZlbWVudEFs", "bERhdGFOb3RpZnkuQWNoaWV2ZW1lbnQuU3RhdHVzIkUKBlN0YXR1cxILCgdJ", "TlZBTElEEAASDgoKVU5GSU5JU0hFRBABEgwKCEZJTklTSEVEEAISEAoMUkVX", "QVJEX1RBS0VOEANiBnByb3RvMw==")); @@ -85,9 +85,9 @@ public sealed partial class AchievementAllDataNotify : pb::IMessageField number for the "list" field. - public const int ListFieldNumber = 4; + public const int ListFieldNumber = 15; private static readonly pb::FieldCodec _repeated_list_codec - = pb::FieldCodec.ForMessage(34, global::AchievementAllDataNotify.Types.Achievement.Parser); + = pb::FieldCodec.ForMessage(122, global::AchievementAllDataNotify.Types.Achievement.Parser); private readonly pbc::RepeatedField list_ = new pbc::RepeatedField(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] @@ -188,7 +188,7 @@ public sealed partial class AchievementAllDataNotify : pb::IMessageField number for the "timestamp" field. - public const int TimestampFieldNumber = 6; + public const int TimestampFieldNumber = 13; private uint timestamp_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] @@ -282,7 +282,7 @@ public sealed partial class AchievementAllDataNotify : pb::IMessageField number for the "current" field. - public const int CurrentFieldNumber = 10; + public const int CurrentFieldNumber = 2; private uint current_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] @@ -294,7 +294,7 @@ public sealed partial class AchievementAllDataNotify : pb::IMessageField number for the "total" field. - public const int TotalFieldNumber = 14; + public const int TotalFieldNumber = 5; private uint total_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] @@ -306,7 +306,7 @@ public sealed partial class AchievementAllDataNotify : pb::IMessageField number for the "id" field. - public const int IdFieldNumber = 13; + public const int IdFieldNumber = 9; private uint id_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] @@ -318,7 +318,7 @@ public sealed partial class AchievementAllDataNotify : pb::IMessageField number for the "status" field. - public const int StatusFieldNumber = 5; + public const int StatusFieldNumber = 6; private global::AchievementAllDataNotify.Types.Achievement.Types.Status status_ = global::AchievementAllDataNotify.Types.Achievement.Types.Status.Invalid; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] @@ -379,25 +379,25 @@ public sealed partial class AchievementAllDataNotify : pb::IMessage