Uninformed: Informative Information for the Uninformed

Vol 1» 2005.May


References

  1. Calling Conventions
    http://www.unixwiz.net/techtips/win32-callconv-asm.html
  2. Symbol Server
    http://www.microsoft.com/whdc/devtools/debugging/debugstart.mspx
  3. Symbols
    ms-help://MS.PSDK.1033/debug/base/symbol_files.htm
  4. Platform SDK
    www.microsoft.com/msdownload/platformsdk/sdkupdate/
  5. Endianness
    http://www.intel.com/design/intarch/papers/endian.pdf
  6. EFLAGS
    ftp://download.intel.com/design/Pentium4/manuals/25366514.pdf Appendix B
  7. Intel Command References
    http://www.intel.com/design/pentium4/manuals/index_new.htm
  8. Debugger Quick Reference
    http://www.tonyschr.net/debugging.htm
  9. WinDBG Prompt
    Reference WinDBG Help, Search, Command Window Prompt
  10. Regular Expressions
    Reference WinDBG Help, Search, Regular Expression Syntax
  11. TEB
    http://msdn.microsoft.com/library/en-us/dllproc/base/teb.asp


12. SetGrid.cpp

/********************************************************************** 
 * SetGrid.cpp - trew@exploit.us
 *
 * This is supplemental code intended to accompany 'Introduction to
 * Reverse Engineering Windows Applications' as part of the Uninformed
 * Journal.  This application sets the reader's playing grid in a 
 * deterministic manner so that demonstrations made within the paper
 * correlate with what the reader encounters in his or her instance of 
 * WinMine.
 *
 *********************************************************************/

#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>

#pragma comment(lib, "advapi32.lib")

#define GRID_ADDRESS     0x1005360
#define GRID_SIZE        0x300

