private void ApplyStringPatch(String oldString, String newStr) { logger.WriteLine($"[P4G PC EXE PT-BR] Enconding Old String \"{oldString}\""); byte[] encodedOldStr = encoder.EncodeString(oldString); string oldStrBytes = ByteArrayToString(encodedOldStr); PatternScanResult oldStrOffset = scanner.CompiledFindPattern(oldStrBytes); logger.WriteLine($"[P4G PC EXE PT-BR] Finding old string pointer"); byte[] oldStrAddressPattern = StringToByteArray((oldStrOffset.Offset + baseAddress.ToInt32()).ToString("X")); Array.Reverse(oldStrAddressPattern); string oldStrPointerBytes = ByteArrayToString(oldStrAddressPattern); PatternScanResult oldStrPointer = scanner.CompiledFindPattern(oldStrPointerBytes); logger.WriteLine($"[P4G PC EXE PT-BR] Enconding New String \"{newStr}\""); byte[] encodedStr = encoder.EncodeString(newStr); IntPtr newOffset = memory.Allocate(encodedStr.Length); logger.WriteLine($"[P4G PC EXE PT-BR] Patching String \"{newStr}\" at 0x{newOffset.ToInt32().ToString("X")}"); memory.SafeWriteRaw(newOffset, encodedStr); string newOffsetStr = newOffset.ToInt32().ToString("X"); byte[] newOffsetStringBytes = StringToByteArray(newOffsetStr); Array.Reverse(newOffsetStringBytes); IntPtr pointerAddress = IntPtr.Add(baseAddress, oldStrPointer.Offset); logger.WriteLine($"[P4G PC EXE PT-BR] Patching pointer at {pointerAddress.ToInt32().ToString("X")}"); memory.SafeWriteRaw(pointerAddress, newOffsetStringBytes); }
/// <summary> /// Creates a <see cref="CircularBuffer"/> within the target memory source. /// </summary> /// <param name="size">The size of the buffer in bytes.</param> /// <param name="source">The source of the buffer where to read/write elements to/from.</param> public CircularBuffer(int size, IMemory source) { Offset = 0; Size = size; Source = source; Address = source.Allocate(Size); }
public static void SetStruct <T>(this IMemory memory, T value) where T : struct { var length = Marshal.SizeOf <T>(); memory.Allocate(length); Marshal.StructureToPtr(value, memory.Ptr, false); }
private static void WriteToMemoryStream(IMemory memory, Action <Stream> write) { var capacity = 4; // todo memory.Allocate(capacity); while (true) { using (var stream = memory.GetWriteStream()) { try { write(stream); memory.Length = checked ((int)stream.Position); break; } catch (NotSupportedException) { memory.Allocate(capacity *= 2); } } } }
public static void SetString(this IMemory memory, string value, Encoding encoding) { var length = encoding.GetByteCount(value); memory.Allocate(length); #if !NETFRAMEWORK encoding.GetBytes(value, memory.AsSpan()); #else unsafe { fixed(char *chars = value) { encoding.GetBytes(chars, value.Length, (byte *)memory.Ptr, length); } } #endif }
/// <summary> /// The entry point of the application. /// </summary> static void Main(string[] args) { // Reloaded 3.X+ exposes the <IMemory> interface that can be used to read/write arbitrary memory. // You can find implementations such as Reloaded.Memory.Sources; // Get a new instance of "Memory" class implementing "IMemory", that provides access to current process' memory. IMemory memory = Sources.Memory.CurrentProcess; // Static/Preinitialized access to current process' memory. // Tutorial 0: Allocate/Free Memory IntPtr memoryLocation = memory.Allocate(65535); // Did you think it would be harder? // Here's 65535 bytes at memoryLocation. // You would free it with memory.Free(memoryLocation); // Tutorial 1: Basic Reading/Writing Primitives PrimitivesExample(memory, memoryLocation); // Tutorial 2: Writing Structs WriteStructsExample(memory, memoryLocation); // Tutorial 3: Memory Sources [Other Processes etc.] MemorySourceExample(memory, memoryLocation); // Tutorial 4: Struct Arrays StructArrayExample(memory, memoryLocation); // Tutorial 5: Marshalling MarshallingExample(memory, memoryLocation); // Tutorial 6: Struct & StructArray Utility Classes StructUtilityExample(memory, memoryLocation); // Cleanup memory.Free(memoryLocation); Console.WriteLine("Press enter to exit."); Console.ReadLine(); }