How can I process memory through scanning and replace only byte arrays?

This question may seem extremely noob, I apologize. I periodically tried over the past three months to figure out how to read / write another process memory or an application that uses process memory, simply through byte arrays. As far as I know, C # does not have the ability to read / write the memory process, so it should call the win32 API dll through P / Invoke.

[DllImport("kernel32.dll")] static extern Int32 ReadProcessMemory(IntPtr OpenedHandle, IntPtr lpBaseAddress, byte[] lpBuffer, UInt32 size, out IntPtr lpNumberOfBytesRead); 

My goal is to search and replace multiple byte arrays as simply and efficiently as in the Cheat Engine. Usually I had two vars either separately or inside an array:

 private string original = "d0 d0 66 ae 0b 68 b9 0a"; private string replace = "d0 02 02 24 00 68 b9 0a"; 

In the call to ReadProcessMemory I do not understand why lpBaseAddress is required. OpenHandle I would usually put the application line since I edit it directly. lpBuffer I assume this is an actual array of bytes to read / write. size I'm not sure about this, and is lpNumberOfBytesRead read number? Mutual polling for WriteProcessMemory .

 [DllImport("kernel32.dll")] private static unsafe extern Boolean WriteProcessMemory(IntPtr hProcess, uint lpBaseAddress, byte[] lpBuffer, int nSize, void* lpNumberOfBytesWritten); 

I would like to give some of the lessons that I have read, but it seems that they no longer exist or have been replaced. Again, I sincerely apologize for asking such a seemingly amateurish question, however S.O. was my last resort.

+4
source share
1 answer

As far as I know, C # does not have the ability to read / write memory the process, so it should call the win32 dll API through P / Invoke.

That's right, and you found a suitable Win32 API for this.

I would usually have two vars either separately or inside an array:

 private string original = "d0 d0 66 ae 0b 68 b9 0a"; private string replace = "d0 02 02 24 00 68 b9 0a"; 

For ReadProcessMemory and WriteProcessMemory you will not use strings, you will use the actual byte arrays ( byte[] ), as shown in the signatures of the P / Invoke function that you specified. Your user interface or command line tool can accept strings, but you need to convert them to byte arrays.

If you have not already done so, you should read the MSDN documentation for ReadProcessMemory and WriteProcessMemory . They give a good description of what is expected and what is returned for each parameter.

In the call to ReadProcessMemory, I have no understanding why lpBaseAddress is needed. OpenHandle I would usually put the application string since I am directly editing it.

First, the OpenHandle parameter expects a process handle, not a file name, which, as I think, you mean. You can get a handle to the running process using the Win32 OpenProcess API (P / Invoke signature can be found here ). To read and write memory in this process, you will need at least PROCESS_VM_READ and PROCESS_VM_WRITE access.

lpBuffer I assume the actual byte array is read / write. A size I'm not very sure about, and lpNumberOfBytesRead is the number to read? Mutual interrogation for WriteProcessMemory.

For ReadProcessMemory , lpBaseAddress indicates where in the memory of the target process you want to read. lpBuffer populated with the contents of the memory of the target process. size indicates how many bytes to read. lpNumberOfBytesRead is an output argument indicating how many bytes were actually read as part of the operation. If successful, this should match the size buffer you specified.

Given this, you should figure out what all the WriteProcessMemory options WriteProcessMemory .


More on how to achieve what you are trying to do: you are trying to perform a search and replace operation. The search section will be the most difficult. I can think of two main approaches:

  • You can perform a full scan in the process memory (literally from the zero address to the 2/3 GB limit (for 32-bit processes)) that is looking for your bytes. This is the slowest but easiest way.

  • Using heap information, you can restrict the scan to known allocated addresses. This is a faster, but much more complex approach. Since you are running Windows, the process you are targeting is likely to use a bunch of Windows to manage memory. Windows provides an API, HeapWalk , to walk around the heaps (and objects) that are allocated in the process. Unfortunately, this requires a handle for the heap, and GetProcessHeap / GetProcessHeaps return the handle of the calling process to the heap (they do not work for remote processes). So, if you need heap information for a remote process, you will need to insert a thread into the remote process to collect this information for you (for example, using CreateRemoteThread ). When you have valid heap addresses, you can simply scan them from your search and replace application.

+4
source

All Articles