int main(int argc, char *argv[]) {

    HANDLE    hProcessSnap        = NULL;
    HANDLE    hWinMineProc        = NULL;
        
    PROCESSENTRY32 peProcess      = {0};

    unsigned int procFound        = 0;
    unsigned long bytesWritten    = 0;

    unsigned char grid[] =        
    
    "\x10\x0f\x8f\x8f\x8f\x8f\x8f\x0f\x8f\x8f\x8f\x8f\x0f\x0f\x8f\x0f"
    "\x0f\x8f\x8f\x8f\x8f\x8f\x8f\x0f\x0f\x0f\x8f\x0f\x0f\x8f\x8f\x10"
    "\x10\x8f\x0f\x0f\x8f\x8f\x0f\x0f\x0f\x0f\x0f\x8f\x0f\x0f\x8f\x8f"
    "\x0f\x8f\x0f\x0f\x0f\x8f\x8f\x8f\x0f\x0f\x8f\x8f\x8f\x8f\x8f\x10"
    "\x10\x0f\x0f\x8f\x0f\x0f\x8f\x0f\x0f\x0f\x0f\x0f\x8f\x0f\x0f\x0f"
    "\x8f\x0f\x0f\x0f\x8f\x8f\x0f\x0f\x8f\x0f\x8f\x0f\x8f\x8f\x0f\x10"
    "\x10\x0f\x0f\x8f\x0f\x0f\x8f\x0f\x0f\x0f\x8f\x0f\x0f\x8f\x0f\x0f"
    "\x8f\x0f\x0f\x8f\x0f\x0f\x0f\x8f\x0f\x0f\x0f\x8f\x0f\x0f\x0f\x10"
    "\x10\x0f\x0f\x8f\x0f\x8f\x8f\x0f\x0f\x8f\x8f\x0f\x0f\x8f\x0f\x0f"
    "\x0f\x0f\x0f\x0f\x8f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x8f\x0f\x0f\x10"
    "\x10\x8f\x0f\x0f\x0f\x0f\x0f\x0f\x8f\x8f\x0f\x8f\x8f\x0f\x0f\x8f"
    "\x0f\x8f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x8f\x8f\x0f\x10"
    "\x10\x8f\x0f\x8f\x8f\x0f\x8f\x8f\x0f\x0f\x0f\x8f\x8f\x0f\x8f\x0f"
    "\x0f\x0f\x0f\x8f\x0f\x8f\x0f\x8f\x0f\x0f\x8f\x8f\x0f\x8f\x0f\x10"
    "\x10\x8f\x8f\x0f\x0f\x0f\x8f\x0f\x0f\x0f\x0f\x8f\x8f\x8f\x8f\x0f"
    "\x0f\x0f\x0f\x0f\x0f\x8f\x8f\x8f\x0f\x0f\x0f\x0f\x8f\x8f\x8f\x10"
    "\x10\x8f\x0f\x8f\x8f\x8f\x0f\x0f\x0f\x0f\x0f\x8f\x0f\x8f\x0f\x0f"
    "\x8f\x8f\x0f\x0f\x0f\x8f\x0f\x8f\x0f\x8f\x0f\x0f\x0f\x0f\x0f\x10"
    "\x10\x0f\x0f\x8f\x8f\x0f\x8f\x8f\x8f\x8f\x0f\x0f\x0f\x0f\x0f\x0f"
    "\x0f\x0f\x0f\x0f\x0f\x8f\x0f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x8f\x10"
    "\x10\x0f\x0f\x0f\x8f\x8f\x8f\x0f\x8f\x8f\x0f\x0f\x0f\x8f\x0f\x0f"
    "\x0f\x8f\x0f\x8f\x0f\x0f\x0f\x8f\x8f\x0f\x0f\x0f\x0f\x8f\x8f\x10"
    "\x10\x0f\x8f\x8f\x0f\x8f\x0f\x8f\x0f\x8f\x0f\x8f\x8f\x0f\x0f\x8f"
    "\x0f\x0f\x0f\x0f\x0f\x0f\x8f\x8f\x0f\x0f\x8f\x0f\x8f\x0f\x0f\x10"
    "\x10\x0f\x0f\x8f\x8f\x0f\x8f\x0f\x0f\x0f\x8f\x0f\x0f\x0f\x8f\x0f"
    "\x8f\x0f\x8f\x8f\x8f\x0f\x0f\x8f\x0f\x8f\x0f\x8f\x8f\x8f\x8f\x10"
    "\x10\x8f\x8f\x0f\x0f\x0f\x0f\x0f\x0f\x8f\x0f\x8f\x0f\x0f\x8f\x0f"
    "\x0f\x0f\x8f\x8f\x8f\x8f\x8f\x0f\x0f\x8f\x8f\x0f\x0f\x8f\x8f\x10"
    "\x10\x8f\x0f\x0f\x0f\x8f\x0f\x8f\x8f\x8f\x8f\x0f\x0f\x8f\x8f\x0f"
    "\x0f\x8f\x0f\x0f\x8f\x8f\x8f\x8f\x0f\x8f\x0f\x8f\x0f\x8f\x8f\x10"
    "\x10\x0f\x8f\x8f\x0f\x0f\x8f\x8f\x8f\x0f\x8f\x0f\x0f\x0f\x0f\x0f"
    "\x0f\x8f\x8f\x8f\x0f\x0f\x8f\x0f\x8f\x8f\x8f\x0f\x8f\x8f\x0f\x10"
    "\x10\x8f\x0f\x0f\x8f\x8f\x8f\x8f\x0f\x0f\x8f\x0f\x0f\x0f\x8f\x8f"
    "\x8f\x8f\x0f\x0f\x0f\x0f\x0f\x8f\x0f\x8f\x8f\x0f\x0f\x8f\x0f\x10"
    "\x10\x0f\x8f\x8f\x0f\x0f\x0f\x0f\x8f\x0f\x8f\x0f\x8f\x0f\x0f\x0f"
    "\x0f\x0f\x0f\x8f\x0f\x0f\x0f\x8f\x0f\x0f\x0f\x8f\x0f\x8f\x0f\x10"
    "\x10\x0f\x0f\x0f\x0f\x8f\x8f\x8f\x8f\x8f\x0f\x0f\x0f\x8f\x0f\x0f"
    "\x8f\x8f\x8f\x0f\x0f\x8f\x8f\x8f\x0f\x0f\x8f\x0f\x0f\x8f\x0f\x10"
    "\x10\x8f\x8f\x0f\x8f\x8f\x0f\x8f\x8f\x0f\x0f\x0f\x0f\x8f\x8f\x8f"
    "\x8f\x0f\x8f\x0f\x0f\x0f\x8f\x0f\x8f\x8f\x8f\x0f\x8f\x0f\x0f\x10"
    "\x10\x0f\x8f\x8f\x0f\x0f\x8f\x8f\x8f\x0f\x0f\x8f\x0f\x0f\x0f\x0f"
    "\x0f\x0f\x8f\x8f\x0f\x8f\x0f\x0f\x0f\x0f\x0f\x0f\x8f\x0f\x8f\x10"
    "\x10\x0f\x0f\x8f\x0f\x8f\x0f\x8f\x8f\x0f\x0f\x0f\x0f\x0f\x0f\x0f"
    "\x0f\x8f\x0f\x0f\x0f\x0f\x0f\x0f\x8f\x0f\x0f\x0f\x0f\x0f\x8f\x10"
    "\x10\x0f\x8f\x8f\x8f\x0f\x8f\x0f\x8f\x0f\x0f\x8f\x0f\x0f\x8f\x0f"
    "\x0f\x8f\x8f\x0f\x0f\x0f\x0f\x8f\x0f\x8f\x8f\x0f\x0f\x0f\x8f\x10"
    "\x10\x8f\x0f\x0f\x0f\x8f\x0f\x0f\x8f\x0f\x8f\x0f\x0f\x0f\x0f\x8f"
    "\x0f\x8f\x0f\x0f\x0f\x8f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x8f\x8f\x10";


    //Get a list of running processes
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        
    if(hProcessSnap == INVALID_HANDLE_VALUE) {
        printf("Unable to get process list (%d).\n", GetLastError());
        return 0;
    }
                
    peProcess.dwSize = sizeof(PROCESSENTRY32);

    //Get first process in list
    if(Process32First(hProcessSnap, &peProcess)) {

        do {
            //Is it's winmine.exe?
            if(!stricmp(peProcess.szExeFile, "winmine.exe")) {

                printf("Found WinMine Process ID (%d)\n", peProcess.th32ProcessID);
                procFound = 1;

                //Get handle on winmine process
                hWinMineProc = OpenProcess(PROCESS_ALL_ACCESS, 
                                           1, 
                                           peProcess.th32ProcessID);
                        
                //Make sure the handle is valid

                if(hWinMineProc == NULL) {
                    printf("Unable to open minesweep process (%d).\n", GetLastError());
                    return 0;
                }

                //Write grid
                if(WriteProcessMemory(hWinMineProc, 
                                      (LPVOID)GRID_ADDRESS,
                                      (LPCVOID)grid, 
                                      GRID_SIZE,
                                      &bytesWritten) == 0) {
                    printf("Unable to write process memory (%d).\n", GetLastError());        
                    return 0;
                } else {
                    printf("Grid Update Successful\n");
                }

                //Let go of minesweep
                CloseHandle(hWinMineProc);
                break;
            }

        //Get next process
        } while(Process32Next(hProcessSnap, &peProcess));   
    }
            
    if(!procFound)
        printf("WinMine Process Not Found\n");

    return 0;
}

