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

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);
1.1.1.2 ! root       16: int    WINAPI HandleRiscBreakPoint(DBGPROCESS *, DWORD);
1.1       root       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:
1.1.1.2 ! root      480: #ifndef _X86_                          /* Risc needs special handling here to reset breakpoint */
        !           481:                                        HandleRiscBreakPoint(lpDbgProcess, de.dwThreadId);
1.1       root      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: 
1.1.1.2 ! root      857: #ifndef _X86_
1.1       root      858: /* 
1.1.1.2 ! root      859:  * MIPS/ALPHA must increment the FIR on a breakpoint 
1.1       root      860:  * in order to fetch the next instruction
                    861:  */
                    862: 
1.1.1.2 ! root      863: int WINAPI HandleRiscBreakPoint(
1.1       root      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: }
1.1.1.2 ! root      899: #endif /* !_X86_ */
1.1       root      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_ */
1.1.1.2 ! root      915:     return (int) ThreadContext.IntSp;
1.1       root      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.