Introduction

Ever wanted to know what is happening in the Minesweeper game behind the
scenes?
Well, I did, and I decided to investigate it. This article is the result of
my research, brought here just for you.

Main Concepts

1. Using P/Invoke to invoke Win32 API's.

2. Direct reading another process memory.

NOTE: the first part of this article involves some assembly code, if there
something you don't understand it's NOT important to the goal of this article.
you CAN skip it. Nevertheless, if you want to ask me about it, you're more then
welcome to mail me your question.

NOTE 2: The program was tested on Windows XP, so if you got some other system
it might not work.. if you got some other system, and it did worked, comment
this article with your system info so we all could enjoy that knowledge.

Update to NOTE 2: the code is now fixed in order to work on Windows 2000 as well. thanks goes to Ryan Schreiber for finding the addresses in Win2K.

Step 1 - Investigate winmine.exe

If you're not an assembly fan, you might want to skip to the end of this
step, to the conclusions..

So, in order to know better what is happening behind the scenes of
Minesweeper I've started by opening the file in a debugger. My personally
favorite debugger is Olly Debugger v1.08, this is a very simple and intuitive
debugger. Anyway, I've open winmine.exe in the debugger and looked a bit on the
file. I've found in the Import section (a section that lists all the dll
functions that are used in the program) the following entry:

010011B0 8D52C377 DD msvcrt.rand

which means that the Minesweeper uses the randomize function of the MicroSoft
Visual C RunTime dll, So I thought it might help me. I've search the file to
find where the rand() function is being called, I've found only one such place:

01003940 FF15 B0110001 CALL DWORD PTR DS:[<&msvcrt.rand>]

Then I've put a breakpoint on this single call and ran the program. I've
discovered that every time you click the smiley a new mines map is generated.
the mines map is created as follows:

1. Allocate a block of memory for the mines map and set all the memory bytes
to 0x0F, which means that there is no mine in that "cell".
2. second, loop over the number of mines and for each mine:
2.1. randomize x position (1 .. width).2.2. randomize y position (1 .. height).2.3. set the correct cell in the memory block to 0x8F, which represents a
mine in this cell.

here is the original code, I've added some remarks, and bolded the important parts:

Step 2 - Design a solution

You might wonder, what kind of solution am I talking about? Well, after
discovering that all the mine information is available for me, and all I need to
do is read the data from the memory I've decided to write a small app that reads
this information and present it for you. It can even draw a map of its own, with
a picture of a mine wherever I find one..

