Introduction

Have you ever had a problem completing a game because your health meter shows just 5% of your health available?Have you ever used a game trainer to solve this problem?Have you ever wondered how this trainer freezes your health meter to 100%?These game trainers, do a simple job!They write a little part of the Game's memory with the 100 value!But how to find the exact part of memory?

The Question and the Answer

Q: How to find the location in which a program stores a value in its memory?A: Some programs named 'Memory Scanners', are written to read and search a program's memory for exact location and help freezing it! (And I have written this article to show you, how to write a 'Memory Scanner')

Step 1: Where to begin?

Let's have a look at a program's memory.Think that I have written a program and we can have a look at its memory.To have a picture in mind, we can say, it looks something like this:

As you can see, the memory is made up of a huge number of small sectors, that hold a value in it. Our picture, just shows a small part of the memory, from sector 0 to sector 99 and a detail of sector 0 to sector 15. But as you know, a computer just knows the meaning of 0 and 1, so what do these Hexadecimal values mean?

Let's take a deep look at the memory again.

As you can see, every byte is made up of 8 bits with each of them being just that 1 or 0, and in Binary mode, they can return the value stored in the byte((00010111)2 = (23)10 = (17)16).

As we saw, a computer's memory stores information by holding the 0 and 1s in the memory bits, and 8 bits of memory make a section of memory named byte, so a byte can hold values up to (11111111)2 = (255)10 = (FF)16, but how about the bigger values?We usually work with values greater than 255!Ok, the answer is that, we have bigger units of memory to hold the bigger values.

Let's look at another picture of memory that shows the bigger units and then, I will explain everything:

So we have 3 bigger memory units: 2 Bytes that make a 16 bit memory unit that we call 'short' in C#, 4 Bytes that make a 32 bit memory unit that we call it 'int' in C#, and 8 Bytes that make a 64 bit memory unit, and we call it 'long' in C#.

Step 2: What to look for?

Now that we have a simple picture of the memory in our mind, let's go back to the first picture:

I know that, you are going to say: "Hey, it's just a row of bytes! How to find the memory units?" And then I'll tell you that, you asked the biggest question in writing a memory scanner!

Ok, let's think that it's a part of the memory of my program, and I know, where in the memory, I have stored the values and I will show you that:

As you see, a memory unit, can be stored in any part of the memory and start from any memory sector. In this program for example, I have stored a 32 bit value in the 0 sector, and because a 32 bit value takes 4 bytes of memory, from the sector 0 to sector 3 is assigned for a 32 bit variable in the program, and after that, from the sector 4, there is a 16 bit variable that takes 2 bytes of memory, next is a 64 bit variable and at the end, there is again a 16 bit variable.

Now let's think that the values of the sectors are the same, but the memory units start from different sectors:

Why everything changed?Because, a variable could be stored in any memory sector number, and most of the time, even the programmer doesn't know, where the variable is stored in the memory, and just the program knows it!

Step 3: Where to find it?

Now, let's think that we are playing a game, and the health meter shows 83%, and we don't know the location of the variable in the memory and we want to find the variable and we start from sector 0, so the memory looks like this:

So what? Is there any 83 in the memory?First, we know that we have the hexadecimal values of the memory bytes. Second, we should guess the variable type to look for.

Ok, let's say that the programmers of the game have used a 32 bit (int) variable, that is the most usual data type being used for storing the value of the health meter. So the value is stored in a 4 bytes long part of the memory. But, how to find it? The only way to search the memory completely, is to start from the beginning, take 4 bytes, test them to see if the value equals our digit (here 83), and find the location. Like this:

Ok, now you know the main concept of memory scanning, but there are some other things that you should know to be able to write the Memory scanner:

