using System.Runtime.Versioning;
using System.Buffers.Binary;
using HaloPixelToolBox.Core.Utilities;
namespace HaloPixelToolBox.Client.Test;
[SupportedOSPlatform("windows")]
internal class Program
{
[SMTest]
public static void TestMethod()
{
var device = new HaloPixelDevice();
device.Initialize();
}
[SMTest]
public static void ParseLrcLyrics()
{
var lines = LrcParser.Parse("[00:02.50]第二句\n[00:01.005]第一句\n[00:03.5]第三句");
XFECode.Assert(lines.Count == 3, "应解析出三行歌词");
XFECode.Assert(lines[0].Text == "第一句" && lines[0].Timestamp.TotalMilliseconds == 1005, "三位毫秒时间戳解析错误");
XFECode.Assert(lines[1].Text == "第二句" && lines[1].Timestamp.TotalMilliseconds == 2500, "两位百分秒时间戳解析错误");
XFECode.Assert(lines[2].Text == "第三句" && lines[2].Timestamp.TotalMilliseconds == 3500, "一位十分秒时间戳解析错误");
}
[SMTest]
public static void ScanCloudMusicSignature()
{
var image = new byte[0x400];
image[0] = (byte)'M';
image[1] = (byte)'Z';
BinaryPrimitives.WriteInt32LittleEndian(image.AsSpan(0x3C, 4), 0x80);
image[0x80] = (byte)'P';
image[0x81] = (byte)'E';
BinaryPrimitives.WriteUInt16LittleEndian(image.AsSpan(0x86, 2), 1);
BinaryPrimitives.WriteUInt16LittleEndian(image.AsSpan(0x94, 2), 0xF0);
BinaryPrimitives.WriteUInt32LittleEndian(image.AsSpan(0x80 + 24 + 56, 4), 0x5000);
const int sectionHeader = 0x80 + 24 + 0xF0;
BinaryPrimitives.WriteUInt32LittleEndian(image.AsSpan(sectionHeader + 12, 4), 0x1000);
BinaryPrimitives.WriteUInt32LittleEndian(image.AsSpan(sectionHeader + 16, 4), 0x200);
BinaryPrimitives.WriteUInt32LittleEndian(image.AsSpan(sectionHeader + 20, 4), 0x200);
BinaryPrimitives.WriteUInt32LittleEndian(image.AsSpan(sectionHeader + 36, 4), 0x20000000);
const int signatureOffset = 0x220;
const int signatureRva = 0x1020;
const int targetRva = 0x3450;
byte?[] signature =
[
0x48, 0x8D, 0x0D, null, null, null, null,
0xE8, null, null, null, null,
0x48, 0x8B, 0xC8,
0xE8, null, null, null, null,
0x48, 0xC7, 0x05, null, null, null, null,
0x00, 0x00, 0x00, 0x00
];
for (var index = 0; index < signature.Length; index++)
image[signatureOffset + index] = signature[index] ?? 0x5A;
BinaryPrimitives.WriteInt32LittleEndian(image.AsSpan(signatureOffset + 3, 4), targetRva - (signatureRva + 7));
BinaryPrimitives.WriteInt32LittleEndian(image.AsSpan(signatureOffset + 23, 4), targetRva - (signatureRva + signature.Length));
var candidates = CloudMusicSignatureScanner.FindBaseAddresses(image);
XFECode.Assert(candidates.Count == 1 && candidates[0] == targetRva, "应通过两条 RIP 相对指令解析出唯一目标 RVA");
}
}
using System.Runtime.Versioning;
using System.Buffers.Binary;
using HaloPixelToolBox.Core.Utilities;
namespace HaloPixelToolBox.Client.Test;
[SupportedOSPlatform("windows")]
internal class Program
{
[SMTest]
public static void TestMethod()
{
var device = new HaloPixelDevice();
device.Initialize();
}
[SMTest]
public static void ParseLrcLyrics()
{
var lines = LrcParser.Parse("[00:02.50]第二句\n[00:01.005]第一句\n[00:03.5]第三句");
XFECode.Assert(lines.Count == 3, "应解析出三行歌词");
XFECode.Assert(lines[0].Text == "第一句" && lines[0].Timestamp.TotalMilliseconds == 1005, "三位毫秒时间戳解析错误");
XFECode.Assert(lines[1].Text == "第二句" && lines[1].Timestamp.TotalMilliseconds == 2500, "两位百分秒时间戳解析错误");
XFECode.Assert(lines[2].Text == "第三句" && lines[2].Timestamp.TotalMilliseconds == 3500, "一位十分秒时间戳解析错误");
}
[SMTest]
public static void ScanCloudMusicSignature()
{
var image = new byte[0x400];
image[0] = (byte)'M';
image[1] = (byte)'Z';
BinaryPrimitives.WriteInt32LittleEndian(image.AsSpan(0x3C, 4), 0x80);
image[0x80] = (byte)'P';
image[0x81] = (byte)'E';
BinaryPrimitives.WriteUInt16LittleEndian(image.AsSpan(0x86, 2), 1);
BinaryPrimitives.WriteUInt16LittleEndian(image.AsSpan(0x94, 2), 0xF0);
BinaryPrimitives.WriteUInt32LittleEndian(image.AsSpan(0x80 + 24 + 56, 4), 0x5000);
const int sectionHeader = 0x80 + 24 + 0xF0;
BinaryPrimitives.WriteUInt32LittleEndian(image.AsSpan(sectionHeader + 12, 4), 0x1000);
BinaryPrimitives.WriteUInt32LittleEndian(image.AsSpan(sectionHeader + 16, 4), 0x200);
BinaryPrimitives.WriteUInt32LittleEndian(image.AsSpan(sectionHeader + 20, 4), 0x200);
BinaryPrimitives.WriteUInt32LittleEndian(image.AsSpan(sectionHeader + 36, 4), 0x20000000);
const int signatureOffset = 0x220;
const int signatureRva = 0x1020;
const int targetRva = 0x3450;
byte?[] signature =
[
0x48, 0x8D, 0x0D, null, null, null, null,
0xE8, null, null, null, null,
0x48, 0x8B, 0xC8,
0xE8, null, null, null, null,
0x48, 0xC7, 0x05, null, null, null, null,
0x00, 0x00, 0x00, 0x00
];
for (var index = 0; index < signature.Length; index++)
image[signatureOffset + index] = signature[index] ?? 0x5A;
BinaryPrimitives.WriteInt32LittleEndian(image.AsSpan(signatureOffset + 3, 4), targetRva - (signatureRva + 7));
BinaryPrimitives.WriteInt32LittleEndian(image.AsSpan(signatureOffset + 23, 4), targetRva - (signatureRva + signature.Length));
var candidates = CloudMusicSignatureScanner.FindBaseAddresses(image);
XFECode.Assert(candidates.Count == 1 && candidates[0] == targetRva, "应通过两条 RIP 相对指令解析出唯一目标 RVA");
}
}