So, what is to design about that? all I need to do is put the address into a
pointer (yes, they exist even in C#) and read the pointed data, right? well, not
exactly, the reason why this is not the case is that the memory where this data is
stored is not in my application. You see, each process has its own address space
so it could not access "by accident" memory that belongs to another program, so
in order to read this data I need to find a way to read the memory of another
process, in this case, its the Minesweeper process.

I've decided to write a small class library, that will receive a process and
will give me the functionality of reading a memory address from this process.
the reason I've decided to make it a class library is because there is allot of
cases you might want to use it so why develop it again and again? That way, you
could easily take the class and use it in your own application, and you are free
to do so. An example for where this class can help is if you write a debugger.
All the debuggers I know have the ability to read memory of the debugged
application..

So, how do we read another process memory? the answer resides in an API called
ReadProcessMemory. this API actually let you read a process memory at a specific
address. Only before you do it you must open the process in a special read mode
and when you finish you must close the process handle, to avoid resource leaks.
The following operations are performed with the help of two more API called
OpenProcess and CloseHandle.

In order to use API's with C# you must use the P/Invoke, meaning you need to
declare the API you're going to use, which is basically quite simple, but you
need to do it in the .NET way, which is not that simple sometimes.. I've found
the API declarations in the MSDN:

If you want to know more information on the types conversions between c++ and
c#, I suggest you searched msdn.microsoft.com for the topics: "Marshaling Data
with Platform Invoke". Basically, if you put there what is logically true, it
will work. sometimes, a bit tuning is requested.

After I have these functions declared, all I need to do is wrap them with a
simple class and use it. I've put the declarations in a separate class called
ProcessMemoryReaderApi, only to be more organized. The main utility class is
called ProcessMemoryReader. This class has a property named
ReadProcess, this property is from the type System.Diagnostics.Process,
this is where you put the process you want to read its memory.

The class has a method which opens the process in the read memory mode:

and all we need to do now is Open the process, read the memory, and close it
when we finish. Again, here is an example of how its been done. Here I read the
memory address that represent the Width of the map.

Im trying to use this function in c#.
Im not sure what I'm doing wrong but I always get a empty MEMORY_BASIC_INFORMATION structure back.
And I can't find ANY examples with google about this function, all i get is C# and VB.NET declaration of this api function.

I am currently trying to scan a processes memory and locate where it stores certain values, in this case where a poker application stores the card values for each player at the table.

I am looking at all of the values in Olly's right now, and see places that mark my interest, but what should I be looking for specifically to target these areas of memory. (e.g., EAX registers, PUSH commands, RETURN commands, etc.)

Any help is greatly appreciated, my mailing address is jon@blake.net and I will post some of the striking memory locations & their values @ http://silenceisdefeat.org/~forte/mem/

I realise this question comes after some years since this article was published. Still, i have a question which was asked before on this site, but apparently has never been answered:

What if i want to scan the memory of a process to find some variables ? For instance i want to create a game trainer like ArtMoney. I introduce a value, and the program finds all the locations in the process' memory which mach my value.

My question is simple: where do i start the search, and where do i stop. I already tried the dummest thing, which was to scan from 0x00000000 and until i find my value... Obviously it got blocked at some point, before finding my value...

I was thinking that most likely, every process has to have a unique address where it memorizes the variables... But i don't know and i can't seem to find anything about that on the net...

Hi bunnyEATINGrabbit!
I've just started using the pointers in C# (i'm not so new in C# but not that expert that the code heros are!) and when I saw this project and got the point of reading another processes memory and then I saw your question, I tried what you asked for and became almost successful and just wanted to know if you are still intrested in solving the problem or not?
If you are, so alert me to help you!
You can even contact me @ sojaner@yahoo.com

Comment:
A nice piece of work. I can already imagine some useful applications for the technique (once the memory is located). I'd imagine writing applications with an absolute memory location withing the apps memory space would make this easier to use.

Question:
For the few who commented on using it to play minesweeper - why ??? I can never seem to understand why someone would want to play and win a single-player game by cheating. What is the point? Really. I would love an explaination so I could understand.

"The difference between genius and stupidity is that genius has its limits." - Albert Einstein

So, I'm writing something similar to this, but the variables are not always in the same location. What I plan on doing is simply scanning the entirety of the application's memory and search for the text immediately preceeding the variable i want.

My problem is, how can I determine how much memory exists inside an application? I've tried a few of the likely .net variables but they don't return a number which corresponds with the size Windows reports (the size of that application in memory.)

1.- well does it means the os has allways reserved this addresses to the winmine?
2.- what if the winmine does not ever run, it's stupid keep memory space for an app wich we don´t know if it's going to ever be run, isn`t it?, and if it is not reserved we might be looking at the wrong position?

3.- So i've thought about this and the only thing that came up and make sense was we are not refering to an absolute memory adress instead we referr to the "iWidthAddress = 0x1005334" within the memory space of the winmine process. is this the answer or it is not?

1. No, the operating system does not always lock that piece of memory for that particular app.
2. Answered in 1
3. 0x anything is what's called an offset. It's the distance from memory adress zero relative to that application. Minesweeper is nice because its memory is static and you will always know where certain pieces of information are.

I'm not certain why the operating system matters, but I'd imagine it has to do with the way the application is compiled on each is different.

I notice through tsearch when looking at the mem locations that there are 2 places affected. The offsets above are one, but there is a second which stores the same info for each of those parameters.

I have noticed that if I change the info at the address above (eg I changed the number of mines at 1005330) it gets overwritten. So to make the change I have to do it in a different area (in the case of xp pro 10056A4). The same happens with width/ht.

I am wondering if this other loc is something to do with the input form where you can enter custom parameters.

My other question is say you want to reset all the mines remotely (same as clicking on the smily face) how does one do that? Can you invoke a process remotely just as you can read memory?

This same question refers to if you would like to "click" on a button as if you were going to play the game from the computer.

Hello friend ...
i was jus browsing around when i had a look at this article of urs .. good effort, i must say ... even i designed something like this in assembly, a couple of years ago ...
wat i did was, use the mouseover to show where the bomb is when its pointing to a grid... it was only done when the special sneaking mode was active and it was all with dll injection in the process... Anyway this method of yours is also a good one ... all the best for ur future work ...
good day

but they didn't include any property or field or method or..., that returns the Context value!
So I went for it and found the "GetThreadContext" function of "kernel32.dll" and in MSND it was explaind like this: