(WIP) Programs And Reading Memory
13 FEB 2026I've previously done some very casual malware analysis and reverse engineering for fun with the express goal of understandin how software works at a lower level and how memory is structured (this was pretty helpful in my previous role).
This blog post is mainly just a bit of a brain dump and a re-learning of the things I've not touched mentally in a while.
Opening a program
When you open a program, it's contents get loaded into the RAM in your computer. RAM is great for quick access, however, it's memory is volatile, meaning that once you turn your computer off any information held there disappears.
You may be wondering, “Why not use the hard drive? The program is already stored there.” Well, unlike RAM access speeds, hard drives are much slower.
Hard drive
terraria.exe
opening terraria.exe...
RAM
terraria code
terraria data
In reality, the above is very much a simplified version of what actually happens. Each process actually gets given its own virtual address space (VAS), which contains various file sections, DLLs, heap and stack.
Within the VAS everything has it's own virtual address which is then mapped to a page which corresponds to a frame in physical memory. Typically each page is 4KB in size, and the frame in physical memory is also 4KB in size. The virtual address space of a process is typically much larger than the amount of physical memory available, which is why virtual memory is used to manage this (among many other reasons).
opening terraria.exe...
VAS
kernel space
stack
↓heap
↑DLLs
.exe image
Page table
pages
frames
0x300
0x100
0x200
0x600
0x900
0x700
0x500
0x300
It's good to know about the virtual memory addresses since this is what you are working with when reverse engineering or manipulating memory. Many people seem to think it is memory direct from the RAM that you're playing with but that's not the case.
Editing memory
Back in ~2007 I remember seeing Runescape videos of people with millions of gold and wondered how they managed to get so rich. Well, it turns out a lot of those videos were people using Cheat Engine to edit the visual value of their gold in memory rather than actually having that much gold.
Cheat Engine is a tool that allows you to attach a running process to it and read it's virtual memory. If you have some sort of software or a game running you can search for a specific value held in memory.
For instance, in Terraria, you have an items bar (similar to Minecraft) and you can hold multiple dirt at a time (say I have 20 dirt), I can then search for the value 20. Now, the issue is that the value "20" is probably going to return mainly different addresses in memory. So you want to change the value of dirt you have (say you place a dirt block so you have 19) and re-search for that value. You can repeat this process until you find the memory address likely to hold the value you're looking for and you can then change it to whatever you want.
Cheat Engine
[attached to Terraria.exe]> Search for value: 20
- 0x89A297DC
- 0x89A297A2
- 0x89A2962C
> Search for value: 19
- 0x89A297A2
Now, I've got that memory address I can just keep changing it to whatever value I want and have as many little dirt blocks that I want (I'm unstoppable now). However, something to bear in mind is that when I close the game or turn my computer off this memory address is probably going to be pointing to something completely different depending on how the variable for this was declared.
Static vs Dynamic
Anything declared in the file scope, global scope, or marked as static when coded using C++ will be statically allocated so its memory address wont change even if the program restarts.
In games, certain data needs to be created as and when (e.g. npc spawns in). This is done with dynamic memory allocation, which is when a program requests memory from the operating system to store data in. This is done using functions like malloc in C or new in C++. Everything allocated via these methods gets stored in the heap. The heap is managed by the operating system and can grow and shrink as needed.
As you probably guessed, if static data has the same address then dynamic data will have a different address each time it is allocated. This can make memory editing a bit more difficult since we ideally don't want to have to scan every single time to find the new memory address.