public static extern bool WriteProcessMemory( SafeMemoryHandle hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int nSize, out int lpNumberOfBytesWritten);
public static extern bool ReadProcessMemory( SafeMemoryHandle hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int dwSize, out int lpNumberOfBytesRead);
/// <summary> /// </summary> /// <param name="handle"> /// </param> /// <param name="search"> /// </param> /// <param name="mbi"> /// </param> /// <returns> /// </returns> private static IntPtr FindKey(SafeMemoryHandle handle, string search, MemoryBasicInformation mbi) { byte[] memCopy = ReadBytes(handle, mbi.BaseAddress, mbi.RegionSize); int len = ASCIIEncoding.ASCII.GetByteCount(search); byte[] src = ASCIIEncoding.ASCII.GetBytes(search); int iPointer = 0; while (iPointer < memCopy.Length - len) { int dPointer = 0; while (dPointer < len) { if (src[dPointer] != memCopy[iPointer + dPointer]) { break; } dPointer++; if (dPointer == len) { return (IntPtr)((int)mbi.BaseAddress + iPointer); } } iPointer++; } return (IntPtr)0; }
public static extern bool VirtualProtectEx( SafeMemoryHandle hProcess, IntPtr lpAddress, int dwSize, MemoryProtectionFlags flNewProtect, out MemoryProtectionFlags lpflOldProtect);
/// <summary> /// </summary> /// <param name="handle"> /// </param> /// <param name="memHandle"> /// </param> /// <param name="search"> /// </param> /// <returns> /// </returns> internal static IntPtr Find(IntPtr handle, SafeMemoryHandle memHandle, string search) { SYSTEM_INFO pSI = new SYSTEM_INFO(); GetSystemInfo(ref pSI); List<MemoryBasicInformation> memPages = new List<MemoryBasicInformation>(); memPages.AddRange( Query(handle, (IntPtr)pSI.lpMinimumApplicationAddress, (IntPtr)pSI.lpMaximumApplicationAddress)); int len = ASCIIEncoding.ASCII.GetByteCount(search); foreach (MemoryBasicInformation mbi in memPages) { if (mbi.RegionSize >= len) { if (((mbi.State & MemoryStateFlags.Commit) == MemoryStateFlags.Commit) && ((mbi.Type & MemoryTypeFlags.Image) == MemoryTypeFlags.Image)) { IntPtr res = FindKey(memHandle, search, mbi); if ((uint)res > 0) { return res; } } } } return (IntPtr)0; }
/// <summary> /// </summary> /// <param name="processHandle"> /// </param> /// <param name="address"> /// </param> /// <param name="byteArray"> /// </param> /// <returns> /// </returns> /// <exception cref="Win32Exception"> /// </exception> public static int WriteBytes(SafeMemoryHandle processHandle, IntPtr address, byte[] byteArray) { // Create the variable storing the number of bytes written int nbBytesWritten; // Write the data to the target process if (WriteProcessMemory(processHandle, address, byteArray, byteArray.Length, out nbBytesWritten)) { // Check whether the length of the data written is equal to the inital array if (nbBytesWritten == byteArray.Length) { return nbBytesWritten; } } // Else the data couldn't be written, throws an exception throw new Win32Exception( string.Format("Couldn't write {0} bytes to 0x{1}", byteArray.Length, address.ToString("X"))); }
/// <summary> /// Reads an array of bytes in the memory form the target process. /// </summary> /// <param name="processHandle"> /// A handle to the process with memory that is being read. /// </param> /// <param name="address"> /// A pointer to the base address in the specified process from which to read. /// </param> /// <param name="size"> /// The number of bytes to be read from the specified process. /// </param> /// <returns> /// The collection of read bytes. /// </returns> public static byte[] ReadBytes(SafeMemoryHandle processHandle, IntPtr address, int size) { // Allocate the buffer var buffer = new byte[size]; int nbBytesRead; // Read the data from the target process if (ReadProcessMemory(processHandle, address, buffer, size, out nbBytesRead) && size == nbBytesRead) { return buffer; } // Else the data couldn't be read, throws an exception throw new Win32Exception( string.Format("Couldn't read {0} byte(s) from 0x{1}.", size, address.ToString("X"))); }
/// <summary> /// </summary> /// <param name="processHandle"> /// </param> /// <param name="address"> /// </param> /// <param name="size"> /// </param> /// <param name="protection"> /// </param> /// <returns> /// </returns> /// <exception cref="Win32Exception"> /// </exception> public static MemoryProtectionFlags ChangeProtection( SafeMemoryHandle processHandle, IntPtr address, int size, MemoryProtectionFlags protection) { // Create the variable storing the old protection of the memory page MemoryProtectionFlags oldProtection; // Change the protection in the target process if (VirtualProtectEx(processHandle, address, size, protection, out oldProtection)) { // Return the old protection return oldProtection; } // Else the protection couldn't be changed, throws an exception throw new Win32Exception( string.Format( "Couldn't change the protection of the memory at 0x{0} of {1} byte(s) to {2}.", address.ToString("X"), size, protection)); }