Pointless Minesweeper Source Code
March 29th, 2006

The source code for my Pointless Minesweeper Clone can be found here. Enjoy it.

The license is BSD (you may know this as the “hey, go nuts” license).

Update, 2012: I’ve put the source code up on github.


Pointless Minesweeper Clone
March 26th, 2006

Minsweeper++

My roommate, a grizzled veteran of Cornell’s CS 211, made an announcement a week or two ago. It was something along the lines of, “gee whiz, I’m glad they didn’t make us write minesweeper as a project. It looks impossible.” To prove my vast intellectual superiority I made a winforms clone in about six or seven hours, including the time it took to draw the graphics and perform extensive “QA.”

You can start the clickonce app from this link.

Screenshot:

Screenshot of Minsweeper++

The source will be forthcoming. Bugs and so forth, feel free to contact me. The rendering is a bit on the slow side for my tastes, so you needn’t mention that.


Debugger Exercise: Displaying a Function's Return Value
March 22nd, 2006

I found myself needing to automatically manipulate the return value of a managed function in release code today. I thought this would make an interesting little writeup.

For the purposes of the demonstration, let’s use this example program:


    class Program
    {
        static void Main()
        {
            while (!Console.KeyAvailable)
            {
                Console.WriteLine(FooBar(false));
                Console.WriteLine(FooBar2());
            }
        }
    
        static string FooBar(bool b)
        {
            if (b)
            {
                return "b";
            }
            return "a";
        }
    
        static string FooBar2()
        {
            return FooBar(true);
        }
    }

  

The function we’re interested in will be FooBar. I’ve made things interesting by calling the function from two places—let’s assume we’re not sure where the function is called from. We’ll make things more interesting still by accepting the limitation that we won’t cheat and set a breakpoint on the ret instruction in FooBar. The function I needed to instrument today was a little monolithic, so let’s take it as a given that we need to be able to handle a function that might be long and might have more than one exit point.

Compile this program and start it in WinDbg. Start by loading SOS:

0:003> .loadby sos mscorwks

The first thing we’ll do is set a breakpoint on FooBar. (I’m going to do this manually so that these steps will work with the CLR v1.1. The new version of SOS makes this slightly easier. I’m also going to cover this quickly, so if you want a clearer explanation of what’s going on in this next step see Eran Sandler’s writeup here.)

To set the breakpoint, let the program run for a second so that the method is compiled by the JIT. Then we need to find and dump out the MethodTable for the class:

0:003> !name2ee retaddr.Program
Module: 00912d5c (retaddr.exe)
Token: 0x02000002
MethodTable: 00913140
EEClass: 009112ec
Name: retaddr.Program

0:003> !dumpmt -md 00913140
EEClass: 009112ec
Module: 00912d5c
Name: retaddr.Program
mdToken: 02000002
BaseSize: 0xc
ComponentSize: 0x0
Number of IFaces in IFaceMap: 0
Slots in VTable: 8
--------------------------------------
MethodDesc Table
   Entry MethodDesc      JIT Name
...
00d00070   00913120      JIT retaddr.Program.Main()
00d000d8   00913128      JIT retaddr.Program.FooBar(Boolean)
00d00130   00913130      JIT retaddr.Program.FooBar2()
...

Now that we have the MethodTable, we need to dump out the MethodDesc for FooBar to get the virtual address of the jitted code.

0:003> !dumpmd 00913128
Method Name: retaddr.Program.FooBar(Boolean)
Class: 009112ec
MethodTable: 00913140
mdToken: 06000002
Module: 00912d5c
IsJitted: yes
m_CodeOrIL: 00d000d8

The compiled method begins at m_CodeOrIL (this is called “Method VA” in SOS 1.1). We can set a breakpoint there with bp 00d000d8.

Here comes the trick. We know that the return address to the method should be on the top of the stack when the method is called. In other words, the ESP register points at the return address. We can set a dynamic breakpoint on that return address using a command like this:

bp 00d000d8 "bp poi(@esp); g"

If you try this, you’ll notice that we break right after FooBar has returned to its caller. As with any function obeying one of the standard calling conventions, the return value is stored in the EAX register. We can give the dynamic breakpoint a command of its own that manipulates this value like this:

bp 00d000d8 "bp poi(@esp) \"!do!do -nofields @eax; g\"; g"

If we run the sample program now, we’ll see this output repeating itself:

breakpoint 1 redefined
Name: System.String
MethodTable: 790fa3e0
EEClass: 790fa340
Size: 20(0x14) bytes
String: a
 
breakpoint 2 redefined
Name: System.String
MethodTable: 790fa3e0
EEClass: 790fa340
Size: 20(0x14) bytes
String: b

Voila.