/// <summary> /// Gets an address from a vtable index. Since it uses index * IntPtr, it should work for both x64 and x32. /// </summary> /// <param name="intPtr">The int PTR.</param> /// <param name="functionIndex">Index of the function.</param> /// <returns>IntPtr.</returns> public static InternalMemoryPointer GetVtableAddress(this MemoryPointer intPtr, int functionIndex) { IntPtr vftable = intPtr.Read <IntPtr>(); IntPtr result = new InternalMemoryPointer(vftable + (functionIndex * IntPtr.Size)).Read <IntPtr>(); return(new InternalMemoryPointer(result)); }
public static byte[] CreateFunctionCall(this MemoryPointer memoryAddress) { List <byte> bytes = new List <byte>(); // 64-bit if (GameSharpProcess.Instance.Is64Bit) { // MOV RAX, bytes.AddRange(new byte[] { 0x48, 0xB8 }); // FUNCTION PTR bytes.AddRange(BitConverter.GetBytes(memoryAddress.Address.ToInt64())); // CALL RAX bytes.AddRange(new byte[] { 0xFF, 0xD0 }); } else { // PUSH opcode http://ref.x86asm.net/coder32.html#x68 bytes.Add(0x68); // FUNCTION TO PUSH bytes.AddRange(BitConverter.GetBytes(memoryAddress.Address.ToInt32())); } // RETN opcode http://ref.x86asm.net/coder32.html#xC3 bytes.Add(0xC3); return(bytes.ToArray()); }
/// <summary> /// Reserve a heap's chunk and returns a pointer to this area. /// </summary> /// <param name="count">Number of bytes to reserve.</param> /// <returns>An handle to the reserved area.</returns> public virtual MemoryPointer Alloc(uint count) { // - Creates a new pointer without reference MemoryPointer newPointer = new MemoryPointer(this, count, 0); return(Alloc(newPointer)); }
private void FillMemoryPointer(MemoryPointer memoryPointer, byte[] function) { MemoryPatch = new MemoryPatch(memoryPointer, function); byte[] retToMemoryPtr = MemoryPatch.PatchAddress.CreateFunctionCall(); HookPatch = new MemoryPatch(TargetFuncPtr, retToMemoryPtr); }
public static T ToDelegate <T>(this MemoryPointer memoryAddress) where T : class { if (typeof(T).GetCustomAttributes(typeof(UnmanagedFunctionPointerAttribute), true).Length == 0) { throw new InvalidOperationException("This operation can only convert to delegates adorned with the UnmanagedFunctionPointerAttribute"); } return(Marshal.GetDelegateForFunctionPointer <T>(memoryAddress.Address)); }
private MemoryPointer AllocateMemory(byte[] function) { LoggingService.Info($"Allocating memory for hook {TargetDelegate}"); MemoryPointer allocatedMemory = GameSharpProcess.Instance.AllocateManagedMemory(function.Length); LoggingService.Info($"Allocated memory at {allocatedMemory}"); return(allocatedMemory); }
/// <summary> /// Reserves a heap's chunk and returns a pointer to this area. /// </summary> /// <param name="newPointer">Number of bytes to reserve.</param> /// <returns>An handle to the reserved area.</returns> protected virtual MemoryPointer Alloc(MemoryPointer newPointer) { // - Iterate over the free spaces for (int i = FreeSpace.Count - 1; i >= 0; --i) { var freeChunk = FreeSpace[i]; // - If we found a suitable free space if (freeChunk.Size >= newPointer.Size) { // - Set the position to the current free chunk newPointer.ChangeOffsetAndSize(freeChunk.Offset, newPointer.Size); // - Calculates the remaining space uint remainingSpace = freeChunk.Size - newPointer.Size; // - If no memory remains in the free space pointer we must delete it if (remainingSpace <= 0) { FreeSpace.Remove(freeChunk); } else { freeChunk.ChangeOffsetAndSize(newPointer.Offset + newPointer.Size, remainingSpace); } // - Adds the new pointer to the used space UsedSpace.Add(newPointer); // - Sort used space UsedSpace.OrderBy(x => x.Offset); // - Update fragmentation factor FragmentationFactor = CalculateFragmentationRate(); return(newPointer); } } // - Expand the heap if (!Grow(newPointer.Size)) { Defrag(); if (FreeSpace.Count > 0 && FreeSpace.Last().Size > newPointer.Size) { return(Alloc(newPointer)); } return(null); } return(Alloc(newPointer)); }
private void ValidateDbgBreakPoint() { ModulePointer ntdll = Process.Modules["ntdll.dll"]; MemoryPointer dbgBreakPointPtr = ntdll.GetProcAddress("DbgBreakPoint"); byte dbgBreakPointByte = dbgBreakPointPtr.Read <byte>(); if (dbgBreakPointByte != 0xCC) { MemoryPatches.Add(new MemoryPatch(dbgBreakPointPtr, new byte[] { 0xCC })); } }
public IMemoryPointer ClaimPointerAtEnd( Action <EndianBinaryReader> readHandler, Action <EndianBinaryWriter> writeHandler) { var pointerImpl = this.impl_.ClaimSubrangeAtEnd(null); var pointer = new MemoryPointer( pointerImpl, readHandler, writeHandler); pointerImpl.Data = pointer; return(pointer); }
public IMemoryPointer ClaimPointerWithin( long offsetInBytes, Action <EndianBinaryReader> readHandler, Action <EndianBinaryWriter> writeHandler) { var pointerImpl = this.impl_.ClaimSubrangeWithin(null, offsetInBytes); var pointer = new MemoryPointer( pointerImpl, readHandler, writeHandler); pointerImpl.Data = pointer; return(pointer); }
private MemoryPointer CreateAntiCheatCodeCave(byte[] function) { LoggingService.Info($"Searching anti-cheat code cave for hook {TargetDelegate}"); InternalModulePointer module = TargetFuncPtr.GetMyModule(); if (module == null) { throw new NullReferenceException("Cannot find a module which belongs to the specified pointer."); } MemoryPointer codeCavePtr = module.FindCodeCaveInModule((uint)function.Length); LoggingService.Info($"Found codecave at 0x{codeCavePtr.ToString()}"); return(codeCavePtr); }
/// <summary> /// Initializes a new instance of the <see cref="Hook" /> class. /// /// A hook can be used to create a detour from an original function into your own function. /// You can then proceed to call the original function by using the method <see cref="CallOriginal" />. /// </summary> /// <param name="target">The target delegate we want to detour.</param> /// <param name="hook">The hook delegate where want it to go.</param> public Hook(bool useAntiCheatHook = true) { try { TargetDelegate = GetHookDelegate(); HookDelegate = GetDetourDelegate(); TargetFuncPtr = TargetDelegate.ToFunctionPtr(); HookPtr = HookDelegate.ToFunctionPtr(); byte[] function = HookPtr.CreateFunctionCall(); MemoryPointer codeCavePtr = useAntiCheatHook ? CreateAntiCheatCodeCave(function) : AllocateMemory(function); FillMemoryPointer(codeCavePtr, function); } catch (Exception ex) { LoggingService.Error($"Hook {ToString()}, could not be initialized: {ex.Message}"); } }
public SafeFunction() { try { Delegate motherDelegate = InitializeDelegate(); InternalMemoryPointer delegatePtr = motherDelegate.ToFunctionPtr(); InternalModulePointer module = delegatePtr.GetMyModule(); Type typeOfDelegate = motherDelegate.GetType(); List <byte> bytes = new List <byte>(); bytes.AddRange(delegatePtr.CreateFunctionCall()); CodeCaveSize = bytes.Count < 12 ? 12 : bytes.Count; MemoryPointer jumpTable = null; if (module != null) { // If the function belongs to a module we can find we want to inject our code bytes into that module before calling it. jumpTable = module.FindCodeCaveInModule((uint)CodeCaveSize); } if (jumpTable == null) { LoggingService.Warning($"Couldn't find a codecave in module."); // Allocate memory jumpTable = GameSharpProcess.Instance.AllocateManagedMemory(CodeCaveSize); } jumpTable.Write(bytes.ToArray()); SafeFunctionDelegate = Marshal.GetDelegateForFunctionPointer(delegatePtr.Address, typeOfDelegate); } catch (Exception ex) { LoggingService.Error($"Function {ToString()}, could not be initialized: {ex.Message}"); } }
public RocksDbSinglePut() { var temp = Path.GetTempPath(); var options = (new DbOptions()).SetCreateIfMissing(true).EnableStatistics(); db = RocksDb.Open(options, Environment.ExpandEnvironmentVariables(Path.Combine(temp, Path.GetRandomFileName()))); nodeIndex = new NodeIdIndex(Environment.ExpandEnvironmentVariables(Path.Combine(temp, Path.GetRandomFileName()))); Nodeid = new NodeID(); Nodeid.Pointer = Utils.NullMemoryPointer(); Nodeid.Graph = "graph"; Nodeid.Nodeid = "1"; rp = new Pointers(); mp = Utils.NullMemoryPointer(); mp.Offset = 100UL; mp.Length = 200UL; rp.Pointers_.Add(mp); }
public ModulePointer LoadLibrary(string pathToDll, bool resolveReferences = true) { byte[] loadLibraryOpcodes = LoadLibraryHelper.LoadLibraryPayload(pathToDll); MemoryPointer allocatedMemory = AllocateManagedMemory(loadLibraryOpcodes.Length); if (Kernel32.WriteProcessMemory(Native.Handle, allocatedMemory.Address, loadLibraryOpcodes, loadLibraryOpcodes.Length, out IntPtr _)) { ModulePointer kernel32Module = Modules["kernel32.dll"]; MemoryPointer loadLibraryAddress; if (resolveReferences) { loadLibraryAddress = kernel32Module.GetProcAddress("LoadLibraryW"); } else { loadLibraryAddress = kernel32Module.GetProcAddress("LoadLibraryExW"); } if (loadLibraryAddress == null) { throw new Win32Exception($"Couldn't get proc address, error code: {Marshal.GetLastWin32Error()}."); } if (Kernel32.CreateRemoteThread(Native.Handle, IntPtr.Zero, 0, loadLibraryAddress.Address, allocatedMemory.Address, 0, IntPtr.Zero) == IntPtr.Zero) { throw new Win32Exception($"Couldn't create a remote thread, error code: {Marshal.GetLastWin32Error()}."); } } ModulePointer injectedModule; while (!Modules.TryGetValue(Path.GetFileName(pathToDll).ToLower(), out injectedModule)) { Thread.Sleep(1); } return(injectedModule); }
public MemoryInputBuffer(Memory <byte> memory) { this.pointer = new MemoryPointer { memory = memory }; }
public override Delegate GetHookDelegate() { MemoryPointer ptr = D3DHelper.GetD3D11Endscene(); return(ptr.ToDelegate <delegateObject>()); }
/// <summary> /// Release a portion of heap described by the provided handler. /// </summary> /// <param name="handler">Handler to the memory chunk you want to free.</param> public virtual void Free(MemoryPointer handler) { // - Assure that handler is valid if (handler == null) { return; } // - Assure that handler is valid if (!UsedSpace.Contains(handler)) { return; } MemoryPointer previousFree = null; MemoryPointer nextFree = null; // - Iterate over the free spaces for (int i = FreeSpace.Count - 1; i >= 0; --i) { var freeChunk = FreeSpace[i]; // - Check if there's a free block before the handler if (freeChunk.Offset + freeChunk.Size == handler.Offset) { previousFree = freeChunk; } // - Check if there's a free block after the handler if (handler.Offset + handler.Size == freeChunk.Offset) { nextFree = freeChunk; } } if (previousFree != null && nextFree != null) { uint newSize = previousFree.Size + handler.Size + nextFree.Size; // - Remove last free space FreeSpace.Remove(nextFree); // - Expand the first free space previousFree.ChangeOffsetAndSize(previousFree.Offset, newSize); } else if (previousFree != null) { uint newSize = previousFree.Size + handler.Size; // - Expand the first free space previousFree.ChangeOffsetAndSize(previousFree.Offset, newSize); } else if (nextFree != null) { uint newSize = nextFree.Size + handler.Size; // - Expand the first free space previousFree.ChangeOffsetAndSize(handler.Offset, newSize); } else { // - Adds the removed space to the FreeSpace list FreeSpace.Add(handler); // - Sort free space FreeSpace.OrderBy(x => x.Offset); } // - Remove the deleted handler UsedSpace.Remove(handler); }
/// <summary> /// This method will re-arrange the array in a way that /// all the used memory is contiguous when possible. /// </summary> /// <param name="limitSwaps">Limits the number of chunk swaps for a partial defragmentation.</param> /// <param name="movedCallback">Callback invoked on each swap.</param> public virtual void Defrag(int limitSwaps = int.MaxValue, Action <MemoryPointer> movedCallback = null) { // - No fragmentation if (FreeSpace.Count <= 1) { return; } int lastOffset = 0; MemoryPointer nextChunk = null; // - Foreach chunk we move the block to the left foreach (var chunk in UsedSpace) { // - Limits the number of adjustments if (limitSwaps <= 0) { nextChunk = chunk; break; } if (chunk.Offset > lastOffset) { unsafe { void *source = chunk.Handler.ToPointer(); void *dest = IntPtr.Add(RawMemory, lastOffset).ToPointer(); Buffer.MemoryCopy(source, dest, chunk.Size, chunk.Size); } movedCallback?.Invoke(chunk); // - Update handler offset chunk.ChangeOffsetAndSize((uint)lastOffset, chunk.Size); limitSwaps--; } lastOffset += (int)chunk.Size; } if (nextChunk != null) { // - Remove remaining spaces before next chunk FreeSpace.RemoveAll(x => x.Offset <= nextChunk.Offset); if (lastOffset < nextChunk.Offset) { uint newSize = (uint)(nextChunk.Offset - lastOffset); FreeSpace.Insert(0, new MemoryPointer(this, newSize, (uint)lastOffset)); } } else { FreeSpace.Clear(); var lastElement = UsedSpace.LastOrDefault(); uint newOffset = lastElement.Offset + lastElement.Size; uint newSize = HeapSize - newOffset; FreeSpace.Add(new MemoryPointer(this, newSize, newOffset)); } // - Update fragmentation factor FragmentationFactor = CalculateFragmentationRate(); }
public ReadOnlyMemoryInputBuffer(ReadOnlyMemory <byte> memory) { this.pointer = new MemoryPointer { memory = memory }; }
public InternalModulePointer(ProcessModule processModule) : base(processModule) { MemoryPointer = new InternalMemoryPointer(ProcessModule.BaseAddress); PeHeader = GeneratePeHeader(); }
public override Delegate GetHookDelegate() { MemoryPointer ptr = D3DHelper.GetD3D9Present(); return(ptr.ToDelegate <D3D9PresentDelegate>()); }