This commit is contained in:
HolographicHat
2023-02-28 19:16:51 +08:00
parent 8e2e438c96
commit c325b5f754
12 changed files with 116 additions and 144 deletions

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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<char> 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<byte> libPath)
{
fixed (char* lpModelName = "kernel32.dll")
{
HINSTANCE hKernel = Native.GetModuleHandle(lpModelName);
if (hKernel.IsNull)
{
public static unsafe int LoadLibraryAndInject(HANDLE hProc, ReadOnlySpan<byte> 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<LPTHREAD_START_ROUTINE>();
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;
}
}
}
}
}

View File

@@ -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::IMessage<AchievementA
}
/// <summary>Field number for the "list" field.</summary>
public const int ListFieldNumber = 4;
public const int ListFieldNumber = 15;
private static readonly pb::FieldCodec<global::AchievementAllDataNotify.Types.Achievement> _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<global::AchievementAllDataNotify.Types.Achievement> list_ = new pbc::RepeatedField<global::AchievementAllDataNotify.Types.Achievement>();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
@@ -188,7 +188,7 @@ public sealed partial class AchievementAllDataNotify : pb::IMessage<AchievementA
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 34: {
case 122: {
list_.AddEntriesFrom(input, _repeated_list_codec);
break;
}
@@ -207,7 +207,7 @@ public sealed partial class AchievementAllDataNotify : pb::IMessage<AchievementA
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
break;
case 34: {
case 122: {
list_.AddEntriesFrom(ref input, _repeated_list_codec);
break;
}
@@ -270,7 +270,7 @@ public sealed partial class AchievementAllDataNotify : pb::IMessage<AchievementA
}
/// <summary>Field number for the "timestamp" field.</summary>
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::IMessage<AchievementA
}
/// <summary>Field number for the "current" field.</summary>
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::IMessage<AchievementA
}
/// <summary>Field number for the "total" field.</summary>
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::IMessage<AchievementA
}
/// <summary>Field number for the "id" field.</summary>
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::IMessage<AchievementA
}
/// <summary>Field number for the "status" field.</summary>
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<AchievementA
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
if (Status != global::AchievementAllDataNotify.Types.Achievement.Types.Status.Invalid) {
output.WriteRawTag(40);
output.WriteEnum((int) Status);
}
if (Timestamp != 0) {
output.WriteRawTag(48);
output.WriteUInt32(Timestamp);
}
if (Current != 0) {
output.WriteRawTag(80);
output.WriteRawTag(16);
output.WriteUInt32(Current);
}
if (Total != 0) {
output.WriteRawTag(40);
output.WriteUInt32(Total);
}
if (Status != global::AchievementAllDataNotify.Types.Achievement.Types.Status.Invalid) {
output.WriteRawTag(48);
output.WriteEnum((int) Status);
}
if (Id != 0) {
output.WriteRawTag(104);
output.WriteRawTag(72);
output.WriteUInt32(Id);
}
if (Total != 0) {
output.WriteRawTag(112);
output.WriteUInt32(Total);
if (Timestamp != 0) {
output.WriteRawTag(104);
output.WriteUInt32(Timestamp);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
@@ -409,25 +409,25 @@ public sealed partial class AchievementAllDataNotify : pb::IMessage<AchievementA
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
if (Status != global::AchievementAllDataNotify.Types.Achievement.Types.Status.Invalid) {
output.WriteRawTag(40);
output.WriteEnum((int) Status);
}
if (Timestamp != 0) {
output.WriteRawTag(48);
output.WriteUInt32(Timestamp);
}
if (Current != 0) {
output.WriteRawTag(80);
output.WriteRawTag(16);
output.WriteUInt32(Current);
}
if (Total != 0) {
output.WriteRawTag(40);
output.WriteUInt32(Total);
}
if (Status != global::AchievementAllDataNotify.Types.Achievement.Types.Status.Invalid) {
output.WriteRawTag(48);
output.WriteEnum((int) Status);
}
if (Id != 0) {
output.WriteRawTag(104);
output.WriteRawTag(72);
output.WriteUInt32(Id);
}
if (Total != 0) {
output.WriteRawTag(112);
output.WriteUInt32(Total);
if (Timestamp != 0) {
output.WriteRawTag(104);
output.WriteUInt32(Timestamp);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
@@ -496,24 +496,24 @@ public sealed partial class AchievementAllDataNotify : pb::IMessage<AchievementA
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 40: {
Status = (global::AchievementAllDataNotify.Types.Achievement.Types.Status) input.ReadEnum();
break;
}
case 48: {
Timestamp = input.ReadUInt32();
break;
}
case 80: {
case 16: {
Current = input.ReadUInt32();
break;
}
case 104: {
case 40: {
Total = input.ReadUInt32();
break;
}
case 48: {
Status = (global::AchievementAllDataNotify.Types.Achievement.Types.Status) input.ReadEnum();
break;
}
case 72: {
Id = input.ReadUInt32();
break;
}
case 112: {
Total = input.ReadUInt32();
case 104: {
Timestamp = input.ReadUInt32();
break;
}
}
@@ -531,24 +531,24 @@ public sealed partial class AchievementAllDataNotify : pb::IMessage<AchievementA
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
break;
case 40: {
Status = (global::AchievementAllDataNotify.Types.Achievement.Types.Status) input.ReadEnum();
break;
}
case 48: {
Timestamp = input.ReadUInt32();
break;
}
case 80: {
case 16: {
Current = input.ReadUInt32();
break;
}
case 104: {
case 40: {
Total = input.ReadUInt32();
break;
}
case 48: {
Status = (global::AchievementAllDataNotify.Types.Achievement.Types.Status) input.ReadEnum();
break;
}
case 72: {
Id = input.ReadUInt32();
break;
}
case 112: {
Total = input.ReadUInt32();
case 104: {
Timestamp = input.ReadUInt32();
break;
}
}

View File

@@ -12,7 +12,6 @@ using Windows.Win32.Foundation;
using Windows.Win32.System.Console;
using YaeAchievement.AppCenterSDK;
using YaeAchievement.res;
using YaeAchievement.Win32;
namespace YaeAchievement;

View File

@@ -1,14 +0,0 @@
using System.ComponentModel;
using YaeAchievement.AppCenterSDK;
namespace YaeAchievement.Win32;
public static class Extensions {
public static int PrintMsgAndReturnErrCode(this Win32Exception ex, string msg) {
Console.WriteLine($"{msg}: {ex.Message}");
AppCenter.TrackCrash(ex, false);
return ex.NativeErrorCode;
}
}