Annotation of mstools/samples/sdktools/walker/pdebug.c, revision 1.1

1.1     ! root        1: #include "pwalk.h"
        !             2: #include <memory.h>
        !             3: 
        !             4: 
        !             5: /* module globals */
        !             6: LPVOID   PMAAddress;
        !             7: LPVOID   PMABuffer;
        !             8: DWORD    PMASize;
        !             9: extern   char    szCurPath[MAX_PATH];
        !            10: 
        !            11: 
        !            12: /* local debug functions */
        !            13: BOOL   WINAPI DebugEventThread (DBGPROCESS *);
        !            14: BOOL   WINAPI CreateDebugEvents (LPHANDLE);
        !            15: void   WINAPI AddThreadNode (DBGPROCESS *, DWORD, HANDLE, int, LPTHREAD_START_ROUTINE, HANDLE);
        !            16: int    WINAPI HandleMipsBreakPoint(DBGPROCESS *, DWORD);
        !            17: void   WINAPI RemoveThreadNode (DBGPROCESS *, DWORD);
        !            18: void   WINAPI AddDllNode (DBGPROCESS *, LOAD_DLL_DEBUG_INFO *);
        !            19: void   WINAPI RemoveDllNode (DBGPROCESS *, LOAD_DLL_DEBUG_INFO *);
        !            20: void   WINAPI SuspendDebuggeeProcess (DBGPROCESS *);
        !            21: void   WINAPI ResumeDebuggeeProcess (DBGPROCESS *);
        !            22: void   WINAPI NameObjects (HANDLE, LPVOID, LPVMOBJECT, int, char *, char *);
        !            23: BOOL   WINAPI VMCompare (LPVMOBJECT, LPVMOBJECT);
        !            24: BOOL   WINAPI InterruptThread_HookProcess (DBGPROCESS *, LPPROCESS_STATE);
        !            25: void   WINAPI ResetInterruptedThread (DBGPROCESS *, LPPROCESS_STATE);
        !            26: void   WINAPI RecordException (DBGPROCESS *, DEBUG_EVENT *);
        !            27: HANDLE WINAPI FindThreadHandle (DBGPROCESS *, DWORD);
        !            28: 
        !            29: 
        !            30: 
        !            31: /* start debug thread, and return event active handle */
        !            32: DBGPROCESS* WINAPI StartChildProcess (
        !            33:     HWND       hWnd,
        !            34:     char       *lpszModule,
        !            35:     LPHANDLE   lpDbgEvents)
        !            36: {
        !            37:     DWORD        TID;
        !            38:     HANDLE       hDebugHeap;
        !            39:     DBGPROCESS   *lpDbgProcess;
        !            40:     int          i;
        !            41: 
        !            42:     /* create unique debug events using debuggee process ID */
        !            43:     if (!CreateDebugEvents (lpDbgEvents))
        !            44:        return NULL;
        !            45: 
        !            46:     /* create serialized heap of dynamic size */
        !            47:     if (!(hDebugHeap = HeapCreate (0, sizeof (DBGPROCESS) + sizeof (DBGTHREAD), 0)))
        !            48:        {
        !            49:        /* close all event handles */
        !            50:        for (i=0; i<nDEBUGEVENTS; i++)
        !            51:            CloseHandle (lpDbgEvents[i]);
        !            52: 
        !            53:        return NULL;
        !            54:        }
        !            55: 
        !            56:     /* allocate and initialize debug heap structure */
        !            57:     lpDbgProcess = (DBGPROCESS *)HeapAlloc (hDebugHeap, 0, sizeof (DBGPROCESS));
        !            58:     lpDbgProcess->hDbgHeap = hDebugHeap;
        !            59:     strcpy (lpDbgProcess->szModule, lpszModule);
        !            60:     lpDbgProcess->hWnd = hWnd;
        !            61:     lpDbgProcess->lpThreads = NULL;
        !            62:     lpDbgProcess->lpSection = NULL;
        !            63:     lpDbgProcess->lpERs = NULL;
        !            64: 
        !            65:     /* create debug thread */
        !            66:     if (!(CreateThread ((LPSECURITY_ATTRIBUTES)NULL,
        !            67:                        4096,
        !            68:                        (LPTHREAD_START_ROUTINE)DebugEventThread,
        !            69:                        (LPVOID)lpDbgProcess,
        !            70:                        0,
        !            71:                        &TID)))
        !            72:        return NULL;
        !            73: 
        !            74:     /* wait 15 seconds for debugger to complete initialization, else error */
        !            75:     if (WAIT_TIMEOUT == WaitForSingleObject (lpDbgEvents[ACKNOWLEDGE], 15000))
        !            76:        {
        !            77:        HeapDestroy (lpDbgProcess->hDbgHeap);
        !            78: 
        !            79:        /* close all event handles */
        !            80:        for (i=0; i<nDEBUGEVENTS; i++)
        !            81:            CloseHandle (lpDbgEvents[i]);
        !            82: 
        !            83:        return NULL;
        !            84:        }
        !            85: 
        !            86:     /* reset acknowledge event */
        !            87:     ResetEvent (lpDbgEvents[ACKNOWLEDGE]);
        !            88: 
        !            89:     /* successfull thread and event start */
        !            90:     return lpDbgProcess;
        !            91: }
        !            92: 
        !            93: 
        !            94: 
        !            95: 
        !            96: /* function notifies debug thread to terminate, frees handles, and destroys heap */
        !            97: void   WINAPI CloseChildProcess (
        !            98:     DBGPROCESS *lpDbgProcess,
        !            99:     LPHANDLE   lpDbgEvents)
        !           100: {
        !           101:     int         i;
        !           102:     DBGTHREAD   *pNode = lpDbgProcess->lpThreads;
        !           103: 
        !           104:     /* set close event for debug thread and wait for acknowledge */
        !           105:     SetEvent (lpDbgEvents[CLOSEDEBUGGER]);
        !           106:     WaitForSingleObject (lpDbgEvents[ACKNOWLEDGE], INFINITE);
        !           107: 
        !           108:     /* close all event handles */
        !           109:     for (i=0; i<nDEBUGEVENTS; i++)
        !           110:        CloseHandle (lpDbgEvents[i]);
        !           111: 
        !           112:     /* close all thread handles in the list */
        !           113:     while (pNode != NULL)
        !           114:        {
        !           115:        RemoveThreadNode (lpDbgProcess, pNode->dwThreadID);
        !           116:        pNode = lpDbgProcess->lpThreads;
        !           117:        }
        !           118: 
        !           119:     /* destroy the debug heap */
        !           120:     HeapDestroy (lpDbgProcess->hDbgHeap);
        !           121: }
        !           122: 
        !           123: 
        !           124: 
        !           125: 
        !           126: /* local function creates debug event objects for thread synchronization */
        !           127: BOOL WINAPI CreateDebugEvents (
        !           128:     LPHANDLE   lpDbgEvents)
        !           129: {
        !           130:     char    szEvent[MAX_PATH];
        !           131: 
        !           132: 
        !           133:     LoadString (GetModuleHandle (NULL), IDS_DBGEVNTACTIVE, szEvent, sizeof (szEvent));
        !           134:     if (!(lpDbgEvents[DEBUGACTIVE] = CreateEvent ((LPSECURITY_ATTRIBUTES)NULL,
        !           135:                                                  TRUE,
        !           136:                                                  TRUE,
        !           137:                                                  szEvent)))
        !           138:        return FALSE;
        !           139: 
        !           140:     LoadString (GetModuleHandle (NULL), IDS_DBGEVNTCLOSE, szEvent, sizeof (szEvent));
        !           141:     if (!(lpDbgEvents[CLOSEDEBUGGER] = CreateEvent ((LPSECURITY_ATTRIBUTES)NULL,
        !           142:                                                   TRUE,
        !           143:                                                   FALSE,
        !           144:                                                   szEvent)))
        !           145:        {
        !           146:        CloseHandle (lpDbgEvents[DEBUGACTIVE]);
        !           147:        return FALSE;
        !           148:        }
        !           149: 
        !           150:     LoadString (GetModuleHandle (NULL), IDS_DBGEVNTSTOP, szEvent, sizeof (szEvent));
        !           151:     if (!(lpDbgEvents[SUSPENDDEBUGGER] = CreateEvent ((LPSECURITY_ATTRIBUTES)NULL,
        !           152:                                                      TRUE,
        !           153:                                                      FALSE,
        !           154:                                                      szEvent)))
        !           155:        {
        !           156:        CloseHandle (lpDbgEvents[DEBUGACTIVE]);
        !           157:        CloseHandle (lpDbgEvents[CLOSEDEBUGGER]);
        !           158:        return FALSE;
        !           159:        }
        !           160: 
        !           161:     LoadString (GetModuleHandle (NULL), IDS_DBGEVNTSTART, szEvent, sizeof (szEvent));
        !           162:     if (!(lpDbgEvents[RESUMEDEBUGGER] = CreateEvent ((LPSECURITY_ATTRIBUTES)NULL,
        !           163:                                                     TRUE,
        !           164:                                                     FALSE,
        !           165:                                                     szEvent)))
        !           166:        {
        !           167:        CloseHandle (lpDbgEvents[DEBUGACTIVE]);
        !           168:        CloseHandle (lpDbgEvents[CLOSEDEBUGGER]);
        !           169:        CloseHandle (lpDbgEvents[SUSPENDDEBUGGER]);
        !           170:        return FALSE;
        !           171:        }
        !           172: 
        !           173:     LoadString (GetModuleHandle (NULL), IDS_DBGEVNTREAD, szEvent, sizeof (szEvent));
        !           174:     if (!(lpDbgEvents[READMEMORY] = CreateEvent ((LPSECURITY_ATTRIBUTES)NULL,
        !           175:                                                 TRUE,
        !           176:                                                 FALSE,
        !           177:                                                 szEvent)))
        !           178:        {
        !           179:        CloseHandle (lpDbgEvents[DEBUGACTIVE]);
        !           180:        CloseHandle (lpDbgEvents[CLOSEDEBUGGER]);
        !           181:        CloseHandle (lpDbgEvents[SUSPENDDEBUGGER]);
        !           182:        CloseHandle (lpDbgEvents[RESUMEDEBUGGER]);
        !           183:        return FALSE;
        !           184:        }
        !           185: 
        !           186:     LoadString (GetModuleHandle (NULL), IDS_DBGEVNTWRITE, szEvent, sizeof (szEvent));
        !           187:     if (!(lpDbgEvents[WRITEMEMORY] = CreateEvent ((LPSECURITY_ATTRIBUTES)NULL,
        !           188:                                                  TRUE,
        !           189:                                                  FALSE,
        !           190:                                                  szEvent)))
        !           191:        {
        !           192:        CloseHandle (lpDbgEvents[DEBUGACTIVE]);
        !           193:        CloseHandle (lpDbgEvents[CLOSEDEBUGGER]);
        !           194:        CloseHandle (lpDbgEvents[SUSPENDDEBUGGER]);
        !           195:        CloseHandle (lpDbgEvents[RESUMEDEBUGGER]);
        !           196:        CloseHandle (lpDbgEvents[READMEMORY]);
        !           197:        return FALSE;
        !           198:        }
        !           199: 
        !           200:     LoadString (GetModuleHandle (NULL), IDS_DBGEVNTACK, szEvent, sizeof (szEvent));
        !           201:     if (!(lpDbgEvents[ACKNOWLEDGE] = CreateEvent ((LPSECURITY_ATTRIBUTES)NULL,
        !           202:                                                  TRUE,
        !           203:                                                  FALSE,
        !           204:                                                  szEvent)))
        !           205:        {
        !           206:        CloseHandle (lpDbgEvents[DEBUGACTIVE]);
        !           207:        CloseHandle (lpDbgEvents[CLOSEDEBUGGER]);
        !           208:        CloseHandle (lpDbgEvents[SUSPENDDEBUGGER]);
        !           209:        CloseHandle (lpDbgEvents[RESUMEDEBUGGER]);
        !           210:        CloseHandle (lpDbgEvents[READMEMORY]);
        !           211:        CloseHandle (lpDbgEvents[WRITEMEMORY]);
        !           212:        return FALSE;
        !           213:        }
        !           214: 
        !           215:     /* success */
        !           216:     return TRUE;
        !           217: }
        !           218: 
        !           219: 
        !           220: 
        !           221: 
        !           222: 
        !           223: /* main daddyo thread that is the debugger residing over a debuggee */
        !           224: BOOL WINAPI DebugEventThread (
        !           225:     DBGPROCESS   *lpDbgProcess)
        !           226: {
        !           227:     DEBUG_EVENT           de;
        !           228:     HANDLE                hDbgEvent[nDEBUGEVENTS];
        !           229:     STARTUPINFO           si;
        !           230:     PROCESS_INFORMATION    pi;
        !           231:     HANDLE                hChildProcess;
        !           232:     BOOL                  bHooked, bUnHooked;
        !           233:     PROCESS_STATE         ProcessState;
        !           234: 
        !           235: 
        !           236:     bHooked = FALSE;
        !           237:     bUnHooked = FALSE;
        !           238: 
        !           239:     /* initialize process startup information */
        !           240:     si.cb             = sizeof (si);
        !           241:     si.lpReserved      = NULL;
        !           242:     si.lpDesktop       = NULL;
        !           243:     si.lpTitle        = NULL;
        !           244:     si.dwX            = 0;
        !           245:     si.dwY            = 0;
        !           246:     si.dwXSize        = 0;
        !           247:     si.dwYSize        = 0;
        !           248:     si.dwXCountChars   = 0;
        !           249:     si.dwYCountChars   = 0;
        !           250:     si.dwFillAttribute = 0;
        !           251:     si.dwFlags        = STARTF_FORCEONFEEDBACK | STARTF_USESHOWWINDOW;
        !           252:     si.wShowWindow     = SW_SHOWNORMAL;
        !           253:     si.cbReserved2     = 0;
        !           254:     si.lpReserved2     = NULL;
        !           255: 
        !           256:     /* create debug process on module name */
        !           257:     if (!CreateProcess (lpDbgProcess->szModule,
        !           258:                        NULL,
        !           259:                        (LPSECURITY_ATTRIBUTES)NULL,
        !           260:                        (LPSECURITY_ATTRIBUTES)NULL,
        !           261:                        FALSE,
        !           262:                        DEBUG_PROCESS,
        !           263:                        NULL,
        !           264:                        NULL,
        !           265:                        (LPSTARTUPINFO)&si,
        !           266:                        (LPPROCESS_INFORMATION)&pi))
        !           267:        {
        !           268:        ReportError (IDS_ERRCREATEPROCESS);
        !           269:        return FALSE;
        !           270:        }
        !           271:     /* open process for all access */
        !           272:     if ((hChildProcess = OpenProcess (PROCESS_ALL_ACCESS,
        !           273:                                      FALSE,
        !           274:                                      pi.dwProcessId)) == NULL)
        !           275:        {
        !           276:        ReportError (IDS_ERROPENPROCESS);
        !           277:        TerminateProcess (pi.hProcess, 0);
        !           278:        return FALSE;
        !           279:        }
        !           280: 
        !           281:     /* store process info */
        !           282:     lpDbgProcess->hProcess = hChildProcess;
        !           283:     lpDbgProcess->dwPriority = GetPriorityClass (pi.hProcess);
        !           284:     lpDbgProcess->dwProcessID = pi.dwProcessId;
        !           285:     lpDbgProcess->bActive = TRUE;
        !           286: 
        !           287:     /* close process and thread handles in pi structure */
        !           288:     CloseHandle (pi.hThread);
        !           289:     CloseHandle (pi.hProcess);
        !           290: 
        !           291:     /* open debug events */
        !           292:     CreateDebugEvents (hDbgEvent);
        !           293: 
        !           294:     /* signale completion of task */
        !           295:     SetEvent (hDbgEvent[ACKNOWLEDGE]);
        !           296: 
        !           297:     /* start debug event loop */
        !           298:     while (TRUE)
        !           299:        {
        !           300:        int    nIndex;
        !           301: 
        !           302:        /* wait for debugger active */
        !           303:        switch (nIndex = WaitForMultipleObjects (nDEBUGEVENTS, hDbgEvent, FALSE, INFINITE))
        !           304:            {
        !           305:            case CLOSEDEBUGGER:
        !           306:                {
        !           307:                int    i;
        !           308: 
        !           309:                /* terminate debuggee process */
        !           310:                TerminateProcess (lpDbgProcess->hProcess, 0);
        !           311:                CloseHandle (lpDbgProcess->hProcess);
        !           312: 
        !           313:                /* signal completion of task */
        !           314:                SetEvent (hDbgEvent[ACKNOWLEDGE]);
        !           315: 
        !           316:                /* close all debug events */
        !           317:                for (i=0; i<nDEBUGEVENTS; i++)
        !           318:                    CloseHandle (hDbgEvent[i]);
        !           319: 
        !           320:                /* exit debugger now */
        !           321:                return TRUE;
        !           322:                }
        !           323:                break;
        !           324: 
        !           325:            case SUSPENDDEBUGGER:
        !           326:                SuspendDebuggeeProcess (lpDbgProcess);
        !           327:                ResetEvent (hDbgEvent[DEBUGACTIVE]);
        !           328:                ResetEvent (hDbgEvent[SUSPENDDEBUGGER]);
        !           329:                break;
        !           330: 
        !           331:            case RESUMEDEBUGGER:
        !           332:                ResumeDebuggeeProcess (lpDbgProcess);
        !           333:                SetEvent (hDbgEvent[DEBUGACTIVE]);
        !           334:                ResetEvent (hDbgEvent[RESUMEDEBUGGER]);
        !           335:                break;
        !           336: 
        !           337:            case READMEMORY:
        !           338:                {
        !           339:                MEMORY_BASIC_INFORMATION    mbi;
        !           340:                DWORD                       Protect = 0;
        !           341: 
        !           342:                /* reset event so we don't do repeat */
        !           343:                ResetEvent (hDbgEvent [READMEMORY]);
        !           344: 
        !           345:                /* if not committed memory abort */
        !           346:                if (!VirtualQueryEx (lpDbgProcess->hProcess,
        !           347:                                     PMAAddress,
        !           348:                                     &mbi,
        !           349:                                     sizeof (MEMORY_BASIC_INFORMATION)) ||
        !           350:                    mbi.State != MEM_COMMIT)
        !           351:                    {
        !           352:                    PMASize = 0;
        !           353:                    SetEvent (hDbgEvent [ACKNOWLEDGE]);
        !           354:                    break;
        !           355:                    }
        !           356: 
        !           357:                /* if guarded memory, change protection temporarily */
        !           358:                if (!(mbi.Protect & PAGE_READONLY) &&
        !           359:                    !(mbi.Protect & PAGE_READWRITE))
        !           360:                    VirtualProtectEx (lpDbgProcess->hProcess,
        !           361:                                      PMAAddress,
        !           362:                                      PMASize,
        !           363:                                      PAGE_READONLY,
        !           364:                                      &Protect);
        !           365: 
        !           366:                if (!ReadProcessMemory (lpDbgProcess->hProcess,
        !           367:                                        PMAAddress,
        !           368:                                        PMABuffer,
        !           369:                                        PMASize,
        !           370:                                        NULL))
        !           371:                    {
        !           372:                    if (mbi.AllocationProtect != PAGE_READONLY &&
        !           373:                        mbi.AllocationProtect != PAGE_READWRITE)
        !           374:                        NotifyUser (NULL, IDS_ERROR, 0, "BaseProtect NOACCESS", 0);
        !           375:                    else
        !           376:                        {
        !           377:                        ReportError (IDS_ERRREADPROCESSMEMORY);
        !           378:                        PMASize = 0;
        !           379:                        }
        !           380:                    }
        !           381: 
        !           382:                /* reset protection if changed */
        !           383:                if (Protect)
        !           384:                    VirtualProtectEx (lpDbgProcess->hProcess,
        !           385:                                      PMAAddress,
        !           386:                                      PMASize,
        !           387:                                      Protect,
        !           388:                                      &Protect);
        !           389: 
        !           390:                /* acknowledge success */
        !           391:                SetEvent (hDbgEvent [ACKNOWLEDGE]);
        !           392:                }
        !           393:                break;
        !           394: 
        !           395:            case WRITEMEMORY:
        !           396:                if (!WriteProcessMemory (lpDbgProcess->hProcess,
        !           397:                                         PMAAddress,
        !           398:                                         PMABuffer,
        !           399:                                         PMASize,
        !           400:                                         NULL))
        !           401:                    {
        !           402:                    ReportError (IDS_ERRWRITEPROCESSMEMORY);
        !           403:                    PMASize = 0;
        !           404:                    }
        !           405: 
        !           406:                ResetEvent (hDbgEvent [WRITEMEMORY]);
        !           407:                SetEvent (hDbgEvent [ACKNOWLEDGE]);
        !           408:                break;
        !           409: 
        !           410:            case DEBUGACTIVE:
        !           411:                /* if debug active */
        !           412:                if ((WaitForDebugEvent (&de, (DWORD)100)))
        !           413:                    {
        !           414:                    if (de.dwProcessId == lpDbgProcess->dwProcessID)
        !           415:                        {
        !           416:                        switch (de.dwDebugEventCode)
        !           417:                            {
        !           418:                            case EXIT_PROCESS_DEBUG_EVENT:
        !           419:                                SetStatusText (lpDbgProcess->hWnd, IDS_EXITPROCESS, 0);
        !           420: 
        !           421:                                /* uninitialize probe dll */
        !           422:                                ResetProbe ();
        !           423: 
        !           424:                                /* process is going away so notify main window */
        !           425:                                SendNotifyMessage (lpDbgProcess->hWnd,
        !           426:                                                   WM_COMMAND,
        !           427:                                                   IDM_PROCESSUNLOAD,
        !           428:                                                   0);
        !           429:                                break;
        !           430: 
        !           431:                            case LOAD_DLL_DEBUG_EVENT:
        !           432:                                SetStatusText (lpDbgProcess->hWnd, IDS_LOADDLL, 0);
        !           433:                                AddDllNode (lpDbgProcess,
        !           434:                                            (LOAD_DLL_DEBUG_INFO *)&(de.u.LoadDll));
        !           435:                                break;
        !           436: 
        !           437:                            case UNLOAD_DLL_DEBUG_EVENT:
        !           438:                                SetStatusText (lpDbgProcess->hWnd, IDS_UNLOADDLL, 0);
        !           439:                                RemoveDllNode (lpDbgProcess,
        !           440:                                               (LOAD_DLL_DEBUG_INFO *)&(de.u.LoadDll));
        !           441:                                break;
        !           442: 
        !           443:                            case CREATE_PROCESS_DEBUG_EVENT:
        !           444:                                SetStatusText (lpDbgProcess->hWnd, IDS_CREATEPROCESS, 0);
        !           445:                                /* add first thread to linked list of dbg structures */
        !           446:                                AddThreadNode (lpDbgProcess,
        !           447:                                                de.dwThreadId,
        !           448:                                                de.u.CreateProcessInfo.hThread,
        !           449:                                                GetThreadPriority (de.u.CreateProcessInfo.hThread),
        !           450:                                                de.u.CreateProcessInfo.lpStartAddress,
        !           451:                                                de.u.CreateProcessInfo.hFile);
        !           452:                                lpDbgProcess->hFile = de.u.CreateProcessInfo.hFile;
        !           453:                                lpDbgProcess->lpImage = de.u.CreateProcessInfo.lpBaseOfImage;
        !           454:                                lpDbgProcess->dwDbgInfoOffset = de.u.CreateProcessInfo.dwDebugInfoFileOffset;
        !           455:                                lpDbgProcess->nDbgInfoSize = de.u.CreateProcessInfo.nDebugInfoSize;
        !           456:                                break;
        !           457: 
        !           458:                            case CREATE_THREAD_DEBUG_EVENT:
        !           459:                                SetStatusText (lpDbgProcess->hWnd, IDS_CREATETHREAD, 0);
        !           460:                                /* add thread to linked list of dbg structures */
        !           461:                                AddThreadNode (lpDbgProcess,
        !           462:                                         de.dwThreadId,
        !           463:                                         de.u.CreateThread.hThread,
        !           464:                                         GetThreadPriority (de.u.CreateThread.hThread),
        !           465:                                         de.u.CreateThread.lpStartAddress,
        !           466:                                         NULL);
        !           467:                                break;
        !           468: 
        !           469:                            case EXIT_THREAD_DEBUG_EVENT:
        !           470:                                SetStatusText (lpDbgProcess->hWnd, IDS_EXITTHREAD, 0);
        !           471:                                /* remove thread record */
        !           472:                                RemoveThreadNode (lpDbgProcess,
        !           473:                                            de.dwThreadId);
        !           474:                                break;
        !           475: 
        !           476:                            case EXCEPTION_DEBUG_EVENT:
        !           477:                                switch (de.u.Exception.ExceptionRecord.ExceptionCode)
        !           478:                                    {
        !           479:                                    case EXCEPTION_BREAKPOINT:
        !           480: #ifdef _MIPS_                          /* mips needs special handling here to reset breakpoint */
        !           481:                                        HandleMipsBreakPoint(lpDbgProcess, de.dwThreadId);
        !           482:                                        SetStatusText (lpDbgProcess->hWnd,
        !           483:                                                       IDS_BREAKPOINTEXCEPTION,
        !           484:                                                       RGB (0, 0xff, 0));
        !           485:                                        break;
        !           486: #endif
        !           487: 
        !           488:                                        /* set up process hook */
        !           489:                                        if (!bHooked)
        !           490:                                            {
        !           491:                                            if (InterruptThread_HookProcess (lpDbgProcess, &ProcessState))
        !           492:                                                SetStatusText (lpDbgProcess->hWnd,
        !           493:                                                               IDS_PROCESSINIT,
        !           494:                                                               RGB (0, 0xff, 0));
        !           495:                                            else
        !           496:                                                ReportError (IDS_HOOKPROCESS);
        !           497: 
        !           498:                                            bHooked = TRUE;
        !           499:                                            }
        !           500: 
        !           501:                                        else if (bHooked &&
        !           502:                                                 !bUnHooked)
        !           503:                                            {
        !           504:                                            ResetInterruptedThread (lpDbgProcess, &ProcessState);
        !           505:                                            SetStatusText (lpDbgProcess->hWnd,
        !           506:                                                           IDS_STATUSREADY,
        !           507:                                                           0);
        !           508: 
        !           509:                                            /* post message to get ball rolling in main thread */
        !           510:                                            PostMessage (lpDbgProcess->hWnd,
        !           511:                                                         WM_COMMAND,
        !           512:                                                         IDM_PROCESSREWALK,
        !           513:                                                         0);
        !           514:                                            bUnHooked = TRUE;
        !           515:                                            }
        !           516: 
        !           517:                                        else
        !           518:                                            SetStatusText (lpDbgProcess->hWnd,
        !           519:                                                           IDS_BREAKPOINTEXCEPTION,
        !           520:                                                           RGB (0, 0xff, 0));
        !           521:                                        break;
        !           522: 
        !           523:                                    case EXCEPTION_ACCESS_VIOLATION:
        !           524:                                        /* record exception information */
        !           525:                                        SetStatusText (lpDbgProcess->hWnd,
        !           526:                                                       IDS_ACCESSVIOLATIONEXCEPTION,
        !           527:                                                       RGB (0xff, 0, 0));
        !           528:                                        RecordException (lpDbgProcess, &de);
        !           529:                                        break;
        !           530: 
        !           531:                                    default:
        !           532:                                        SetStatusText (lpDbgProcess->hWnd,
        !           533:                                                       IDS_UNHANDLEDEXCEPTION,
        !           534:                                                       RGB (0xff, 0, 0));
        !           535:                                        RecordException (lpDbgProcess, &de);
        !           536:                                        break;
        !           537:                                    }
        !           538:                                break;
        !           539: 
        !           540:                            case RIP_EVENT:
        !           541:                                SetStatusText (lpDbgProcess->hWnd,
        !           542:                                               IDS_RIPEVENT,
        !           543:                                               RGB (0, 0xff, 0));
        !           544:                                break;
        !           545: 
        !           546:                            case OUTPUT_DEBUG_STRING_EVENT:
        !           547:                                SetStatusText (lpDbgProcess->hWnd,
        !           548:                                               IDS_OUTPUTDEBUGSTRING,
        !           549:                                               RGB (0, 0xff, 0));
        !           550:                                break;
        !           551: 
        !           552:                            default:
        !           553:                                break;
        !           554:                            }
        !           555:                        }
        !           556: 
        !           557:                    ContinueDebugEvent (de.dwProcessId, de.dwThreadId, DBG_CONTINUE);
        !           558:                    }
        !           559:                break;
        !           560:            }
        !           561: 
        !           562:        }
        !           563: 
        !           564:     return TRUE;
        !           565: }
        !           566: 
        !           567: 
        !           568: 
        !           569: 
        !           570: void WINAPI SuspendDebuggeeProcess (
        !           571:     DBGPROCESS   *lppr)
        !           572: {
        !           573:     DBGTHREAD   *lpth = (DBGTHREAD *)lppr->lpThreads;
        !           574: 
        !           575:     while (lpth)
        !           576:        {
        !           577:        SuspendThread (lpth->hThread);
        !           578:        lpth = (DBGTHREAD *)lpth->Next;
        !           579:        }
        !           580: 
        !           581:     /* inform user via status bar */
        !           582:     SetStatusText (lppr->hWnd, IDS_PROCESSSUSPENDED, RGB (0xff, 0, 0));
        !           583:     lppr->bActive = FALSE;
        !           584: }
        !           585: 
        !           586: 
        !           587: 
        !           588: 
        !           589: void WINAPI ResumeDebuggeeProcess (
        !           590:     DBGPROCESS   *lppr)
        !           591: {
        !           592:     DBGTHREAD   *lpth = (DBGTHREAD *)lppr->lpThreads;
        !           593: 
        !           594:     while (lpth)
        !           595:        {
        !           596:        ResumeThread (lpth->hThread);
        !           597:        lpth = (DBGTHREAD *)lpth->Next;
        !           598:        }
        !           599: 
        !           600:     /* inform user via status bar */
        !           601:     SetStatusText (lppr->hWnd, IDS_PROCESSRESUMED, RGB (0, 0xff, 0));
        !           602:     lppr->bActive = TRUE;
        !           603: }
        !           604: 
        !           605: 
        !           606: 
        !           607: 
        !           608: void WINAPI AddThreadNode (
        !           609:     DBGPROCESS               *lppr,
        !           610:     DWORD                    dwThreadID,
        !           611:     HANDLE                   hThread,
        !           612:     int                      nPriority,
        !           613:     LPTHREAD_START_ROUTINE    lpStart,
        !           614:     HANDLE                   hFile)
        !           615: {
        !           616:     DBGTHREAD   *lpth;
        !           617:     DBGTHREAD   *pNode = lppr->lpThreads;
        !           618: 
        !           619:     /* allocate thread node off heap */
        !           620:     lpth = (DBGTHREAD *)HeapAlloc (lppr->hDbgHeap, 0, sizeof (DBGTHREAD));
        !           621: 
        !           622:     /* initialize thread data */
        !           623:     lpth->lpStartAddress = lpStart;
        !           624:     lpth->nPriority = nPriority;
        !           625:     lpth->dwThreadID = dwThreadID;
        !           626:     lpth->hThread = hThread;
        !           627:     lpth->Next = NULL;
        !           628: 
        !           629:     /* retieve section names for executable module if file handle passed */
        !           630:     if (hFile)
        !           631:        {
        !           632:        RetrieveModuleName (lppr->szModule, hFile);
        !           633:        lppr->lpSection = NULL;
        !           634:        RetrieveSectionNames (lppr->hDbgHeap, hFile, &(lppr->lpSection));
        !           635:        }
        !           636: 
        !           637:     /* set linked list pointers */
        !           638:     while (pNode && pNode->Next)
        !           639:        pNode = (DBGTHREAD *)pNode->Next;
        !           640: 
        !           641:     if (!pNode)
        !           642:        lppr->lpThreads = lpth;
        !           643:     else
        !           644:        (DBGTHREAD *)pNode->Next = lpth;
        !           645: }
        !           646: 
        !           647: 
        !           648: 
        !           649: 
        !           650: void WINAPI RemoveThreadNode (
        !           651:     DBGPROCESS   *lppr,
        !           652:     DWORD        dwThreadID)
        !           653: {
        !           654:     DBGTHREAD   *pNode = lppr->lpThreads;
        !           655:     DBGTHREAD   *lpth;
        !           656: 
        !           657:     while (pNode->Next &&
        !           658:           ((DBGTHREAD *)(pNode->Next))->dwThreadID != dwThreadID)
        !           659:        pNode = (DBGTHREAD *)pNode->Next;
        !           660: 
        !           661:     if (pNode->Next)
        !           662:        {
        !           663:        lpth = (DBGTHREAD *)pNode->Next;
        !           664:        pNode->Next = ((DBGTHREAD *)(pNode->Next))->Next;
        !           665:        CloseHandle (lpth->hThread);
        !           666:        HeapFree (lppr->hDbgHeap, 0, (LPSTR)lpth);
        !           667:        }
        !           668: 
        !           669:     else if (pNode->dwThreadID == dwThreadID)
        !           670:        {
        !           671:        lpth = pNode;
        !           672:        lppr->lpThreads = NULL;
        !           673:        CloseHandle (lpth->hThread);
        !           674:        HeapFree (lppr->hDbgHeap, 0, (LPSTR)lpth);
        !           675:        }
        !           676: }
        !           677: 
        !           678: 
        !           679: 
        !           680: /* find a thread's handle based on thread ID */
        !           681: HANDLE WINAPI FindThreadHandle (
        !           682:     DBGPROCESS   *lppr,
        !           683:     DWORD        dwThreadId)
        !           684: {
        !           685:     DBGTHREAD   *pNode = lppr->lpThreads;
        !           686: 
        !           687:     while (pNode != NULL)
        !           688:        if (pNode->dwThreadID == dwThreadId)
        !           689:            return (pNode->hThread);
        !           690:     return NULL;
        !           691: }
        !           692: 
        !           693: 
        !           694: 
        !           695: 
        !           696: void WINAPI AddDllNode (
        !           697:     DBGPROCESS            *lppr,
        !           698:     LOAD_DLL_DEBUG_INFO    *lpdbgDll)
        !           699: {
        !           700:     DBGDLL    *lpdll;
        !           701:     DBGDLL    *pNode = lppr->lpDlls;
        !           702:     char      szImageName[MAX_PATH*2];
        !           703:     BOOL      bDummy;
        !           704: 
        !           705:     /* allocate Dll node off heap */
        !           706:     if ((lpdll = (DBGDLL *)HeapAlloc (lppr->hDbgHeap, 0, sizeof (DBGDLL))) == NULL)
        !           707:        ReportError (IDS_ERRHEAPALLOC);
        !           708: 
        !           709:     /* initialize Dll structure */
        !           710:     lpdll->hFile = lpdbgDll->hFile;
        !           711:     lpdll->lpBaseOfDll = lpdbgDll->lpBaseOfDll;
        !           712:     lpdll->dwDebugInfoFileOffset = lpdbgDll->dwDebugInfoFileOffset;
        !           713:     lpdll->nDebugInfoSize = lpdbgDll->nDebugInfoSize;
        !           714:     lpdll->fUnicode = lpdbgDll->fUnicode;
        !           715:     lpdll->Next = NULL;
        !           716:     lpdll->lpSection = NULL;
        !           717: 
        !           718:     /* if imagename is valid, copy locally */
        !           719:     if ((lpdbgDll->lpImageName != NULL) &&
        !           720:        (*(char **)(lpdbgDll->lpImageName)) != NULL)
        !           721:        {
        !           722:        /* if unicode, convert to ascii */
        !           723:        if (lpdbgDll->fUnicode)
        !           724:            {
        !           725:            if (!ReadProcessMemory (lppr->hProcess,
        !           726:                                    *(char **)(lpdbgDll->lpImageName),
        !           727:                                    szImageName,
        !           728:                                    MAX_PATH*2,
        !           729:                                    NULL))
        !           730:                ReportError (IDS_ERRREADPROCESSMEMORY);
        !           731:            else
        !           732:                WideCharToMultiByte (CP_ACP,
        !           733:                                     0,
        !           734:                                     (LPWSTR)szImageName,
        !           735:                                     -1,
        !           736:                                     lpdll->szImageName,
        !           737:                                     MAX_PATH,
        !           738:                                     NULL,
        !           739:                                     &bDummy);
        !           740:            }
        !           741:        else
        !           742:            {
        !           743:            if (!ReadProcessMemory (lppr->hProcess,
        !           744:                                    *(char **)(lpdbgDll->lpImageName),
        !           745:                                    lpdll->szImageName,
        !           746:                                    MAX_PATH,
        !           747:                                    NULL))
        !           748:                ReportError (IDS_ERRREADPROCESSMEMORY);
        !           749:            }
        !           750:        }
        !           751:     else
        !           752:        RetrieveModuleName (lpdll->szImageName, lpdbgDll->hFile);
        !           753: 
        !           754:     /* get section names for DLL */
        !           755:     RetrieveSectionNames (lppr->hDbgHeap, lpdbgDll->hFile, &(lpdll->lpSection));
        !           756: 
        !           757:     /* set linked list pointers */
        !           758:     while (pNode && pNode->Next)
        !           759:        pNode = (DBGDLL *)pNode->Next;
        !           760: 
        !           761:     if (!pNode)
        !           762:        lppr->lpDlls = lpdll;
        !           763:     else
        !           764:        (DBGDLL *)pNode->Next = lpdll;
        !           765: }
        !           766: 
        !           767: 
        !           768: 
        !           769: void WINAPI RemoveDllNode (
        !           770:     DBGPROCESS            *lppr,
        !           771:     LOAD_DLL_DEBUG_INFO    *lpdbgDll)
        !           772: {
        !           773:     DBGDLL       *pNode = lppr->lpDlls;
        !           774:     DBGDLL       *lpdll;
        !           775:     SECTIONINFO    *pSection, *pNext;
        !           776: 
        !           777:     while (pNode->Next &&
        !           778:           ((DBGDLL *)(pNode->Next))->lpBaseOfDll != lpdbgDll->lpBaseOfDll)
        !           779:        pNode = (DBGDLL *)pNode->Next;
        !           780: 
        !           781:     if (pNode->Next)
        !           782:        {
        !           783:        lpdll = (DBGDLL *)pNode->Next;
        !           784:        pNode->Next = ((DBGDLL *)(pNode->Next))->Next;
        !           785: 
        !           786:        pSection = pNext = lpdll->lpSection;
        !           787:        while (pNext)
        !           788:            {
        !           789:            pNext = (SECTIONINFO *)pSection->Next;
        !           790:            HeapFree (lppr->hDbgHeap, 0, (LPSTR)pSection);
        !           791:            pSection = pNext;
        !           792:            }
        !           793: 
        !           794:        HeapFree (lppr->hDbgHeap, 0, (LPSTR)lpdll);
        !           795:        }
        !           796: 
        !           797:     else if (pNode->lpBaseOfDll == lpdbgDll->lpBaseOfDll)
        !           798:        {
        !           799:        lpdll = pNode;
        !           800:        lppr->lpDlls = NULL;
        !           801: 
        !           802:        pSection = pNext = lpdll->lpSection;
        !           803:        while (pNext)
        !           804:            {
        !           805:            pNext = (SECTIONINFO *)pSection->Next;
        !           806:            HeapFree (lppr->hDbgHeap, 0, (LPSTR)pSection);
        !           807:            pSection = pNext;
        !           808:            }
        !           809: 
        !           810:        HeapFree (lppr->hDbgHeap, 0, (LPSTR)lpdll);
        !           811:        }
        !           812: }
        !           813: 
        !           814: 
        !           815: 
        !           816: void WINAPI RecordException (
        !           817:     DBGPROCESS    *lppr,
        !           818:     DEBUG_EVENT    *de)
        !           819: {
        !           820:     DBGEXCEPTREC    *lper;
        !           821:     DBGEXCEPTREC    *per = lppr->lpERs;
        !           822:     HANDLE         hThread;
        !           823:     int            i;
        !           824: 
        !           825:     /* allocate Dll node off heap */
        !           826:     if ((lper = (DBGEXCEPTREC *)HeapAlloc (lppr->hDbgHeap, 0, sizeof (DBGEXCEPTREC))) == NULL)
        !           827:        ReportError (IDS_ERRHEAPALLOC);
        !           828: 
        !           829:     /* initialize exception record structure */
        !           830:     lper->dwThreadId = de->dwThreadId;
        !           831:     lper->dwFirstChance = de->u.Exception.dwFirstChance;
        !           832:     lper->ExceptRecord.ExceptionCode = de->u.Exception.ExceptionRecord.ExceptionCode;
        !           833:     lper->ExceptRecord.ExceptionFlags = de->u.Exception.ExceptionRecord.ExceptionFlags;
        !           834:     lper->ExceptRecord.ExceptionRecord = NULL;
        !           835:     lper->ExceptRecord.ExceptionAddress = de->u.Exception.ExceptionRecord.ExceptionAddress;
        !           836:     lper->ExceptRecord.NumberParameters = de->u.Exception.ExceptionRecord.NumberParameters;
        !           837:     for (i=0; i<EXCEPTION_MAXIMUM_PARAMETERS; i++)
        !           838:        lper->ExceptRecord.ExceptionInformation[i] =
        !           839:           de->u.Exception.ExceptionRecord.ExceptionInformation[i];
        !           840: 
        !           841:     /* get exception thread handle */
        !           842:     hThread = FindThreadHandle (lppr, de->dwThreadId);
        !           843:     lper->Context.ContextFlags = CONTEXT_CONTROL;
        !           844:     GetThreadContext (hThread, &(lper->Context));
        !           845: 
        !           846:     /* set linked list pointers */
        !           847:     while (per && per->Next)
        !           848:        per = (DBGEXCEPTREC *)per->Next;
        !           849:     if (!per)
        !           850:        lppr->lpERs = lper;
        !           851:     else
        !           852:        (DBGEXCEPTREC *)per->Next = lper;
        !           853: }
        !           854: 
        !           855: 
        !           856: 
        !           857: #ifdef _MIPS_
        !           858: /* 
        !           859:  * MIPS must increment the FIR on a breakpoint 
        !           860:  * in order to fetch the next instruction
        !           861:  */
        !           862: 
        !           863: int WINAPI HandleMipsBreakPoint(
        !           864:     DBGPROCESS               *lppr,
        !           865:     DWORD                    dwThreadID
        !           866:     )
        !           867: {
        !           868:     CONTEXT   ThreadContext;
        !           869:     DBGTHREAD *pNode = lppr->lpThreads;
        !           870:     HANDLE    hThread;
        !           871: 
        !           872:     while (pNode && pNode->dwThreadID != dwThreadID)
        !           873:        pNode = (DBGTHREAD *)pNode->Next;
        !           874: 
        !           875:     if(!pNode)
        !           876:        return(0);
        !           877:     else
        !           878:        {
        !           879:         hThread = (HANDLE) pNode->hThread;
        !           880:        
        !           881:         ThreadContext.ContextFlags = CONTEXT_CONTROL;
        !           882:         if (!GetThreadContext (hThread, &ThreadContext))
        !           883:            {
        !           884:            ReportError (IDS_ERRGETTHREADCONTEXT);
        !           885:             return(0);
        !           886:            }
        !           887: 
        !           888:         ThreadContext.Fir += 4;
        !           889: 
        !           890:         if (!SetThreadContext (hThread, &ThreadContext))
        !           891:            {
        !           892:            ReportError (IDS_ERRSETTHREADCONTEXT);
        !           893:            return (0);
        !           894:            }
        !           895: 
        !           896:        return (1);
        !           897:        }
        !           898: }
        !           899: #endif /* _MIPS_ */
        !           900: 
        !           901: 
        !           902: 
        !           903: int   WINAPI WhereIsStack (
        !           904:     HANDLE       hThreadContext)
        !           905: {
        !           906:     CONTEXT                    ThreadContext;
        !           907: 
        !           908:     ThreadContext.ContextFlags = CONTEXT_CONTROL;
        !           909:     if (!GetThreadContext (hThreadContext, &ThreadContext))
        !           910:        ReportError (IDS_ERRGETTHREADCONTEXT);
        !           911: 
        !           912: #ifdef _X86_
        !           913:     return ThreadContext.Esp;
        !           914: #else /* _MIPS_ */
        !           915:     return ThreadContext.IntSp;
        !           916: #endif
        !           917: 
        !           918: }
        !           919: 
        !           920: 
        !           921: 
        !           922: /* function walks memory regions of process */
        !           923: int    WINAPI WalkProcess (
        !           924:     HANDLE    hChildProcess,
        !           925:     LPVOID    *lpWalk,
        !           926:     LPINT     *lpObjects)
        !           927: {
        !           928:     LPVMOBJECT   lpList;
        !           929:     LPVOID       lpMem = 0;
        !           930:     LPVOID       lpStack = 0;
        !           931:     int          nCnt, i;
        !           932: 
        !           933:     /* if pointer exists, reset to no commit */
        !           934:     if (*lpWalk)
        !           935:        {
        !           936:        if (!VirtualFree (*lpWalk, 0, MEM_DECOMMIT))
        !           937:            ReportError (IDS_ERRVIRTUALFREE);
        !           938:        }
        !           939: 
        !           940:     /* else perform initial reserve */
        !           941:     else
        !           942:        if ((*lpWalk = VirtualAlloc (NULL,
        !           943:                                     TOTALVMRESERVE,
        !           944:                                     MEM_RESERVE,
        !           945:                                     PAGE_NOACCESS)) == NULL)
        !           946:            ReportError (IDS_ERRVIRTUALALLOC);
        !           947: 
        !           948:     /* initialize list pointer to beginning of walker list */
        !           949:     lpList = (LPVMOBJECT)*lpWalk;
        !           950: 
        !           951:     /* walk process addresses */
        !           952:     while ((DWORD)lpMem < 0x7fff0000)
        !           953:        {
        !           954:        try  /* virtual memory exception handler automatically commits mem */
        !           955:            {
        !           956:            /* touch memory in VMOBJECT structure that exists after mbi field to trigger
        !           957:               access violation for a new page of memory.  Do this here since VirtualQueryEx
        !           958:               does not seem to generate exceptions, rather it just fails calls */
        !           959:            *lpList->szObjType = 0;
        !           960:            *lpList->szModule = 0;
        !           961:            *lpList->szSection = 0;
        !           962:            lpList->bNew = 0;
        !           963: 
        !           964:            VirtualQueryEx (hChildProcess,
        !           965:                            lpMem,
        !           966:                            &(lpList->mbi),
        !           967:                            sizeof (MEMORY_BASIC_INFORMATION));
        !           968: 
        !           969:            /* increment lpMem to next region of memory */
        !           970:            lpMem = (LPVOID)((DWORD)lpList->mbi.BaseAddress +
        !           971:                             (DWORD)lpList->mbi.RegionSize);
        !           972: 
        !           973:            lpList++;
        !           974:            }
        !           975: 
        !           976:        except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
        !           977:            {
        !           978:            /* commit next page of walker list memory */
        !           979:            if (((int)lpList + 4096) < (int)*lpWalk + TOTALVMRESERVE)
        !           980:                VirtualAlloc ((LPVOID)((int)lpList + sizeof (VMOBJECT)),
        !           981:                              4096,
        !           982:                              MEM_COMMIT,
        !           983:                              PAGE_READWRITE);
        !           984:            else
        !           985:                {
        !           986:                NotifyUser (NULL,
        !           987:                            IDS_ERROR,
        !           988:                            IDS_NOTENOUGHMEM,
        !           989:                            " reserved for Objects",
        !           990:                            MB_OK);
        !           991:                return 0;
        !           992:                }
        !           993:            }
        !           994:        }
        !           995: 
        !           996:     /* allocate objects index array */
        !           997:     if (*lpObjects)
        !           998:        LocalFree (*lpObjects);
        !           999:     nCnt = (((int)(LPVOID)lpList)-(int)*lpWalk)/sizeof (VMOBJECT);
        !          1000:     *lpObjects = LocalAlloc (LPTR, nCnt * sizeof (int));
        !          1001:     for (i=0; i<nCnt; i++)
        !          1002:        (*lpObjects)[i] = i;
        !          1003: 
        !          1004:     /* return number of item in list */
        !          1005:     return (nCnt);
        !          1006: }
        !          1007: 
        !          1008: 
        !          1009: 
        !          1010: 
        !          1011: void WINAPI AnalyzeProcess (
        !          1012:     DBGPROCESS   *lpDbgProcess,
        !          1013:     LPVMOBJECT   lpVMObject,
        !          1014:     int          nObjects)
        !          1015: {
        !          1016:     DBGTHREAD                  *pTh = lpDbgProcess->lpThreads;
        !          1017:     DBGDLL                     *pDll = lpDbgProcess->lpDlls;
        !          1018:     int                        nStack;
        !          1019:     int                        nThreadCnt = 0;
        !          1020:     char                       szNum[10];
        !          1021:     char                       szObjDesc[MAX_PATH];
        !          1022:     SECTIONINFO                 *pSection;
        !          1023:     int                        i;
        !          1024:     MEMORY_BASIC_INFORMATION   mbi;
        !          1025:     LPPROBE                    lpProbe;
        !          1026: 
        !          1027: 
        !          1028:     /* name default heap in process if available */
        !          1029:     if (lpProbe = RetrieveProbeData ())
        !          1030:        {
        !          1031:        VirtualQueryEx (lpDbgProcess->hProcess, (PVOID)lpProbe->hDefHeap, &mbi, sizeof (mbi));
        !          1032: 
        !          1033:        /* ignore invalid regions with a base region of 0 */
        !          1034:        if (mbi.AllocationBase)
        !          1035:            {
        !          1036:            /* find all objects with same base region */
        !          1037:            for (i=0; i<nObjects; i++)
        !          1038:                {
        !          1039:                if (lpVMObject[i].mbi.AllocationBase == mbi.AllocationBase)
        !          1040:                    {
        !          1041:                    strcpy (lpVMObject[i].szObjType, "heap");
        !          1042:                    strcpy (lpVMObject[i].szModule, "process default");
        !          1043:                    }
        !          1044:                }
        !          1045:            }
        !          1046:        }
        !          1047: 
        !          1048:     /* name stack object for each thread in process */
        !          1049:     while (pTh != NULL)
        !          1050:        {
        !          1051:        /* get stack location for thread */
        !          1052:        nStack = WhereIsStack (pTh->hThread);
        !          1053: 
        !          1054:        strcpy (szObjDesc, "Thread ");
        !          1055:        strcat (szObjDesc, itoa (nThreadCnt, szNum, 10));
        !          1056: 
        !          1057:        /* locate base region */
        !          1058:        VirtualQueryEx (lpDbgProcess->hProcess, (PVOID)nStack, &mbi, sizeof (mbi));
        !          1059: 
        !          1060:        /* ignore invalid regions with a base region of 0 */
        !          1061:        if (mbi.AllocationBase)
        !          1062:            {
        !          1063:            /* find all objects with same base region */
        !          1064:            for (i=0; i<nObjects; i++)
        !          1065:                {
        !          1066:                if (lpVMObject[i].mbi.AllocationBase == mbi.AllocationBase)
        !          1067:                    {
        !          1068:                    strcpy (lpVMObject[i].szObjType, "stack");
        !          1069:                    strcpy (lpVMObject[i].szModule, szObjDesc);
        !          1070:                    }
        !          1071:                }
        !          1072:            }
        !          1073: 
        !          1074:        /* locate and identify the guard page in each stack.
        !          1075:           The guard page is a single page of committed memory at the lower end of
        !          1076:           committed memory and immediately adjacent to the stack's reserved memory.
        !          1077:           If there is no more reserved stack space left, the guard page will be the
        !          1078:           last page of committed memory.  A stack cannot exist without a guard page.
        !          1079:           There will be at most three regions of memory in the stack: the actual stack
        !          1080:           space is committed, the guard page is committed and the remaining address
        !          1081:           space is marked reserved. */
        !          1082:        /* locate lowest region of stack, since objects array is not sorted until after
        !          1083:           this function, it is always in ascending address order :) */
        !          1084:        i=0;
        !          1085:        while (i<nObjects &&
        !          1086:               (int)lpVMObject[i].mbi.BaseAddress < nStack &&
        !          1087:               lpVMObject[i].mbi.AllocationBase != mbi.AllocationBase)
        !          1088:            i++;
        !          1089: 
        !          1090:        if (i<nObjects &&
        !          1091:            lpVMObject[i].mbi.AllocationBase == mbi.AllocationBase)
        !          1092:            {
        !          1093:            if (lpVMObject[i].mbi.State == MEM_RESERVE)
        !          1094:                i++;
        !          1095: 
        !          1096:            /* identify guard page in section field */
        !          1097:            strcpy (lpVMObject[i].szSection, "guard");
        !          1098:            }
        !          1099: 
        !          1100:        /* increment thread count */
        !          1101:        nThreadCnt++;
        !          1102: 
        !          1103:        /* increment list pointer */
        !          1104:        pTh = (DBGTHREAD *)pTh->Next;
        !          1105:        }
        !          1106: 
        !          1107:     /* name DLL objects in process */
        !          1108:     while (pDll != NULL)
        !          1109:        {
        !          1110:        /* locate dll base region */
        !          1111:        VirtualQueryEx (lpDbgProcess->hProcess, pDll->lpBaseOfDll, &mbi, sizeof (mbi));
        !          1112: 
        !          1113:        /* ignore invalid regions with a base region of 0 */
        !          1114:        if (mbi.AllocationBase)
        !          1115:            {
        !          1116:            /* find all objects with same base region */
        !          1117:            for (i=0; i<nObjects; i++)
        !          1118:                {
        !          1119:                if (lpVMObject[i].mbi.AllocationBase == mbi.AllocationBase)
        !          1120:                    {
        !          1121:                    strcpy (lpVMObject[i].szObjType, "dll");
        !          1122:                    strcpy (lpVMObject[i].szModule, pDll->szImageName);
        !          1123:                    }
        !          1124:                }
        !          1125:            }
        !          1126: 
        !          1127:        /* name dll sections */
        !          1128:        pSection = (SECTIONINFO *)pDll->lpSection;
        !          1129:        while (pSection != NULL)
        !          1130:            {
        !          1131:            i = 0;
        !          1132:            while (i++<nObjects)
        !          1133:                {
        !          1134:                if (lpVMObject[i].mbi.BaseAddress ==
        !          1135:                        ((char *)pDll->lpBaseOfDll + pSection->uVirtualAddress))
        !          1136:                    {
        !          1137:                    strcpy (lpVMObject[i].szSection, pSection->szSection);
        !          1138:                    break;
        !          1139:                    }
        !          1140:                }
        !          1141:            pSection = (SECTIONINFO *)pSection->Next;
        !          1142:            }
        !          1143: 
        !          1144:        /* increment list pointer */
        !          1145:        pDll = (DBGDLL *)pDll->Next;
        !          1146:        }
        !          1147: 
        !          1148:     /* locate exe base region */
        !          1149:     VirtualQueryEx (lpDbgProcess->hProcess, lpDbgProcess->lpImage, &mbi, sizeof (mbi));
        !          1150: 
        !          1151:     /* ignore invalid regions with a base region of 0 */
        !          1152:     if (mbi.AllocationBase)
        !          1153:        {
        !          1154:        /* find all objects with same base region */
        !          1155:        for (i=0; i<nObjects; i++)
        !          1156:            {
        !          1157:            if (lpVMObject[i].mbi.AllocationBase == mbi.AllocationBase)
        !          1158:                {
        !          1159:                strcpy (lpVMObject[i].szObjType, "exe");
        !          1160:                strcpy (lpVMObject[i].szModule, lpDbgProcess->szModule);
        !          1161:                }
        !          1162:            }
        !          1163:        }
        !          1164: 
        !          1165:     /* name exe sections */
        !          1166:     pSection = lpDbgProcess->lpSection;
        !          1167:     while (pSection != NULL)
        !          1168:        {
        !          1169:        i = 0;
        !          1170:        while (i++<nObjects)
        !          1171:            {
        !          1172:            if (lpVMObject[i].mbi.BaseAddress ==
        !          1173:                    ((char *)lpDbgProcess->lpImage + pSection->uVirtualAddress))
        !          1174:                {
        !          1175:                strcpy (lpVMObject[i].szSection, pSection->szSection);
        !          1176:                break;
        !          1177:                }
        !          1178:            }
        !          1179:        pSection = (SECTIONINFO *)pSection->Next;
        !          1180:        }
        !          1181: }
        !          1182: 
        !          1183: 
        !          1184: 
        !          1185: 
        !          1186: /* find all occurrances of objects having same base region */
        !          1187: void WINAPI NameObjects (
        !          1188:     HANDLE       hProcess,
        !          1189:     LPVOID       lpAddress,
        !          1190:     LPVMOBJECT   lpVMObj,
        !          1191:     int          nObjects,
        !          1192:     char         *lpszObjType,
        !          1193:     char         *lpszModule)
        !          1194: {
        !          1195:     int                        i;
        !          1196:     MEMORY_BASIC_INFORMATION   mbi;
        !          1197: 
        !          1198:     /* locate base region */
        !          1199:     VirtualQueryEx (hProcess, lpAddress, &mbi, sizeof (mbi));
        !          1200: 
        !          1201:     /* ignore invalid regions with a base region of 0 */
        !          1202:     if (!mbi.AllocationBase)
        !          1203:        return;
        !          1204: 
        !          1205:     /* find all objects with same base region */
        !          1206:     for (i=0; i<nObjects; i++)
        !          1207:        {
        !          1208:        if (lpVMObj[i].mbi.AllocationBase == mbi.AllocationBase)
        !          1209:            {
        !          1210:            strcpy (lpVMObj[i].szObjType, lpszObjType);
        !          1211:            strcpy (lpVMObj[i].szModule, lpszModule);
        !          1212:            }
        !          1213:        }
        !          1214: }
        !          1215: 
        !          1216: 
        !          1217: 
        !          1218: 
        !          1219: void WINAPI IdentifyNewObjects (
        !          1220:     LPVMOBJECT   lpVMObjectOld,
        !          1221:     int          nObjectsOld,
        !          1222:     LPVMOBJECT   lpVMObject,
        !          1223:     int          nObjects)
        !          1224: {
        !          1225:     int    i, j;
        !          1226: 
        !          1227:     for (i=0; i<nObjects; i++)
        !          1228:        {
        !          1229:        for (j=0; j<nObjectsOld; j++)
        !          1230:            {
        !          1231:            if (VMCompare (lpVMObject+i, lpVMObjectOld+j))
        !          1232:                goto NEXT;
        !          1233:            }
        !          1234: 
        !          1235:        /* if not found must be a new item */
        !          1236:        lpVMObject[i].bNew = TRUE;
        !          1237: NEXT:;
        !          1238:        }
        !          1239: }
        !          1240: 
        !          1241: 
        !          1242: BOOL WINAPI VMCompare (
        !          1243:     LPVMOBJECT   lpVM1,
        !          1244:     LPVMOBJECT   lpVM2)
        !          1245: {
        !          1246: 
        !          1247:     /* compare memory info */
        !          1248:     if (lpVM1->mbi.AllocationBase      != lpVM2->mbi.AllocationBase      ||
        !          1249:        lpVM1->mbi.BaseAddress         != lpVM2->mbi.BaseAddress          ||
        !          1250:        lpVM1->mbi.RegionSize          != lpVM2->mbi.RegionSize           ||
        !          1251:        lpVM1->mbi.Protect             != lpVM2->mbi.Protect              ||
        !          1252:        lpVM1->mbi.AllocationProtect   != lpVM2->mbi.AllocationProtect    ||
        !          1253:        lpVM1->mbi.State               != lpVM2->mbi.State                ||
        !          1254:        lpVM1->mbi.Type                != lpVM2->mbi.Type                    )
        !          1255:        return FALSE;
        !          1256: 
        !          1257:     /* compare character information */
        !          1258:     if (memcmp ((LPVOID)lpVM1->szObjType, (LPVOID)lpVM2->szObjType, 12) ||
        !          1259:        memcmp ((LPVOID)lpVM1->szSection,
        !          1260:                (LPVOID)lpVM2->szSection,
        !          1261:                IMAGE_SIZEOF_SHORT_NAME)                                ||
        !          1262:        memcmp ((LPVOID)lpVM1->szModule, (LPVOID)lpVM2->szModule, MAX_PATH))
        !          1263:        return FALSE;
        !          1264: 
        !          1265:     /* if still here, must be a match */
        !          1266:     return TRUE;
        !          1267: }
        !          1268: 
        !          1269: 
        !          1270: 
        !          1271: 
        !          1272: /* test to see if all memory objects in range are committed */
        !          1273: BOOL   WINAPI CommittedMemoryRange (
        !          1274:     int          i,
        !          1275:     int          j,
        !          1276:     LPVMOBJECT   lpvm,
        !          1277:     int          *Objects)
        !          1278: {
        !          1279:     int    k;
        !          1280: 
        !          1281:     /* test each memory object in range */
        !          1282:     for (k = min(i, j); k <= max (i, j); k++)
        !          1283:        /* report any non committed memory regions */
        !          1284:        if (lpvm[Objects[k]].mbi.State != MEM_COMMIT)
        !          1285:            return FALSE;
        !          1286: 
        !          1287:     /* report all committed range */
        !          1288:     return TRUE;
        !          1289: }
        !          1290: 
        !          1291: 
        !          1292: 
        !          1293: 
        !          1294: /* signal debugger thread to access process memory */
        !          1295: BOOL WINAPI AccessProcessMemory (
        !          1296:     HANDLE    hMemoryEvent,
        !          1297:     HANDLE    hAckEvent,
        !          1298:     LPVOID    lpAddress,
        !          1299:     LPVOID    lpBuffer,
        !          1300:     DWORD     *dwSize)
        !          1301: {
        !          1302:     DWORD    dwResult;
        !          1303: 
        !          1304:     /* copy data to module globals */
        !          1305:     PMAAddress = lpAddress;
        !          1306:     PMABuffer = lpBuffer;
        !          1307:     PMASize = *dwSize;
        !          1308: 
        !          1309:     /* signal debugger thread to read memory from process */
        !          1310:     SetEvent (hMemoryEvent);
        !          1311: 
        !          1312:     /* wait on debugger thread to signal completion of memory task */
        !          1313:     dwResult = WaitForSingleObject (hAckEvent, 100000);
        !          1314:     ResetEvent (hAckEvent);
        !          1315: 
        !          1316:     /* reset size accessed to verify operation */
        !          1317:     *dwSize = PMASize;
        !          1318: 
        !          1319:     return (dwResult == WAIT_OBJECT_0 &&
        !          1320:            PMASize != 0);
        !          1321: }
        !          1322: 
        !          1323: 
        !          1324: 
        !          1325: 
        !          1326: BOOL WINAPI InterruptThread_HookProcess (
        !          1327:     DBGPROCESS        *lpDbgProcess,
        !          1328:     LPPROCESS_STATE    lpState)
        !          1329: {
        !          1330:     DBGDLL                     *pDlls = lpDbgProcess->lpDlls;
        !          1331:     int                        nBytes, nLen, i;
        !          1332:     MEMORY_BASIC_INFORMATION   mbi;
        !          1333:     LPVOID                     lpLoadLibrary = NULL;
        !          1334:     char                       szKernel[] = "KERNEL32.DLL";
        !          1335:     char                       szFunction[] = "LoadLibraryA";
        !          1336:     BYTE                       pCode[PAGESIZE];
        !          1337:     BYTE                       pStack[PAGESIZE];
        !          1338:     HANDLE                     hDll;
        !          1339: 
        !          1340: 
        !          1341:     /* initialize stack and code pages */
        !          1342:     for (i=0; i<PAGESIZE; i++)
        !          1343:        {
        !          1344:        pStack[i] = 0;
        !          1345:        pCode[i] = 0;
        !          1346:        }
        !          1347: 
        !          1348:     /* find kernel32 Dll */
        !          1349:     while (pDlls != NULL)
        !          1350:        {
        !          1351:        if (!stricmp (pDlls->szImageName, szKernel))
        !          1352:            break;
        !          1353:        pDlls = (DBGDLL *)pDlls->Next;
        !          1354:        }
        !          1355: 
        !          1356:     /* if DLL not loaded abort */
        !          1357:     if (pDlls == NULL)
        !          1358:        return FALSE;
        !          1359: 
        !          1360:     /* load the dll in this process, find the function offset in this
        !          1361:        process and normalize to the offset in the child process */
        !          1362:     hDll = LoadLibrary (szKernel);
        !          1363:     lpLoadLibrary = GetProcAddress (hDll, szFunction);
        !          1364:     VirtualQuery (lpLoadLibrary, &mbi, sizeof (mbi));
        !          1365:     (int)lpLoadLibrary += ((int)pDlls->lpBaseOfDll - (int)mbi.AllocationBase);
        !          1366:     FreeLibrary (hDll);
        !          1367: 
        !          1368:     /* get thread context information and save for replacement */
        !          1369:     lpState->Context.ContextFlags = CONTEXT_FULL;
        !          1370:     if (!GetThreadContext (lpDbgProcess->lpThreads->hThread, &(lpState->Context)))
        !          1371:        return FALSE;
        !          1372: 
        !          1373: #ifdef _X86_
        !          1374:     lpState->Eip = (LPVOID)lpState->Context.Eip;
        !          1375:     lpState->Esp = (LPVOID)lpState->Context.Esp;
        !          1376: #else /* MIPS */
        !          1377:     lpState->Eip = (LPVOID)lpState->Context.Fir;
        !          1378:     lpState->Esp = (LPVOID)lpState->Context.IntSp;
        !          1379: #endif
        !          1380: 
        !          1381:     /* locate first writeable code page in exe module */
        !          1382:     lpState->pCodePage = lpDbgProcess->lpImage;
        !          1383:     VirtualQueryEx (lpDbgProcess->hProcess, lpState->pCodePage, &mbi, sizeof (mbi));
        !          1384:     while (!(mbi.Protect & PAGE_READWRITE) &&
        !          1385:           mbi.AllocationBase == lpDbgProcess->lpImage)
        !          1386:        {
        !          1387:        (int)lpState->pCodePage = (int)mbi.BaseAddress + mbi.RegionSize;
        !          1388:        VirtualQueryEx (lpDbgProcess->hProcess, lpState->pCodePage, &mbi, sizeof (mbi));
        !          1389:        }
        !          1390: 
        !          1391:     if (mbi.AllocationBase != lpDbgProcess->lpImage)
        !          1392:        return FALSE;
        !          1393: 
        !          1394:     /* save code page for reset process */
        !          1395:     ReadProcessMemory (lpDbgProcess->hProcess, lpState->pCodePage, lpState->Code, PAGESIZE, &nBytes);
        !          1396: 
        !          1397:     /* write DLL path to code page */
        !          1398:     strcpy ((char *)pCode, szCurPath);
        !          1399:     strcat ((char *)pCode, "\\probe.dll");
        !          1400:     nLen = strlen ((char *)pCode) + 1;
        !          1401: 
        !          1402:     /* find current stack page and save  */
        !          1403: 
        !          1404: #ifdef _X86_
        !          1405:     lpState->pStackPage = (LPVOID)((((int)lpState->Context.Esp)/PAGESIZE) * PAGESIZE);
        !          1406: #else /* MIPS */
        !          1407:     lpState->pStackPage = (LPVOID)((((int)lpState->Context.IntSp)/PAGESIZE) * PAGESIZE);
        !          1408: #endif
        !          1409: 
        !          1410:     ReadProcessMemory (lpDbgProcess->hProcess, lpState->pStackPage, lpState->Stack, PAGESIZE, &nBytes);
        !          1411: 
        !          1412:     /* push address of DLL string on stack */
        !          1413:     *((int *)(pStack+4092)) = (int)lpState->pCodePage;
        !          1414: 
        !          1415:     /* push return address on stack */
        !          1416:     *((int *)(pStack+4088)) = (int)lpState->pCodePage+nLen;
        !          1417: 
        !          1418:     /* return to Int 3 breakpoint instruction */
        !          1419:     pCode[nLen] = 0xCC;
        !          1420: 
        !          1421:     /* write new code and stack pages */
        !          1422:     WriteProcessMemory (lpDbgProcess->hProcess, lpState->pCodePage, pCode, PAGESIZE, &nBytes);
        !          1423:     WriteProcessMemory (lpDbgProcess->hProcess, lpState->pStackPage, pStack, PAGESIZE, &nBytes);
        !          1424: 
        !          1425:     /* update Eip to execute at actual LoadLibrary function */
        !          1426:     /* adjust stack pointer to point to return address */
        !          1427: 
        !          1428: #ifdef _X86_
        !          1429:     lpState->Context.Eip = (UINT)lpLoadLibrary;
        !          1430:     lpState->Context.Esp = (UINT)lpState->pStackPage+4088;
        !          1431: #else /* _MIPS_ */
        !          1432:     lpState->Context.Fir = (UINT)lpLoadLibrary;
        !          1433:     lpState->Context.IntSp = (UINT)lpState->pStackPage+4088;
        !          1434: #endif
        !          1435: 
        !          1436:     if (!SetThreadContext (lpDbgProcess->lpThreads->hThread, &(lpState->Context)))
        !          1437:        {
        !          1438:        ReportError (IDS_ERRSETTHREADCONTEXT);
        !          1439:        /* replace code and stack pages */
        !          1440:        WriteProcessMemory (lpDbgProcess->hProcess, lpState->pCodePage, lpState->Code, PAGESIZE, &nBytes);
        !          1441:        WriteProcessMemory (lpDbgProcess->hProcess, lpState->pStackPage, lpState->Stack, PAGESIZE, &nBytes);
        !          1442:        return FALSE;
        !          1443:        }
        !          1444: 
        !          1445:     return TRUE;
        !          1446: }
        !          1447: 
        !          1448: 
        !          1449: 
        !          1450: 
        !          1451: void WINAPI ResetInterruptedThread (
        !          1452:     DBGPROCESS        *lpDbgProcess,
        !          1453:     LPPROCESS_STATE    lpState)
        !          1454: {
        !          1455:     int    nBytes;
        !          1456: 
        !          1457:     /* return thread context information */
        !          1458: 
        !          1459: #ifdef _X86_
        !          1460:     lpState->Context.Eip = (UINT)lpState->Eip;
        !          1461:     lpState->Context.Esp = (UINT)lpState->Esp;
        !          1462: #else /* MIPS */
        !          1463:     lpState->Context.Fir = (UINT)lpState->Eip;
        !          1464:     lpState->Context.IntSp = (UINT)lpState->Esp;
        !          1465: #endif
        !          1466: 
        !          1467:     SetThreadContext (lpDbgProcess->lpThreads->hThread, &(lpState->Context));
        !          1468: 
        !          1469:     /* return code and stack information */
        !          1470:     WriteProcessMemory (lpDbgProcess->hProcess, lpState->pCodePage, lpState->Code, PAGESIZE, &nBytes);
        !          1471:     WriteProcessMemory (lpDbgProcess->hProcess, lpState->pStackPage, lpState->Stack, PAGESIZE, &nBytes);
        !          1472: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.