Q: How long is a program's memory? (Where to begin and where to stop?)A: As you know, Microsoft's first OS was DOS that was a 8 bit OS, after that, the Windows 3.1 became a 16 bit OS, and after that, the Windows OS became a 32 bit OS. (I'm a real fan of Apple Co. that developed the Apple Macintosh OS, a 64 bit OS, exactly when Microsoft was working on DOS (a 8 bit OS) and today, Microsoft is going to write a 64 bit Windows (and like the first Windows versions, it still looks like the Apple OSs) but, I still recommend Apple MacOS X (Ver. 10)). So, in the DOS OS that was a 8 bit OS, programmers named 8 bits of memory, a "Byte". After that, When the Windows 3.1 OS was a 16 bit OS, they named 16 bits of memory(2 Bytes) a "WORD", and 32 bits of memory(4 Bytes) a "DWORD"(Double Word) and 64 bits of memory(8 Bytes) a "QWORD"(Quad Word).As I experienced, the length of every program's memory in Windows XP, is from "0x00000000" to the maximum value of a "Int"("DWORD"), and equals to "0x7FFFFFFF".I'm not sure, but I guess, it's because of that, the Windows is a 32 bit OS and the main memory unit for it, is a 32 bit memory unit, and so, the length of a program's memory, is the maximum value of a 32 bit memory unit!Ok. So, we should start our search from "0x0000000" to "0x7FFFFFFF".

Q: Is the first found memory address, the exact answer of our search?A: No! As you can see, there are "0x7FFFFFFF" sectors, and when you search it for a value like 83, you could find so many of them. So you need to hold the memory addresses and wait for the values to be changed. Then search the addresses you have, for the new value, and do this, until you find, just one memory address that matches your value.

Q: How to read a program's memory and search it?A: There are some functions in Windows API that make it possible for us to read and write the memory, from another program.Thanks goes to "Arik Poznanski" for P/Invokes and methods needed to read and write the Memory, I just used his classes to do this and didn't do the P/Invokes myself.You can search Codeproject.com, for "Minesweeper, Behind the scenes", to find his comments about these classes.

Q: How to convert these bytes to a 16, 32 or 64 bit value?A: For this, we used .NET goods! There is a class with static methods that does this for us:

Step 4: Let's do the final job

Ok, now you have all the information you need to write the memory scanner.You just need to do these in your code:

Select a process to scan its memory.

Scan the whole memory for the specified value and hold the addresses.

Wait for the value to be changed and search the memory address list that you got from the first scan and again wait for the value to be changed and scan again, and do this until you find just the address that matches the value.

At the end, you can freeze the address with a new value, by using a timer to write the memory in every timer's tick.

Comments on my classes

If you download my code, you will find them with comments for every command and every line of code. But there it a little thing I should explain:

ReadProcessMemory(IntPtr MemoryAddress, uint bytesToRead, out int bytesRead) that is the most important function, returns an empty bytes array if reading your request's size is too big! So I had to read the memory in parts as big as 20480 bytes (20KB), and because, when you are searching these memory parts, byte by byte, at the end of the bytes array, there will be some bytes left! (for example, 3 bytes will be left when you are searching for 32 bit values)!

So the solution I used was this:

if (/*scan requirement is less than 20480 bytes*/)
{
//Read the memory at once
}
else
{
/*Loop through blocks(of length 20480 bytes),
until the whole memory is read;
After the first loop, move the current address to
[Data type bytes count - 1] steps back in the memory,
to fix the previously told problem;
After the loops, check to see if any other memory addresses
are left outside of the loops and if so, read them;*/
}

You can see it:

That's all

Ok folks, that's all! Hope you like and enjoy it!And now I'm working on a Enhanced Memory Scanner that could scan all types of data, including the Bytes, Signed Data Types and even Strings, it just takes some time!I'll be back soon.

Hi,
I'm the head of programmers in a big company now and so busy and have no time to complete this for now but for strings, if you know the Encoding used to generated the string, just use the Encoding to get the string bytes (likely the default .net string encoding) and if you don't, you have to try different Encoders and try to find the string. This is the beginning point for you to start from.

Thanks for your interest.
Also thanks for your information, but I think I have read somewhere that DOS has been 8-bit OS sometime in it's life time.
I have no enough time but you may help by reading this and correcting me if I'm really wrong!Timeline of x86 DOS operating systems[^]
Thanks again.

The first DOS's (there were many different from different vendors, I've also written one [very less features^^]) were 8Bit, but MS-DOS was a 16Bit operating system.
It was designed for 80x86 processers, which started as 16Bit ones. Also DOS uses BIOS interrupts, and the BIOS contains 16Bit code on IBM PC's.
80x86 processors doesn't contain a 8Bit mode, there's only 16Bit (Real-)mode, 32Bit (Protected-)mode and 64Bit (Long-)mode.
More informations can be found at osdev.org or lowlevel.eu (german)

