private static uint GetTagAddress(ProcessMemoryStream stream, int tagIndex) { // Read the tag count and validate the tag index var reader = new BinaryReader(stream); reader.BaseStream.Position = 0x22AB008; var maxIndex = reader.ReadInt32(); if (tagIndex >= maxIndex) return 0; // Read the tag index table to get the index of the tag in the address table reader.BaseStream.Position = 0x22AAFFC; var tagIndexTableAddress = reader.ReadUInt32(); if (tagIndexTableAddress == 0) return 0; reader.BaseStream.Position = tagIndexTableAddress + tagIndex * 4; var addressIndex = reader.ReadInt32(); if (addressIndex < 0) return 0; // Read the tag's address in the address table reader.BaseStream.Position = 0x22AAFF8; var tagAddressTableAddress = reader.ReadUInt32(); if (tagAddressTableAddress == 0) return 0; reader.BaseStream.Position = tagAddressTableAddress + addressIndex * 4; return reader.ReadUInt32(); }
public SecondGenMapPointerReader(ProcessMemoryStream stream, EngineDescription engineInfo, PokingInformation info) { _baseAddress = (long)stream.BaseProcess.MainModule.BaseAddress; _mapHeaderAddress = _baseAddress + info.HeaderAddress.Value; _mapMagicAddress = _baseAddress + info.MagicAddress.Value; _mapSharedMagicAddress = _baseAddress + info.SharedMagicAddress.Value; GetLayoutConstants(engineInfo); var reader = new EndianReader(stream, BitConverter.IsLittleEndian ? Endian.LittleEndian : Endian.BigEndian); ReadMapPointers32(reader); ReadMapHeader(reader); ProcessMapHeader(); }
public override bool Execute(List<string> args) { if (args.Count != 1 && args.Count != 2) return false; int tagIndex; if (!int.TryParse(args[0], NumberStyles.HexNumber, null, out tagIndex) || tagIndex < 0) return false; // Get the process to open Process process; if (args.Count == 2) { // Get process by ID int processId; if (!int.TryParse(args[1], NumberStyles.HexNumber, null, out processId) || processId < 0) return false; try { process = Process.GetProcessById(processId); } catch (ArgumentException) { Console.Error.WriteLine("Unable to find a process with an ID of 0x{0:X}", processId); return true; } } else { // Find first eldorado process var processes = Process.GetProcessesByName("eldorado"); if (processes.Length == 0) { Console.Error.WriteLine("Unable to find any eldorado.exe processes."); return true; } process = processes[0]; } using (var stream = new ProcessMemoryStream(process)) { var address = GetTagAddress(stream, tagIndex); if (address != 0) Console.WriteLine("Tag 0x{0:X} is loaded at 0x{1:X8} in process 0x{2:X}.", tagIndex, address, process.Id); else Console.Error.WriteLine("Tag 0x{0:X} is not loaded in process 0x{1:X}.", tagIndex, process.Id); } return true; }
static void PatchClient(UserSettings settings, SuspendedProcess process, ClientVersion clientVersion, IPAddress serverIPAddress, int serverPort) { if (settings.ShouldRedirectClient && serverIPAddress == null) { throw new ArgumentNullException("serverIPAddress", "Server IP address must be specified when redirecting the client"); } if (settings.ShouldRedirectClient && serverPort <= 0) { throw new ArgumentOutOfRangeException("Server port number must be greater than zero when redirecting the client"); } using (var stream = new ProcessMemoryStream(process.ProcessId)) using (var patcher = new RuntimePatcher(clientVersion, stream, leaveOpen: true)) { // Apply server hostname/port patch if (settings.ShouldRedirectClient && clientVersion.ServerHostnamePatchAddress > 0 && clientVersion.ServerPortPatchAddress > 0) { Debug.WriteLine("Applying server redirect patch..."); patcher.ApplyServerHostnamePatch(serverIPAddress); patcher.ApplyServerPortPatch(serverPort); } // Apply intro video patch if (settings.ShouldSkipIntro && clientVersion.IntroVideoPatchAddress > 0) { Debug.WriteLine("Applying intro video patch..."); patcher.ApplySkipIntroVideoPatch(); } // Apply multiple instances patch if (settings.ShouldAllowMultipleInstances && clientVersion.MultipleInstancePatchAddress > 0) { Debug.WriteLine("Applying multiple instance patch..."); patcher.ApplyMultipleInstancesPatch(); } // Apply hide walls patch if (settings.ShouldHideWalls && clientVersion.HideWallsPatchAddress > 0) { Debug.WriteLine("Applying hide walls patch..."); patcher.ApplyHideWallsPatch(); } } }
/// <summary> /// Obtains a stream which can be used to read and write a cache file's meta in realtime. /// The stream will be set up such that offsets in the stream correspond to meta pointers in the cache file. /// </summary> /// <param name="cacheFile">The cache file to get a stream for.</param> /// <returns>The stream if it was opened successfully, or null otherwise.</returns> public IStream GetMetaStream(ICacheFile cacheFile) { Process gameProcess = FindGameProcess(); if (gameProcess == null) { return(null); } var gameMemory = new ProcessMemoryStream(gameProcess); var mapInfo = new H2VistaMapPointerReader(gameMemory); long metaAddress; if (cacheFile.Type != CacheFileType.Shared) { metaAddress = mapInfo.CurrentMetaAddress; // The map isn't shared, so make sure the map names match if (mapInfo.MapName != cacheFile.InternalName) { gameMemory.Close(); return(null); } } else { metaAddress = mapInfo.SharedMetaAddress; // Make sure the shared and current map pointers are different, // or that the current map is the shared map if (mapInfo.MapType != CacheFileType.Shared && mapInfo.CurrentMetaAddress == mapInfo.SharedMetaAddress) { gameMemory.Close(); return(null); } } var metaStream = new OffsetStream(gameMemory, metaAddress - cacheFile.MetaArea.BasePointer); return(new EndianStream(metaStream, BitConverter.IsLittleEndian ? Endian.LittleEndian : Endian.BigEndian)); }
private static uint GetTagAddress(ProcessMemoryStream stream, int tagIndex) { // Read the tag count and validate the tag index var reader = new BinaryReader(stream); reader.BaseStream.Position = 0x22AB008; var maxIndex = reader.ReadInt32(); if (tagIndex >= maxIndex) { return(0); } // Read the tag index table to get the index of the tag in the address table reader.BaseStream.Position = 0x22AAFFC; var tagIndexTableAddress = reader.ReadUInt32(); if (tagIndexTableAddress == 0) { return(0); } reader.BaseStream.Position = tagIndexTableAddress + tagIndex * 4; var addressIndex = reader.ReadInt32(); if (addressIndex < 0) { return(0); } // Read the tag's address in the address table reader.BaseStream.Position = 0x22AAFF8; var tagAddressTableAddress = reader.ReadUInt32(); if (tagAddressTableAddress == 0) { return(0); } reader.BaseStream.Position = tagAddressTableAddress + addressIndex * 4; return(reader.ReadUInt32()); }
/// <summary> /// Obtains a stream which can be used to read and write a cache file's meta in realtime. /// The stream will be set up such that offsets in the stream correspond to meta pointers in the cache file. /// </summary> /// <param name="cacheFile">The cache file to get a stream for.</param> /// <param name="tag">The tag to get a stream for.</param> /// <returns> /// The stream if it was opened successfully, or null otherwise. /// </returns> public IStream GetMetaStream(ICacheFile cacheFile, ITag tag) { // Open a handle to the game process var gameProcess = FindGameProcess(); if (gameProcess == null) { return(null); } var memoryStream = new ProcessMemoryStream(gameProcess); var exeBase = (uint)memoryStream.BaseProcess.MainModule.BaseAddress - 0x400000; var tagAddress = GetTagAddress(new EndianReader(memoryStream, Endian.LittleEndian), tag.Index.Index, exeBase); if (tagAddress == 0) { memoryStream.Close(); return(null); } var offsetStream = new OffsetStream(memoryStream, tagAddress - tag.HeaderLocation.AsOffset()); return(new EndianStream(offsetStream, Endian.LittleEndian)); }
public ThirdGenMapPointerReader(ProcessMemoryStream processStream, EngineDescription engineInfo, PokingInformation info) { _baseAddress = (long)processStream.BaseProcess.MainModule.BaseAddress; GetLayoutConstants(engineInfo); var reader = new EndianReader(processStream, BitConverter.IsLittleEndian ? Endian.LittleEndian : Endian.BigEndian); if (info.HeaderPointer.HasValue) { reader.SeekTo(_baseAddress + info.HeaderPointer.Value); long address = reader.ReadUInt32(); _mapHeaderAddress = address + 0x8; _mapMagicAddress = address + engineInfo.HeaderSize + info.MagicOffset.Value; } else { _mapHeaderAddress = _baseAddress + info.HeaderAddress.Value; _mapMagicAddress = _baseAddress + info.MagicAddress.Value; } ReadMapPointers32(reader); ReadMapHeader(reader); ProcessMapHeader(); }
// Start is called before the first frame update void Start() { stream = new ProcessMemoryStream(executableName, ProcessMemoryStream.Mode.Read); }
private void Launch() { _config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); string path = _config.AppSettings.Settings["Path"].Value; if (!File.Exists(path)) { MessageBox.Show("Hybrasyl Launcher could not find Dark Ages located at: \r\n" + path, "File not found!", MessageBoxButton.OK, MessageBoxImage.Hand); return; } ProcessInformation information; StartupInfo startupInfo = new StartupInfo(); startupInfo.Size = Marshal.SizeOf(startupInfo); Kernel32.CreateProcess(path, null, IntPtr.Zero, IntPtr.Zero, false, ProcessCreationFlags.Suspended, IntPtr.Zero, null, ref startupInfo, out information); using (ProcessMemoryStream stream = new ProcessMemoryStream(information.ProcessId, ProcessAccess.VmWrite | ProcessAccess.VmRead | ProcessAccess.VmOperation)) { if (_config.AppSettings.Settings["SkipIntro"].Value == "true") { stream.Position = 0x42E625L; // intro stream.WriteByte(0x90); stream.WriteByte(0x90); stream.WriteByte(0x90); stream.WriteByte(0x90); stream.WriteByte(0x90); stream.WriteByte(0x90); } #region Legacy IPAddress Code /*Legacy IP Address code. do not remove.*/ //stream.Position = 0x4333C2L; // ip //IPAddress addr = Dns.GetHostAddresses(HostName)[0]; //var serverBytes = addr.GetAddressBytes(); //stream.WriteByte(0x6A); //stream.WriteByte(serverBytes[3]); //stream.WriteByte(0x6A); //stream.WriteByte(serverBytes[2]); //stream.WriteByte(0x6A); //stream.WriteByte(serverBytes[1]); //stream.WriteByte(0x6A); //stream.WriteByte(serverBytes[0]); //stream.Position = 0x4333F5L; // port //stream.WriteByte((byte)(Port % 256)); //stream.WriteByte((byte)(Port / 256)); /*End legacy IP Address code. do not remove.*/ #endregion var hostBytes = Encoding.UTF8.GetBytes(HostName); byte[] endBytes = new byte[12]; if (hostBytes.Length != 12) { for (var i = 0; i < hostBytes.Length; i++) { endBytes[i] = hostBytes[i]; } } else { endBytes = hostBytes; } stream.Position = 0x6707A8L; stream.Write(endBytes, 0, 12); if (_config.AppSettings.Settings["MultiInstance"].Value == "true") { stream.Position = 0x57A7D9L; // multi-instance stream.WriteByte(0xEB); } else { LaunchEnabled = false; OnPropertyChanged("LaunchEnabled"); } } Kernel32.ResumeThread(information.ThreadHandle); var process = Process.GetProcessById(information.ProcessId); process.WaitForInputIdle(); User32.SetWindowText(process.MainWindowHandle, "DarkAges : Hybrasyl"); }
public override void CreateWriter() { ProcessMemoryStream stream = new ProcessMemoryStream(name, ProcessMemoryStream.Mode.AllAccess); writer = new Writer(stream, Settings.s.IsLittleEndian); }
public override object Execute(List <string> args) { if (args.Count > 1) { return(false); } Process process; if (args.Count == 1) { if (!int.TryParse(args[0], NumberStyles.HexNumber, null, out int processId) || processId < 0) { return(false); } #if !DEBUG try { #endif process = Process.GetProcessById(processId); #if !DEBUG } catch (ArgumentException) { Console.Error.WriteLine("Unable to find a process with an ID of 0x{0:X}", processId); return(true); } #endif } else { var processes = Process.GetProcessesByName("eldorado"); if (processes.Length == 0) { Console.Error.WriteLine("Unable to find any eldorado.exe processes."); return(true); } process = processes[0]; } using (var processStream = new ProcessMemoryStream(process)) { var address = GetTagAddress(processStream, Tag.Index); var runtimeContext = new RuntimeSerializationContext(CacheContext, processStream); processStream.Position = address + Tag.DefinitionOffset; var definition = CacheContext.Deserializer.Deserialize(runtimeContext, TagDefinition.Find(Tag.Group.Tag)); CacheContext.Serializer.Serialize(runtimeContext, Value); if (address != 0) { Console.WriteLine("Tag 0x{0:X} is loaded at 0x{1:X8} in process 0x{2:X}.", Tag.Index, address, process.Id); } else { Console.Error.WriteLine("Tag 0x{0:X} is not loaded in process 0x{1:X}.", Tag.Index, process.Id); } } return(true); }
public override object Execute(List <string> args) { if (args.Count < 1 || args.Count > 2) { return(false); } if (!int.TryParse(args[0], NumberStyles.HexNumber, null, out int tagIndex) || tagIndex < 0) { return(false); } Process process; if (args.Count == 2) { if (!int.TryParse(args[1], NumberStyles.HexNumber, null, out int processId) || processId < 0) { return(false); } try { process = Process.GetProcessById(processId); } catch (ArgumentException) { Console.Error.WriteLine("Unable to find a process with an ID of 0x{0:X}", processId); return(true); } } else { var processes = Process.GetProcessesByName("eldorado"); if (processes.Length == 0) { Console.Error.WriteLine("Unable to find any eldorado.exe processes."); return(true); } process = processes[0]; } using (var stream = new ProcessMemoryStream(process)) { var exeBase = (uint)stream.BaseProcess.MainModule.BaseAddress - 0x400000; var address = GetTagAddress(stream, tagIndex, exeBase); if (address != 0) { Console.WriteLine("Tag 0x{0:X} is loaded at 0x{1:X8} in process 0x{2:X}.", tagIndex, address, process.Id); } else { Console.Error.WriteLine("Tag 0x{0:X} is not loaded in process 0x{1:X}.", tagIndex, process.Id); } } return(true); }
public override object Execute(List <string> args) { if (args.Count > 1) { return(false); } Process process; if (args.Count == 1) { if (!int.TryParse(args[0], NumberStyles.HexNumber, null, out int processId) || processId < 0) { return(false); } #if !DEBUG try { #endif process = Process.GetProcessById(processId); #if !DEBUG } catch (ArgumentException) { Console.Error.WriteLine("Unable to find a process with an ID of 0x{0:X}", processId); return(true); } #endif } else { var processes = Process.GetProcessesByName("eldorado"); if (processes.Length == 0) { Console.Error.WriteLine("Unable to find any eldorado.exe processes."); return(true); } process = processes[0]; } using (var processStream = new ProcessMemoryStream(process)) { var address = GetTagAddress(processStream, Tag.Index); if (address != 0) { var runtimeContext = new RuntimeSerializationContext(Cache, processStream, address, Tag.Offset, Tag.CalculateHeaderSize(), Tag.TotalSize); //pause the process during poking to prevent race conditions Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); process.Suspend(); Cache.Serializer.Serialize(runtimeContext, Value); process.Resume(); stopWatch.Stop(); Console.WriteLine($"Poked tag at 0x{address.ToString("X8")} in {stopWatch.ElapsedMilliseconds / 1000.0f} seconds"); } else { Console.Error.WriteLine("Tag 0x{0:X} is not loaded in process 0x{1:X}.", Tag.Index, process.Id); } } return(true); }
public RuntimeSerializationContext(HaloOnlineCacheContext cacheContext, ProcessMemoryStream processStream) { CacheContext = cacheContext; ProcessStream = processStream; }
/// <summary> /// Obtains a stream which can be used to read and write a cache file's meta in realtime. /// The stream will be set up such that offsets in the stream correspond to meta pointers in the cache file. /// </summary> /// <param name="cacheFile">The cache file to get a stream for.</param> /// <returns>The stream if it was opened successfully, or null otherwise.</returns> public IStream GetMetaStream(ICacheFile cacheFile) { if (string.IsNullOrEmpty(_buildInfo.GameExecutable)) { throw new InvalidOperationException("No gameExecutable value found in Engines.xml for engine " + _buildInfo.Name + "."); } if (_buildInfo.Poking == null) { throw new InvalidOperationException("No poking definitions found in Engines.xml for engine " + _buildInfo.Name + "."); } Process gameProcess = FindGameProcess(); if (gameProcess == null) { return(null); } string version = gameProcess.MainModule.FileVersionInfo.FileVersion; PokingInformation info = _buildInfo.Poking.RetrieveInformation(version); if (info == null) { throw new InvalidOperationException("Game version " + version + " does not have poking information defined in the Formats folder."); } if (!info.HeaderAddress.HasValue) { throw new NotImplementedException("Second Generation poking requires a HeaderAddress value."); } if (!info.MagicAddress.HasValue) { throw new NotImplementedException("Second Generation poking requires a MagicAddress value."); } if (!info.SharedMagicAddress.HasValue) { throw new NotImplementedException("Second Generation poking requires a SharedMagicAddress value."); } var gameMemory = new ProcessMemoryStream(gameProcess); var mapInfo = new SecondGenMapPointerReader(gameMemory, _buildInfo, info); long metaAddress; if (cacheFile.Type != CacheFileType.Shared) { metaAddress = mapInfo.CurrentCacheAddress; // The map isn't shared, so make sure the map names match if (mapInfo.MapName != cacheFile.InternalName) { gameMemory.Close(); return(null); } } else { metaAddress = mapInfo.SharedCacheAddress; // Make sure the shared and current map pointers are different, // or that the current map is the shared map if (mapInfo.MapType != CacheFileType.Shared && mapInfo.CurrentCacheAddress == mapInfo.SharedCacheAddress) { gameMemory.Close(); return(null); } } var metaStream = new OffsetStream(gameMemory, metaAddress - cacheFile.MetaArea.BasePointer); return(new EndianStream(metaStream, BitConverter.IsLittleEndian ? Endian.LittleEndian : Endian.BigEndian)); }