Fun with Direct Memory Access

By Brad Campbell

In 1984, Jones and Dewdney released a niche computer programming game called Core War. In this game, rival programs would be placed into a virtual memory segment and sequentially execute their instructions with the purpose of hunting down and terminating the other program placed into memory with them. This spawned a small but dedicated community of players dedicated to making the best and most successful programs possible. Multiple “metas”, or an overarching strategic move, have popped out of this. Namely, rock, paper, and scissors. Paper programs, known as “replicators”, are essentially fork bombs which execute their code in parallel. Hard to kill, but very rarely kill their victims. “Scanners”, known as scissors due to their design for combating replicators, are a class of program hunt the memory space for the other program to selectively find and kill it. These can be combated by “Bombers”, otherwise known as Rock in our rock-paper-scissors analogy. Bombers copy data to intervals over the entire memory space hoping to hit and kill a program. Their operation is simple and is countered by replicators. There are many other types of general-purpose programs that exist, however these 3 are the most common and well-known. When these programs operate, they are alone in their memory space. The playing field changes when programs start executing alongside other code such as the operating system and associated critical systems.

As most people are aware, there are many programs that run running simultaneously on a computer (maybe make a note about how processes actually just run really fast in linear time). Normally, these programs are segmented from each other by the kernel into its “virtual memory” space. In this state, the program thinks it is the only one running. The kernel keeps a mapping of programs and their locations in physical memory. The ability to read physical memory would give a program power to modify any running program and access structures that other programs normally shouldn’t have the ability to. Debuggers are capable of doing this on a targeted basis, however this post will take a dive into programs that would indiscriminately access the physical memory of a computer, much in the same way that the aforementioned Core Wars programs do in their memory space.

Linux provides a simple mechanism to access the physical memory of the running machine. The device file /dev/mem allows direct access into the physical memory space. This device file can be read and written to like a normal file, and the data transferred will be from the requisite space in memory. However, on most modern distros the kernel is compiled with a safeguard against this tactic. Programs generally don’t need to access the running kernel memory, and as such /dev/mem is generally restricted to only the first 1MB of memory. Afterwards an exception will be thrown by the kernel.


This can be taken care of by recompiling the kernel and setting the option “CONFIG_STRICT_DEVMEM=y” to “n”. Doing so allows userspace programs running as root to access and modify kernel memory outside of the initial 1MB.

Once this has been done it is possible to write a program that will interact with /dev/mem and read/write to it like a normal file. Seeking an offset in this file will direct the user to that part of physical memory. At this point there is a nearly infinite amount of possibilities available to the program. At the end of this document is an example program written in C. It is a sample bomber, dropping a “bomb” (in this case a null byte) every 4th byte in memory. Naturally, this causes some interesting issues with the computer, more often than not an outright crash. An attempt was made to make a scanner-style program, however that was more difficult than expected. Reading the memory in and processing it with capstone was successful, however given the complexity of x86, as compared to Redcode in Core Wars, there was almost nothing intelligible that could be gleaned or performed.

Converting this idea into a scored service like Core Wars was more difficult than was possible to be performed in the timeline of this blog post. In Core Wars the programs are allowed to execute one instruction at a time, and when they parallelize only one of those segments is allowed to execute at once. This is complicated by the nature of the processor, and needing the explicitly control the EIP register between programs caused many unforeseen issues since it is not made to jump back and forth between programs (without having a jump instruction inserted after each executed instruction, however orchestrating that zipper of jump statements caused many more problems than I was able to solve). Also, since programs are running in the same address space as the control program, all they would have to do to win is be the first to find that program in memory. If the issue of execution equality and control-program hijacking could be overcome, this would be an interesting way to play a more advanced version of Core Wars, and finding new programmatic strategies to win this game would be quite an adventure.







#include <stdio.h>

#define KB 1024

#define MB (KB*1024)

#define GB (MB*1024)

#define BOMB '\x00'

int main() {

       // File pointer to memory

       FILE *memory = fopen("/dev/mem", "rw");

       //Skip the VMWare code loaded in front of the kernel

       long start_loc = 1*MB;

       fseek(memory, start_loc, SEEK_SET);

       // "Bomb" every 4th byte from the start of the kernel to

       // the end of the first GB of RAM

       for(int index = 0; index < 1*GB; index += 1) {

              fprintf(memory, "%c", BOMB);


       return 0;




Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s