I didnt know if you had ever worked out the string variables for the memory scanner. I tried the scanner, but I am confused as to what it is accomplishing. is it finding every instance of a certain int in the memory location that is being scanned. and if it is, what its the second scan for, is it for finding the same value after the values of other variables have most likely changed?

Your question is not clear to me.What do you mean by the second scan? Do you mean the second scan in the sample memory scanner app provided? If so, how is it related to Strings scanning?
Please repeat your question in a clear way.
Thanks.

Mainly I was wondering how to find specific strings in a memory location that is activly being written before it is saved in a log file. I saw that you were looking to write a string locator in memory, but I was wondering how it is done or if you ever did write one. I think that your article is awesome by the way. I just need some guidance on what I could do to find words(strings) in a memory location while a program is writing to it. I want to parse that data and then use it as a variable later. something like when the string "Your syntesis is successful" occurs, the memory program will find that then save it to a memory location and then perform a keyboard command later that will correspond to the string. Something like using the [Enter] button on the keyboard when the string appears. I thought that your idea of a string locator would do this as well.

Strings are not native types in most of the programming languages and so, the compiler for that language may store the Strong in the memory, in its unique way...
But most of the languages use a similar way for that...
But there are many types of string encodings and also different types of byte encodings...
For example, the String may be in UTF-8, Unicode, Windows-1256 or many other encodings and byte orders, and the compiler may store the bytes using the big-endian or little-endian byte orders in the memory...
So as you can see, there are many different combinations possible to look for, in the memory...
You have to be completely sure about these parameters or search the memory using all possible combinations that likely takes too long, maybe forever!
That's the reason why I have never completed my code to find Strings, but of you like, you can use these guidelines and complete it yourself.
I hope these help you.

I have made several tries to make function to search for a specific string and return the addresses but failed and tried several codes from the net, please bro help me with this i still using CheatEngine to get my addresses.

Hi,
I'm happy that you liked my article.
Because of many questions about Strings and finding them in the memory, I will write an example soon, but as I'm really busy right now, it may take some times. I'll try to do so in a week or less, but I do not make a promise.
Hope that helps.
Greetings.

I found that the codes im using are correct, but the needed value was saved outside the rage it was supposed to be, i was searching between module.BaseAddress and module.BaseAddress+ module.ModuleMemorySize,
so i got the point to search from 00000000 to 7fffffff,
but can you please help me with a hint how to make it faster, currently im increasing adress +1
,my search string always 6 digits,
thanks for your help.

Small and quick hint: As other viewers mentioned you can test the first byte of the string with the current memory byte and if it is equal test the rest of the string.
That would increase the process speed.

First of all, very nice tutorial ! I'm definitely going to work with it and hopefully it can help me reaching my goal.

I was wondering though, is it long to scan the memory of a program ? My objective would be to find some addresses of stored variables from a Flash game, to make statistics out of it. For example, by knowing the game is a multiplayers soccer game (in 2D but that's not important to know I guess), and that I want to make stats such as time possession, score, goals, assists etc.

I just want to know if it is even possible in your opinion,
thanks in advance !

Hi,
I'm happy that you liked my article.
I have never used any memory scanner (Including mine) to scan a SWF file's memory. In fact, that's the memory for Flash Player not the SWF file and I have no idea about the memory management that Flash Player does, because a Flash Game, is not a real computer program and it's the Flash Player that deals with the variables and memory management, so there may be some difficulties to reach the variable and so in the memory.
My Memory Scanner is a demonstration to the way computer programs deal with the memory and so I suggest you to use a tool like Cheat Engine to first make sure that you can even reach the variables through the scan process and then you can use my code for your purpose and do the statistics job.
Hope this helps.
Greetings.