13. MineSweeper.cpp

/********************************************************************** 
 * MineSweeper.cpp - trew@exploit.us
 *
 * This is supplemental code intended to accompany 'Introduction to
 * Reverse Engineering Windows Applications' as part of the Uninformed
 * Journal.  This application reveals and/or removes mines from the 
 * WinMine grid.  Note, this code only works on the version of WinMine 
 * shipped with WinXP, as the versions differ between releases of 
 * Windows.
 *
 *********************************************************************/

#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>

#pragma comment(lib, "advapi32.lib")

#define BOMB_HIDDEN      0x8f
#define BOMB_REVEALED    0x8a
#define BLANK            0x0f
#define GRID_ADDRESS     0x1005360
#define GRID_SIZE        0x300

int main(int argc, char *argv[]) {

    HANDLE    hProcessSnap        = NULL;
    HANDLE    hWinMineProc        = NULL;
        
    PROCESSENTRY32 peProcess      = {0};

    unsigned char procFound       = 0;
    unsigned long bytesWritten    = 0;
    unsigned char *grid           = 0;
    unsigned char replacement     = BOMB_REVEALED;
    unsigned int x                = 0;

    grid = (unsigned char *)malloc(GRID_SIZE);

    if(!grid)
        return 0;

    if(argc > 1) {
        if(stricmp(argv[1], "remove") == 0) {
            replacement = BLANK;
        }
    }

    //Get a list of running processes
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        
    //Ensure the handle is valid
    if(hProcessSnap == INVALID_HANDLE_VALUE) {
        printf("Unable to get process list (%d).\n", GetLastError());
        return 0;
    }
                
    peProcess.dwSize = sizeof(PROCESSENTRY32);

    //Get first process in list
    if(Process32First(hProcessSnap, &peProcess)) {

        do {
            //Is it's winmine.exe?
            if(!stricmp(peProcess.szExeFile, "winmine.exe")) {

                printf("Found WinMine Process ID (%d)\n", peProcess.th32ProcessID);
                procFound = 1;

                //Get handle on winmine process
                hWinMineProc = OpenProcess(PROCESS_ALL_ACCESS,
                                           1,
                                           peProcess.th32ProcessID);
                        
                //Make sure the handle is valid
                if(hWinMineProc == NULL) {
                    printf("Unable to open minesweep process (%d).\n", GetLastError());
                    return 0;
                }

                //Read Grid
                if(ReadProcessMemory(hWinMineProc,
                                     (LPVOID)GRID_ADDRESS,
                                     (LPVOID)grid, GRID_SIZE,
                                     &bytesWritten) == 0) {
                    printf("Unable to read process memory (%d).\n", GetLastError());        
                    return 0;
                } else {
                    //Modify Grid
                    for(x=0;x<=GRID_SIZE;x++) {
                        if((*(grid + x) & 0xff) == BOMB_HIDDEN) {
                            *(grid + x) = replacement;
                        }
                    }
                }

                //Write grid
                if(WriteProcessMemory(hWinMineProc, 
                                      (LPVOID)GRID_ADDRESS,
                                      (LPCVOID)grid, 
                                      GRID_SIZE, 
                                      &bytesWritten) == 0) {
                    printf("Unable to write process memory (%d).\n", GetLastError());        
                    return 0;
                } else {
                    printf("Grid Update Successful\n");
                }

                //Let go of minesweep
                CloseHandle(hWinMineProc);
                break;
            }

        //Get next process
        } while(Process32Next(hProcessSnap, &peProcess));   
    }
    
    if(!procFound)
        printf("WinMine Process Not Found\n");

    return 0;
}