예제 #1
0
        /// <summary>
        /// Remove protection from address and write value.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="address">Address to unprotect and write.</param>
        /// <param name="value">Value to write.</param>
        public static void UnprotectWrite <T>(IntPtr address, T value) where T : unmanaged
        {
            int size = Unsafe.SizeOf <T>();

            if (OSHelper.IsWindows)
            {
                Kernel32.MemoryProtection oldFlags = Kernel32.VirtualProtect(address, size, Kernel32.MemoryProtection.READ_WRITE);
                Write(address, value);
                Kernel32.VirtualProtect(address, size, oldFlags);
            }
            else if (OSHelper.IsLinux)
            {
                byte[] byteValue;

                unsafe
                {
                    void *ptr = Unsafe.AsPointer(ref value);
                    byteValue = new Span <byte>(ptr, size).ToArray();
                }

                lock (LockSelfMemLinux)
                {
                    //Prevent segmentation fault.
                    using FileStream fs = File.Open($"/proc/self/mem", FileMode.Open, FileAccess.ReadWrite);
                    fs.Seek(address.ToInt64(), SeekOrigin.Begin);
                    fs.Write(byteValue, 0, byteValue.Length);
                }
            }
            else
            {
                Mman.mprotect(address, (ulong)size, MmapProts.PROT_WRITE);
                Write(address, value);
            }
        }
예제 #2
0
 /// <summary>
 /// Free memory trampoline.
 /// </summary>
 /// <param name="address"></param>
 public static void FreeTrampoline(IntPtr address)
 {
     if (OSHelper.IsPosix)
     {
         Mman.munmap(address, TrampolineInstruction.Length);
     }
     else
     {
         Kernel32.VirtualFree(address, TrampolineInstruction.Length);
     }
 }
예제 #3
0
 /// <summary>
 /// Free memory trampoline.
 /// </summary>
 /// <param name="address"></param>
 public static void FreeTrampoline(IntPtr address)
 {
     if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
     {
         Kernel32.VirtualFree(address, TrampolineInstruction.Length);
     }
     else
     {
         Mman.munmap(address, TrampolineInstruction.Length);
     }
 }
예제 #4
0
        public static IntPtr AllocateTrampoline(IntPtr address)
        {
            byte[] trampoline = GetTrampoline(address);
            IntPtr jmpNative;

            if (OSHelper.IsPosix)
            {
                jmpNative = Mman.mmap(trampoline.Length, MmapProts.PROT_EXEC | MmapProts.PROT_WRITE, MmapFlags.MAP_ANON | MmapFlags.MAP_SHARED);
            }
            else
            {
                jmpNative = Kernel32.VirtualAlloc(trampoline.Length, Kernel32.AllocationType.Commit, Kernel32.MemoryProtection.EXECUTE_READ_WRITE);
            }

            Marshal.Copy(trampoline, 0, jmpNative, trampoline.Length);
            return(jmpNative);
        }
예제 #5
0
        /// <summary>
        /// Create a trampoline 64 bits.
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public static IntPtr AllocateTrampoline(IntPtr address)
        {
            IntPtr jmpNative;

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                jmpNative = Kernel32.VirtualAlloc(TrampolineInstruction.Length, Kernel32.AllocationType.Commit, Kernel32.MemoryProtection.EXECUTE_READ_WRITE);
            }
            else
            {
                jmpNative = Mman.mmap(TrampolineInstruction.Length, MmapProts.PROT_EXEC | MmapProts.PROT_WRITE, MmapFlags.MAP_ANON | MmapFlags.MAP_SHARED);
            }

            Marshal.Copy(TrampolineInstruction, 0, jmpNative, TrampolineInstruction.Length);
            Marshal.WriteIntPtr(jmpNative, 2, address);
            return(jmpNative);
        }
예제 #6
0
        /// <summary>
        /// Write pointer on address.
        /// </summary>
        /// <param name="address">Address to write pointer.</param>
        /// <param name="pointer">Pointer to write.</param>
        private static void WritePointer(IntPtr address, IntPtr pointer)
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Kernel32.MemoryProtection oldFlags = Kernel32.VirtualProtect(address, IntPtr.Size, Kernel32.MemoryProtection.READ_WRITE);
                Marshal.WriteIntPtr(address, pointer);
                Kernel32.VirtualProtect(address, IntPtr.Size, oldFlags);
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                byte[] newAddress = BitConverter.GetBytes(pointer.ToInt64());

                //Prevent segmentation fault.
                using FileStream fs = File.Open($"/proc/{ProcessInfo.PID}/mem", FileMode.Open, FileAccess.ReadWrite);
                fs.Seek(address.ToInt64(), SeekOrigin.Begin);
                fs.Write(newAddress, 0, newAddress.Length);
            }
            else
            {
                Mman.mprotect(address, (ulong)IntPtr.Size, MmapProts.PROT_WRITE);
                Marshal.WriteIntPtr(address, pointer);
            }
        }