Add DLL to modify PlayFab url
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Prospect.Launcher.Invoke;
|
||||
|
||||
namespace Prospect.Launcher
|
||||
{
|
||||
public static class Inject
|
||||
{
|
||||
const int PROCESS_CREATE_THREAD = 0x0002;
|
||||
const int PROCESS_QUERY_INFORMATION = 0x0400;
|
||||
const int PROCESS_VM_OPERATION = 0x0008;
|
||||
const int PROCESS_VM_WRITE = 0x0020;
|
||||
const int PROCESS_VM_READ = 0x0010;
|
||||
|
||||
const uint MEM_COMMIT = 0x00001000;
|
||||
const uint MEM_RESERVE = 0x00002000;
|
||||
const uint PAGE_READWRITE = 4;
|
||||
|
||||
// https://codingvision.net/c-inject-a-dll-into-a-process-w-createremotethread
|
||||
public static unsafe bool Library(uint processId, string path)
|
||||
{
|
||||
IntPtr procHandle = Kernel32.OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, (int)processId);
|
||||
|
||||
var loadLibraryAddr = Kernel32.GetProcAddress(Kernel32.GetModuleHandle("kernel32.dll"), "LoadLibraryA");
|
||||
if (loadLibraryAddr == IntPtr.Zero)
|
||||
{
|
||||
Console.WriteLine("Failed GetProcAddress.");
|
||||
return false;
|
||||
}
|
||||
|
||||
var allocMemAddress = Kernel32.VirtualAllocEx(procHandle, IntPtr.Zero, (uint)((path.Length + 1) * Marshal.SizeOf(typeof(char))), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
if (allocMemAddress == IntPtr.Zero)
|
||||
{
|
||||
Console.WriteLine("Failed VirtualAllocEx.");
|
||||
return false;
|
||||
}
|
||||
|
||||
var libraryBytes = Encoding.Default.GetBytes(path);
|
||||
|
||||
fixed (byte* pLibraryBytes = libraryBytes)
|
||||
{
|
||||
Kernel32.WriteProcessMemory(procHandle, allocMemAddress, pLibraryBytes, libraryBytes.Length + 1, out _);
|
||||
}
|
||||
|
||||
var threadHandle = Kernel32.CreateRemoteThread(procHandle, IntPtr.Zero, 0, loadLibraryAddr, allocMemAddress, 0, IntPtr.Zero);
|
||||
if (threadHandle == IntPtr.Zero)
|
||||
{
|
||||
Console.WriteLine("Failed CreateRemoteThread.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,5 +42,23 @@ namespace Prospect.Launcher.Invoke
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
public static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, uint flNewProtect, out uint lpflOldProtect);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern IntPtr GetModuleHandle(string lpModuleName);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
|
||||
|
||||
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
|
||||
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
|
||||
public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
public static extern uint ResumeThread(IntPtr hThread);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -44,10 +44,13 @@ namespace Prospect.Launcher
|
||||
Write(offset, data);
|
||||
}
|
||||
|
||||
public unsafe void Write(int offset, Span<byte> data)
|
||||
public unsafe void Write(int offset, ReadOnlySpan<byte> data)
|
||||
{
|
||||
Write(_baseAddress + offset, data);
|
||||
}
|
||||
|
||||
public unsafe void Write(IntPtr addr, ReadOnlySpan<byte> data)
|
||||
{
|
||||
var addr = _baseAddress + offset;
|
||||
|
||||
// Modify protection.
|
||||
if (!Kernel32.VirtualProtectEx(_handle, addr, data.Length, 0x40, out var oldProtect))
|
||||
{
|
||||
@@ -56,7 +59,7 @@ namespace Prospect.Launcher
|
||||
|
||||
fixed (byte* pData = data)
|
||||
{
|
||||
var write = Kernel32.WriteProcessMemory(_handle, _baseAddress + offset, pData, data.Length, out _);
|
||||
var write = Kernel32.WriteProcessMemory(_handle, addr, pData, data.Length, out _);
|
||||
|
||||
// Restore protection.
|
||||
Kernel32.VirtualProtectEx(_handle, addr, data.Length, oldProtect, out _);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Prospect.Launcher.Invoke;
|
||||
using Prospect.Launcher.Invoke.Structs;
|
||||
|
||||
@@ -33,6 +32,7 @@ namespace Prospect.Launcher
|
||||
|
||||
// 2EA46 = Default
|
||||
// A22AB = The Cycle Playtest
|
||||
gameArgs.Add("-empty");
|
||||
gameArgs.Add("-log");
|
||||
gameArgs.Add("-windowed");
|
||||
gameArgs.Add("-noeac");
|
||||
@@ -51,7 +51,7 @@ namespace Prospect.Launcher
|
||||
// Spawn.
|
||||
var startupInfo = new StartupInfo();
|
||||
|
||||
if (!Kernel32.CreateProcess(gameBinary, string.Join(' ', gameArgs), ProcessCreationFlags.ZERO_FLAG, ref startupInfo, out var processInfo))
|
||||
if (!Kernel32.CreateProcess(gameBinary, string.Join(' ', gameArgs), ProcessCreationFlags.CREATE_SUSPENDED, ref startupInfo, out var processInfo))
|
||||
{
|
||||
Console.WriteLine("Failed to spawn game.");
|
||||
return;
|
||||
@@ -59,22 +59,21 @@ namespace Prospect.Launcher
|
||||
|
||||
Console.WriteLine("Spawned.");
|
||||
|
||||
// Modify.
|
||||
MemoryHelper memory;
|
||||
|
||||
while ((memory = MemoryHelper.CreateForHandle(processInfo.hProcess, gameBinary)) == null)
|
||||
{
|
||||
Console.WriteLine("Failed to obtain MemoryHelper.");
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
// Inject DLL.
|
||||
var agentPath = Path.Combine(AppContext.BaseDirectory, "Libs", "Prospect.Agent.dll");
|
||||
|
||||
if (!Patches.ChangePlayFabUrl(memory, ".localhost"))
|
||||
if (!Inject.Library(processInfo.dwProcessId, agentPath))
|
||||
{
|
||||
Console.WriteLine("Failed to patch playfab url.");
|
||||
Console.WriteLine("Failed to inject library.");
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine("Injected.");
|
||||
|
||||
// Resume.
|
||||
Kernel32.ResumeThread(processInfo.hThread);
|
||||
|
||||
Console.WriteLine("Patched.");
|
||||
Console.WriteLine("Resumed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,4 +14,14 @@
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Libs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Libs\Prospect.Agent.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user