/// <summary> /// Writes RETN instruction to the address provided in the process specified. /// </summary> /// <param name="process">Process where write memory.</param> /// <param name="address">Address of the process at which memory writing should occur.</param> /// <param name="size">Size of the return. 0 by default.</param> /// <returns><see cref="InjectResult"/> of the memory writing.</returns> public static InjectResult MakeRETN(Process process, uint address, ushort size = 0) { var hProcess = NativeCall.OpenProcess(ProcessAccessFlags.All, false, process.Id); if (size != 0) { var array = new byte[3] { (byte)InjectInstr.RET, (byte)(size & 0xFF), (byte)(size >> 8) }; NativeCall.VirtualProtect(hProcess, (IntPtr)address, (UIntPtr)array.Length, 4, out var old); NativeCall.WriteProcessMemory(hProcess, (IntPtr)address, array, (uint)array.Length, out var num); NativeCall.VirtualProtect(hProcess, (IntPtr)address, (UIntPtr)array.Length, old, out old); NativeCall.CloseHandle(hProcess); return(array.Length == num ? InjectResult.Success : InjectResult.WritingFailed); } else { var array = new byte[1] { (byte)InjectInstr.RETN }; NativeCall.VirtualProtect(hProcess, (IntPtr)address, (UIntPtr)array.Length, 4, out var old); NativeCall.WriteProcessMemory(hProcess, (IntPtr)address, array, (uint)array.Length, out var num); NativeCall.VirtualProtect(hProcess, (IntPtr)address, (UIntPtr)array.Length, old, out old); NativeCall.CloseHandle(hProcess); return(array.Length == num ? InjectResult.Success : InjectResult.WritingFailed); } }
/// <summary> /// Terminates <see cref="Thread"/> with ID specified. /// </summary> /// <param name="id">ID of the <see cref="Thread"/> to terminate.</param> /// <returns><see langword="true"/> if thread was successfully terminated; /// <see langword="false"/> otherwise.</returns> public static bool TerminateThread(int id) { var handle = NativeCall.OpenThread(0x40000000, false, (uint)id); var result = NativeCall.CancelSynchronousIo(handle); NativeCall.CloseHandle(handle); return(result); }
/// <summary> /// Terminates <see cref="Thread"/> specified. /// </summary> /// <param name="thread"><see cref="Thread"/> to terminate.</param> /// <returns><see langword="true"/> if thread was successfully terminated; /// <see langword="false"/> otherwise.</returns> public static bool TerminateThread(Thread thread) { int code = 0; var id = thread.ManagedThreadId; var handle = NativeCall.OpenThread(0x40000000, false, (uint)id); var result = NativeCall.TerminateThread(handle, code); NativeCall.CloseHandle(handle); return(result != 0); }
/// <summary> /// Reads memory of the <see cref="Process"/> provided at the address specified. /// </summary> /// <param name="process">Process where read memory.</param> /// <param name="address">Address of the process at which memory reading should occur.</param> /// <param name="size">Amount of bytes to read.</param> /// <returns>Memory read as an array of bytes.</returns> public static byte[] ReadMemory(Process process, uint address, int size) { var array = new byte[size]; int bytes_read = 0; var hProcess = NativeCall.OpenProcess(ProcessAccessFlags.All, false, process.Id); NativeCall.VirtualProtect(hProcess, (IntPtr)address, (UIntPtr)size, 4, out var old); NativeCall.ReadProcessMemory(hProcess, (IntPtr)address, array, (uint)size, bytes_read); NativeCall.VirtualProtect(hProcess, (IntPtr)address, (UIntPtr)size, old, out old); NativeCall.CloseHandle(hProcess); return(array); }
/// <summary> /// Writes byte array passed to the process specified at the address provided. /// </summary> /// <param name="process">Process where write memory.</param> /// <param name="address">Address of the process at which memory writing should occur.</param> /// <param name="array">Byte array to write to memory.</param> /// <returns><see cref="InjectResult"/> of the memory writing.</returns> public static InjectResult WriteMemory(Process process, uint address, byte[] array) { var hProcess = NativeCall.OpenProcess(ProcessAccessFlags.All, false, process.Id); if (array == null) { return(InjectResult.ByteCastFailure); } NativeCall.VirtualProtect(hProcess, (IntPtr)address, (UIntPtr)array.Length, 4, out var old); NativeCall.WriteProcessMemory(hProcess, (IntPtr)address, array, (uint)array.Length, out var num); NativeCall.VirtualProtect(hProcess, (IntPtr)address, (UIntPtr)array.Length, old, out old); NativeCall.CloseHandle(hProcess); return(array.Length == num ? InjectResult.Success : InjectResult.WritingFailed); }
/// <summary> /// Writes CALL instruction to the address provided in the process specified. /// </summary> /// <param name="process">Process where write memory.</param> /// <param name="address">Address of the process at which memory writing should occur.</param> /// <param name="function">Function that should be called.</param> /// <returns><see cref="InjectResult"/> of the memory writing.</returns> public static InjectResult MakeCALL(Process process, uint address, uint function) { var hProcess = NativeCall.OpenProcess(ProcessAccessFlags.All, false, process.Id); var array = new byte[5] { (byte)InjectInstr.CALL, 0, 0, 0, 0 }; var diff = BitConverter.GetBytes(function - address - 5); for (int a1 = 0; a1 < 4; ++a1) { array[1 + a1] = diff[a1]; } NativeCall.VirtualProtect(hProcess, (IntPtr)address, (UIntPtr)array.Length, 4, out var old); NativeCall.WriteProcessMemory(hProcess, (IntPtr)address, array, (uint)array.Length, out var num); NativeCall.VirtualProtect(hProcess, (IntPtr)address, (UIntPtr)array.Length, old, out old); NativeCall.CloseHandle(hProcess); return(array.Length == num ? InjectResult.Success : InjectResult.WritingFailed); }
/// <summary> /// Writes NOP instructions to the address provided in the process specified. /// </summary> /// <param name="process">Process where write memory.</param> /// <param name="address">Address of the process at which memory writing should occur.</param> /// <param name="size">Size of the NOP.</param> /// <returns><see cref="InjectResult"/> of the memory writing.</returns> public static InjectResult MakeNOP(Process process, uint address, int size) { if (size <= 0) { return(InjectResult.InvalidSize); } var hProcess = NativeCall.OpenProcess(ProcessAccessFlags.All, false, process.Id); var array = new byte[size]; for (int a1 = 0; a1 < size; ++a1) { array[a1] = (byte)InjectInstr.NOP; } NativeCall.VirtualProtect(hProcess, (IntPtr)address, (UIntPtr)array.Length, 4, out var old); NativeCall.WriteProcessMemory(hProcess, (IntPtr)address, array, (uint)array.Length, out var num); NativeCall.VirtualProtect(hProcess, (IntPtr)address, (UIntPtr)array.Length, old, out old); NativeCall.CloseHandle(hProcess); return(array.Length == num ? InjectResult.Success : InjectResult.WritingFailed); }
/// <summary> /// Makes function at the specified address of the process provided return a /// specific value passed. /// </summary> /// <param name="process">Process where write memory.</param> /// <param name="address">Address of the process at which memory writing should occur.</param> /// <param name="value">Value that function should return. This value should /// be convertible to 4-byte unsigned integer type.</param> /// <returns><see cref="InjectResult"/> of the memory writing.</returns> public static InjectResult ReturnValue(Process process, uint address, object value) { var hProcess = NativeCall.OpenProcess(ProcessAccessFlags.All, false, process.Id); var array = new byte[6] { (byte)InjectInstr.MOV, 0, 0, 0, 0, (byte)InjectInstr.RETN }; var val = value.ReinterpretCast(typeof(uint)); if (val == null) { return(InjectResult.ByteCastFailure); } var diff = BitConverter.GetBytes((uint)val); for (int a1 = 0; a1 < 4; ++a1) { array[1 + a1] = diff[a1]; } NativeCall.VirtualProtect(hProcess, (IntPtr)address, (UIntPtr)array.Length, 4, out var old); NativeCall.WriteProcessMemory(hProcess, (IntPtr)address, array, (uint)array.Length, out var num); NativeCall.VirtualProtect(hProcess, (IntPtr)address, (UIntPtr)array.Length, old, out old); NativeCall.CloseHandle(hProcess); return(array.Length == num ? InjectResult.Success : InjectResult.WritingFailed); }
/// <summary> /// Closes hProcess handle with pointer provided. /// </summary> /// <param name="hProcess">Pointer to base address of a <see cref="Process"/>.</param> /// <returns>Result of closing.</returns> public static int CloseHandle(IntPtr hProcess) => NativeCall.CloseHandle(hProcess);