mirror of
https://github.com/araxiaonline/WoW-Launcher.git
synced 2026-06-13 01:22:21 -04:00
Patch in a static auth seed to remove the need of updating them on new builds:
- Only works with --staticseed launch arg. - Works on all supported game versions. - Use the following auth seed on your server: 179D3DC3235629D07113A9B3867F97A7
This commit is contained in:
@@ -12,6 +12,7 @@ static class LaunchOptions
|
||||
public static Option<string> GamePath = new("--path");
|
||||
public static Option<string> GameBinary = new("--binary");
|
||||
public static Option<bool> KeepCache = new("--keepcache", () => true);
|
||||
public static Option<bool> UseStaticAuthSeed = new("--staticseed");
|
||||
|
||||
public static Parser Instance => new CommandLineBuilder(ConfigureCommandLine(RootCommand))
|
||||
.UseHelp()
|
||||
@@ -26,7 +27,8 @@ static class LaunchOptions
|
||||
Version,
|
||||
GamePath,
|
||||
GameBinary,
|
||||
KeepCache
|
||||
KeepCache,
|
||||
UseStaticAuthSeed
|
||||
};
|
||||
|
||||
static Command ConfigureCommandLine(Command rootCommand)
|
||||
|
||||
@@ -90,7 +90,7 @@ class Launcher
|
||||
return gameBinaryPath;
|
||||
}
|
||||
|
||||
public static bool LaunchGame(string appPath, string gameCommandLine)
|
||||
public static bool LaunchGame(string appPath, string gameCommandLine, bool useStaticAuthSeed)
|
||||
{
|
||||
var startupInfo = new StartupInfo();
|
||||
var processInfo = new ProcessInformation();
|
||||
@@ -135,6 +135,9 @@ class Launcher
|
||||
// Refresh the client data before patching.
|
||||
memory.RefreshMemoryData((int)gameAppData.Length);
|
||||
|
||||
// We need to cache this here since we are using our RSA modulus as auth seed.
|
||||
var modulusOffset = memory.Data.FindPattern(Patterns.Common.SignatureModulus);
|
||||
|
||||
// Wait for all direct memory patch tasks to complete,
|
||||
Task.WaitAll(new[]
|
||||
{
|
||||
@@ -154,25 +157,7 @@ class Launcher
|
||||
|
||||
NativeWindows.NtResumeProcess(processInfo.ProcessHandle);
|
||||
|
||||
// Wait for client initialization.
|
||||
var initOffset = memory?.Read(mbi.BaseAddress, (int)mbi.RegionSize)?.FindPattern(Patterns.Windows.Init) ?? 0;
|
||||
|
||||
while (initOffset == 0)
|
||||
{
|
||||
initOffset = memory?.Read(mbi.BaseAddress, (int)mbi.RegionSize)?.FindPattern(Patterns.Windows.Init) ?? 0;
|
||||
|
||||
Console.WriteLine("Waiting for client initialization...");
|
||||
}
|
||||
|
||||
initOffset += BitConverter.ToUInt32(memory.Read(initOffset + memory.BaseAddress + 2, 4), 0) + 10;
|
||||
|
||||
while (memory?.Read(initOffset + memory.BaseAddress, 1)?[0] == null ||
|
||||
memory?.Read(initOffset + memory.BaseAddress, 1)?[0] == 0)
|
||||
memory.Data = memory.Read(mbi.BaseAddress, (int)mbi.RegionSize);
|
||||
|
||||
PrepareAntiCrash(memory, ref mbi, ref processInfo);
|
||||
|
||||
memory.RefreshMemoryData((int)mbi.RegionSize);
|
||||
WaitForUnpack(ref processInfo, memory, ref mbi);
|
||||
|
||||
#if x64
|
||||
Task.WaitAll(new[]
|
||||
@@ -180,6 +165,21 @@ class Launcher
|
||||
memory.QueuePatch(Patterns.Windows.CertBundle, Patches.Windows.CertBundle, "CertBundle"),
|
||||
memory.QueuePatch(Patterns.Windows.CertCommonName, Patches.Windows.CertCommonName, "CertCommonName", 5)
|
||||
}, CancellationTokenSource.Token);
|
||||
|
||||
if (useStaticAuthSeed)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
Console.WriteLine("Static auth seed used. Be sure that the server you are connecting to supports it.");
|
||||
Console.ResetColor();
|
||||
|
||||
// Generates a patch for the auth seed so we don't have to update them on each build.
|
||||
var authSeedFunctionOffset = GenerateAuthSeedFunctionPatch(memory, modulusOffset);
|
||||
|
||||
Task.WaitAll(new[]
|
||||
{
|
||||
memory.QueuePatch(authSeedFunctionOffset, Patches.Windows.AuthSeed, "CustomAuthSeedFunction")
|
||||
}, CancellationTokenSource.Token);
|
||||
}
|
||||
#if CUSTOM_FILES
|
||||
Task.WaitAll(new[]
|
||||
{
|
||||
@@ -248,6 +248,49 @@ class Launcher
|
||||
return false;
|
||||
}
|
||||
|
||||
static long GenerateAuthSeedFunctionPatch(WinMemory memory, long modulusOffset)
|
||||
{
|
||||
var authSeedLoadOffset = memory.Data.FindPattern(Patterns.Windows.AuthSeed);
|
||||
|
||||
if (authSeedLoadOffset == 0)
|
||||
throw new InvalidDataException("authSeedLoadOffset");
|
||||
|
||||
var leaStartOffset = authSeedLoadOffset + 9;
|
||||
var leaValue = Unsafe.ReadUnaligned<int>(ref memory.Data[leaStartOffset + 3]);
|
||||
var authSeedWrapperOffset = leaStartOffset + leaValue + 7;
|
||||
var jmpValue = Unsafe.ReadUnaligned<uint>(ref memory.Data[authSeedWrapperOffset + 6]);
|
||||
var authSeedFunctionOffset = authSeedWrapperOffset + 5 + jmpValue + 5;
|
||||
|
||||
// Write the modulus offset to our custom get seed functions.
|
||||
// Resulting static auth seed is: 179D3DC3235629D07113A9B3867F97A7
|
||||
Unsafe.WriteUnaligned(ref Patches.Windows.AuthSeed[3], (uint)(modulusOffset - authSeedFunctionOffset - 7));
|
||||
|
||||
return authSeedFunctionOffset;
|
||||
}
|
||||
|
||||
static void WaitForUnpack(ref ProcessInformation processInfo, WinMemory memory, ref MemoryBasicInformation mbi)
|
||||
{
|
||||
// Wait for client initialization.
|
||||
var initOffset = memory?.Read(mbi.BaseAddress, (int)mbi.RegionSize)?.FindPattern(Patterns.Windows.Init) ?? 0;
|
||||
|
||||
while (initOffset == 0)
|
||||
{
|
||||
initOffset = memory?.Read(mbi.BaseAddress, (int)mbi.RegionSize)?.FindPattern(Patterns.Windows.Init) ?? 0;
|
||||
|
||||
Console.WriteLine("Waiting for client initialization...");
|
||||
}
|
||||
|
||||
initOffset += BitConverter.ToUInt32(memory.Read(initOffset + memory.BaseAddress + 2, 4), 0) + 10;
|
||||
|
||||
while (memory?.Read(initOffset + memory.BaseAddress, 1)?[0] == null ||
|
||||
memory?.Read(initOffset + memory.BaseAddress, 1)?[0] == 0)
|
||||
memory.Data = memory.Read(mbi.BaseAddress, (int)mbi.RegionSize);
|
||||
|
||||
PrepareAntiCrash(memory, ref mbi, ref processInfo);
|
||||
|
||||
memory.RefreshMemoryData((int)mbi.RegionSize);
|
||||
}
|
||||
|
||||
static void PrepareAntiCrash(WinMemory memory, ref MemoryBasicInformation mbi, ref ProcessInformation processInfo)
|
||||
{
|
||||
memory.RefreshMemoryData((int)mbi.RegionSize);
|
||||
|
||||
@@ -11,6 +11,7 @@ static class Windows
|
||||
public static byte[] CertCommonName = { 0xB0, 0x01 };
|
||||
public static byte[] ShortJump = { 0xEB };
|
||||
public static byte[] NoJump = { 0x00, 0x00, 0x00, 0x00 };
|
||||
public static byte[] AuthSeed = { 0x0F, 0x28, 0x05, 0xEF, 0xBE, 0xAD, 0xDE, 0x0F, 0x11, 0x02, 0xC3 };
|
||||
#elif ARM64
|
||||
public static byte[] Integrity = { };
|
||||
public static byte[] Branch = { 0xB5 };
|
||||
|
||||
@@ -17,6 +17,9 @@ static class Windows
|
||||
public static short[] CertBundle = { 0x75, 0x06, 0x48, -1, -1, 0x60, 0x5F, 0xC3 };
|
||||
public static short[] CertCommonName = { 0x80, -1, 0x2A, 0x75, -1, 0x32, 0xC0, 0x48 };
|
||||
|
||||
// Auth seed function.
|
||||
public static short[] AuthSeed = { 0x57, 0x6F, 0x57, 0x00, 0xE8, -1, -1, -1, -1, 0x48, 0x8D };
|
||||
|
||||
// Custom files (mods).
|
||||
public static short[] LoadByFileId = { 0x41, -1, -1, 0x01, 0x0F, 0x84, -1, 0x00, 0x00, 0x00, 0x48, 0x8B, -1, -1, -1, -1, -1, 0x8B };
|
||||
public static short[] LoadByFilePath = { 0x01, 0x0F, 0x84, -1, -1, -1, -1, 0x48, 0x8B, -1, -1, -1, -1, -1, 0x44, 0x89, -1, -1, -1, 0x48, 0x85, 0xC9 };
|
||||
|
||||
@@ -16,7 +16,7 @@ LaunchOptions.RootCommand.SetHandler(context =>
|
||||
var appPath = Launcher.PrepareGameLaunch(context.ParseResult);
|
||||
var gameCommandLine = string.Join(" ", context.ParseResult.UnmatchedTokens);
|
||||
|
||||
if (string.IsNullOrEmpty(appPath) || !Launcher.LaunchGame(appPath, gameCommandLine))
|
||||
if (string.IsNullOrEmpty(appPath) || !Launcher.LaunchGame(appPath, gameCommandLine, context.ParseResult.HasOption(LaunchOptions.UseStaticAuthSeed)))
|
||||
WaitAndExit(5000);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user