Unsafe Rust — Modify memory of another process 😖
A couple of weeks ago, i posted an article about using Cheat Engine to modify the memory of the game Metal Slug 3. However, Cheat Engine…

A few weeks ago, I shared an article about using Cheat Engine to inspect and modify the memory of the game Metal Slug 3. However, Cheat Engine is primarily designed for inspection and may not be very convenient if you want to automate the process of modifying the game’s memory. Today, we will tackle this challenge by writing a simple program in Rust to freeze a memory address.🦀 😘
No need to worry if you missed the previous post; this one will focus on the FFI part, which is unrelated to Cheat Engine.
How?
We’ll utilize the Win32 API’s WriteProcessMemory to write the desired value to that process.
As the API is in another language, we’ll need to perform FFI (Foreign Function Interface) in Rust. Luckily, Microsoft has generously exposed the entire Win32 API in Rust through the “windows-sys” crate, saving us the trouble of doing it ourselves.
Let’s go
Let create the project using these commands:
cargo new metal_slug_3_trainer
cd metal_slug_3_trainer
code .
These commands should create the project and open that project in your VsCode.
Dependencies
We’ll require two crates as dependencies in our codebase. The first one, as mentioned earlier, is “windows-sys.” The second one is “sysinfo,” which we use to retrieve the process ID from the process name.
Open the cargo.toml
and add these lines to your [dependencies]
section:
sysinfo = "0.26.4"
windows-sys = { version = "0.42.0", features = [
"Win32_System_Diagnostics_Debug",
"Win32_Foundation",
"Win32_System_Threading",
] }
These features are mandatory, as indicated in the sysinfo documentation here and here.
The Handle
Let’s take a quick look at the signature of WriteProcessMemory.

The first parameter is the Handle. What exactly is a Handle, and how do we obtain it? In a general sense, a handle is a reference or pointer to a particular entity. In this case, it’s a pointer to the memory of our process.

We will use the function OpenProcess to retrieve the handle.

Now, back to the code. we will call the function like this:

The document of WriteProcessMemory states The handle must have PROCESS_VM_WRITE and PROCESS_VM_OPERATION access to the process.
You can set the parameter as PROCESS_ALL_ACCESS like my code or can set it like this PROCESS_VM_WRITE | PROCESS_VM_OPERATION
The second parameter is set to 0
because we have no intention to create any child process.
The process_id
parameter can be retrieved by using the crate sysinfo
which i mentioned above like this.


“neoragex” here is the process name, i also used the nth(0)
because the given name could returns many processes. Since neoragex has only one process, the first one found should be the one we needed.
The remaining parameters…
lpBaseAddress
is the pointer to the address of the process we want to write, we can create it like this

lpBuffer
is the pointer to the buffer we want to write, we do the same thing but a bit different here

nSize
because our buffer is 4 bytes (0xFF 0x07 0x00 0x00), the value for this parameter is 4.
lpNumberOfBytesWritten
this is an out value indicates how many bytes were written, we don't need it in this case so i will set it to NULL.
Finally
With all the parameters available, we can call the function like this:

But this only writes the memory once, if we want to freeze the memory, a loop is required

Conclusion
Doing FFI (Foreign Function Interface) for the first time might seem a bit peculiar, wouldn’t you agree? However, it can be quite enjoyable, too.
You can access the source code for this post on GitHub. Feel free to explore and even add some fun features like switching to a random gun every 3 seconds — it’s all about enhancing the experience! Enjoy coding! 😄