Beispiel #1
0
__inline VOID
SortFromBounds (
    WORD cbnds,
    LPBNDS rgbnds,
    WORD cv,
    LPV rgv,
    WORD cbv
    )
{
    LPV  lpv    = MHAlloc (cbv * cv);
    WORD ibnds  = 0;
    WORD iv     = 0;

    if (lpv == NULL) {
        return;
    }

    for (ibnds = 0; ibnds < cbnds; ibnds++) {
        WORD cvT = rgbnds [ ibnds ].ilnEnd - rgbnds [ ibnds ].ilnStart + 1;

        memcpy(((LPB) lpv) + (iv * cbv),
               ((LPB) rgv) + (rgbnds[ibnds].ilnStart * cbv),
               cvT * cbv);

        iv += cvT;
    }

    memcpy(rgv, lpv, cbv * cv);

    MHFree(lpv);
}
Beispiel #2
0
VOID
SHFree(
    LPV lpv
    )
{
    MHFree (lpv);
}
Beispiel #3
0
LOCAL HST
HstFromLpmds (
    LPMDS lpmds
    )
{
    if (lpmds->hst != NULL) {
        return lpmds->hst;
    } else if (lpmds->pmod) {
        // Allocate space for this module's line number information,
        // then load it from the PDB and sort it.

        if (!ModQueryLines(lpmds->pmod, 0, (CB *)&lpmds->cbhst) ||
            !(lpmds->cbhst) ||
            !(lpmds->hst = MHAlloc(lpmds->cbhst)))
            return 0;

        if (ModQueryLines(lpmds->pmod, (PB)lpmds->hst, (CB *)&lpmds->cbhst)) {
            SortSM((LPSM)lpmds->hst);
            return lpmds->hst;
        } else {
            MHFree(lpmds->hst);
            lpmds->hst = 0;
            return 0;
        }
    } else if (lpmds->ulhst == 0) {
        return NULL;
    } else {
        assert(FALSE);          // We should never hit this code now
                                //  that we're mapped.
        LPEXG lpexg = (LPEXG) LLLock (lpmds->hexg);
        HANDLE hfile = SYOpen (lpexg->lszDebug);
        HST   hst   = MHAlloc ((UINT) lpmds->cbhst);

        if (hfile == INVALID_HANDLE_VALUE || hst == NULL) {
            LLUnlock (lpmds->hexg);
            return NULL;
        }

        if (SYSeek(hfile, lpmds->ulhst, SEEK_SET) != (LONG) lpmds->ulhst) {
            assert(FALSE);
        }

        if (SYReadFar (hfile, (LPB) hst, (UINT) lpmds->cbhst) != lpmds->cbhst) {
            assert (FALSE);
        }

        SYClose (hfile);

        lpmds->hst = hst;

        LLUnlock (lpmds->hexg);

        SortSM ((LPSM)hst);

        return hst;
    }
}
Beispiel #4
0
__inline VOID
SortSL (
    LPSL lpsl
    )
{
    WORD   coff      = lpsl->cLnOff;
    LPUL   rgoff     = lpsl->offset;
    LPW    rgln      = (LPW) &lpsl->offset [ coff ];
    WORD   cbnds     = 0;
    LPBNDS rgbnds    = NULL;

    rgbnds = BuildBounds (coff, rgoff, &cbnds);
    if (rgbnds != NULL) {
        SortOffFromBounds (cbnds, rgbnds, coff, rgoff);
        SortLnFromBounds  (cbnds, rgbnds, coff, rgln );

        MHFree (rgbnds);
    }
}
Beispiel #5
0
int
WINAPI
SLCAddrFromLine (
    HEXE        hexeStart,
    HMOD        hmodStart,
    LSZ         lszFileT,
    WORD        line,
    LPSLP      *lplpslp
    )
{
    LPSLP   lpslp = (LPSLP)NULL;
    int     cslp = 0;
    HMOD    hmod = hmodStart;
    HEXE    hexe = hexeStart;
    int     iPass;
    char    szFileBuf[_MAX_PATH];
    LPSTR   lszFile;

    assert(lplpslp);
    assert(lszFileT);
    assert(*lszFileT != '\0');

    // If the filename is quoted, remove the quotes.
    if ((*lszFileT == '\"') && (*(lszFileT + _tcslen(lszFileT) - 1) == '\"')) {
        lszFile = szFileBuf;
        memcpy(lszFile, _tcsinc(lszFileT), _tcslen(lszFileT) - 2);
        lszFile[_tcslen(lszFileT)-2] = '\0';
    } else {
        lszFile = lszFileT;
    }

    if ((SlCache.cslp != -1) &&
        (hexeStart == SlCache.hexe) &&
        (hmodStart == SlCache.hmod) &&
        (line      == SlCache.line) &&
        (!_tcscmp(lszFile, SlCache.szFile)))
    {
        if ((SlCache.cslp == 0) ||
            !(lpslp = (LPSLP)MHAlloc(sizeof(SLP) * (SlCache.cslp))))
        {
            *lplpslp = NULL;
            return 0;
        }

        assert(SlCache.lpslp != NULL);

        memcpy(lpslp, SlCache.lpslp, sizeof(SLP) * SlCache.cslp);
        *lplpslp = lpslp;
        return SlCache.cslp;
    }

    // Two passes, first pass, see if there is an exact match.  If there aren't
    // any exact matches, try to match just the file.ext name.  When OMF file
    // names are fully qualified, we should expect to always find a match on
    // the first pass.  This will help out with the case where there are two
    // different file.ext's in the exes/dlls loaded.
    for(iPass = 0; iPass < 2 && !lpslp; ++iPass) {

        // Loop through all of the exes that we know about.  We may want
        // to change this later
        while(hexeStart || (hexe = SHGetNextExe(hexe))) {

            // Extra fast scan to see if the file is in the list of files for the exe
            if (SLFFileInHexe(hexe, (BOOL)!iPass, lszFile)) {

                while(hmodStart || (hmod = SHGetNextMod(hexe, hmod))) {
                    LPMDS   lpmds = (LPMDS) hmod;
                    short   isf;
                    short   isfNext = -1;

                    do {
                        isf = isfNext + 1;

                        // Search for the filename in the current module
                        isfNext = IsfFromName((BOOL)!iPass, isf, lszFile, lpmds);

                        if (isfNext != -1) {
                            HSF     hsf;
                            SHOFF   cb;
                            ADDR    addr;
                            WORD    iSeg = 0;
                            WORD    iEntry = 0;

                            hsf = (HSF)GetLpsfFromIndex(
                                (LPSM) HstFromLpmds(lpmds),
                                isfNext
                           );

                            // Reuse the original version.  Since we have gotten our
                            // own hsf, we know that we will get the correct line
                            // number table
                            while(SLFLineToAddrExtended(hsf,
                                                          line,
                                                          &iSeg,
                                                          &iEntry,
                                                          &addr,
                                                          &cb,
                                                          NULL))
                            {
                                // This could be smarter to allocate blocks, but the
                                // regular case will be that this will only happen
                                // once rather than multiple times, so just eat up
                                // a little CPU for simplicity
                                if (lpslp) {
                                    lpslp = (LPSLP)MHRealloc(lpslp,
                                                    sizeof(SLP) * (cslp + 1));
                                }
                                else {
                                    lpslp = (LPSLP)MHAlloc(sizeof(SLP));
                                }

                                // Additional check to see that the allocation
                                // actually succeeded before copying the data
                                if (lpslp) {
                                    lpslp[ cslp ].cb = cb;
                                    lpslp[ cslp ].addr = addr;
                                    ++cslp;
                                }
                            }
                        }
                    } while(isfNext != -1);

                    // If a module is specified, then DON'T loop through the rest of
                    // the modules
                    if (hmodStart) {
                        break;
                    }
                }
            }

            // If a module is specified, DON'T loop through any of the remaining
            // modules or exes.  Also, if an exe is specified, don't go through
            // any mor exes either
            if (hmodStart || hexeStart) {
                break;
            }
        }
    }

    *lplpslp = lpslp;

    // Only free up if we need to
    if (SlCache.cslp < cslp) {
        if (SlCache.lpslp) {
            MHFree(SlCache.lpslp);
        }
        SlCache.lpslp = (LPSLP)MHAlloc(sizeof(SLP) * cslp);

        if (SlCache.lpslp == NULL) {
            return(0);
        }
    }

    if (cslp) {
        memcpy(SlCache.lpslp, lpslp, sizeof(SLP) * cslp);
    }

    _tcscpy(SlCache.szFile, lszFile);
    SlCache.hexe = hexeStart;
    SlCache.hmod = hmodStart;
    SlCache.line = line;
    SlCache.cslp = cslp;

    return cslp;
}
Beispiel #6
0
void
ProcessSegmentLoadEvent(
    DEBUG_EVENT64 * pde,
    HTHDX           hthdx
    )

/*++

Routine Description:

    This function takes care of dealing with segment load events from
    the wow system.  These come in as exceptions and are translated
    to segment load events in ProcessDebugEvent.

Arguments:

    pde         - Supplies a pointer to the modified debug event

    hthdx       - Supplies the handle to the thread of the debug event

Return Value:

    None.

--*/

{
#if defined(i386) && !defined(WIN32S)

    PDWORDLONG  lpdw = &pde->u.Exception.ExceptionRecord.ExceptionInformation[0];
    int         mode = LOWORD( (DWORD)lpdw[0] );
    int         cb;
    int         cbRead;
    int         b;
    char *      lpb;
    WORD        packetType = tlfDebugPacket;
    HEMI        hemi;
    HPRCX       hprcx = hthdx->hprc;
    int         idx;
    SEGMENT_NOTE        sn;
    ADDR                addr;
    EXPECTED_EVENT *    pee;
    DWORD       eventCode;
    DWORD       subClass;
    LDT_ENTRY   ldt;
    BREAKPOINT *bp;


    DeWow = *pde;

    if ( !FVDMInitDone ) {
        HANDLE  hmodVDM;

        hmodVDM = LoadLibrary("VDMDBG.DLL");

        if ( hmodVDM != (HANDLE)NULL ) {
            FVDMActive = TRUE;

            pfnVDMProcessException = (VDMPROCESSEXCEPTIONPROC)
                GetProcAddress( hmodVDM, "VDMProcessException" );
            pfnVDMGetPointer = (VDMGETPOINTERPROC)
                GetProcAddress( hmodVDM, "VDMGetPointer" );
            pfnVDMGetThreadSelectorEntry = (VDMGETTHREADSELECTORENTRYPROC)
                GetProcAddress( hmodVDM, "VDMGetThreadSelectorEntry" );
            pfnVDMGetThreadContext = (VDMGETCONTEXTPROC)
                GetProcAddress( hmodVDM, "VDMGetContext" );
            pfnVDMSetThreadContext = (VDMSETCONTEXTPROC)
                GetProcAddress( hmodVDM, "VDMSetContext" );
            pfnVDMGetSelectorModule = (VDMGETSELECTORMODULEPROC)
                GetProcAddress( hmodVDM, "VDMGetSelectorModule" );
            pfnVDMEnumProcessWOW = (VDMENUMPROCESSWOWPROC)
                GetProcAddress( hmodVDM, "VDMEnumProcessWOW" );

        } else {
            DMPrintShellMsg( _T("LoadLibrary(VDMDBG.DLL) failed\n"));
        }
        FVDMInitDone = TRUE;
    }
    if ( !FVDMActive ) {
        return;
    } else {
        DebugEvent64To32(pde, &DeWow32);
        (*pfnVDMProcessException)((LPDEBUG_EVENT)&DeWow32);
        DebugEvent32To64(&DeWow32, pde);
    }

    hthdx->fWowEvent   = TRUE;

    switch ( mode ) {
        /*
         *   SEG LOAD:
         *
         *      LOWORD(lpdw[0]) --- DBG_SEGLOAD
         *      HIWORD(lpdw[0]) --- Unused
         *      LOWORD(lpdw[1]) --- Unused
         *      HIWORD(lpdw[1]) --- Unused
         *      lpdw[2]         --- pointer to SEGMENT_NOTE structure
         *      lpdw[3]         --- Reserved
         */

    case DBG_SEGLOAD:
        lpb = (char *) lpdw[2];
        b = DbgReadMemory(hprcx, (UINT_PTR)lpb, &sn, sizeof(sn), &cbRead);

        if ((b == 0) || (cbRead != sizeof(sn))) {
            b = GetLastError();
            AddQueue( QT_CONTINUE_DEBUG_EVENT,
                      hthdx->hprc->pid,
                      hthdx->tid,
                      DBG_CONTINUE,
                      0);
            //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second);
            //hthdx->tstate |= ts_running;
			hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second));
			hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running));
            return;
        }

        if (sn.FileName[0] == 0) {
            AddQueue( QT_CONTINUE_DEBUG_EVENT,
                      hthdx->hprc->pid,
                      hthdx->tid,
                      DBG_CONTINUE,
                      0);
            //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second);
            //hthdx->tstate |= ts_running;
			hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second));
			hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running));
            return;
        }
        cb = _tcslen(sn.FileName)+1;

        idx = LookupDllName(hprcx, sn.FileName);

        if ( idx != -1 ) {
            if (hprcx->rgDllList[idx].fReal) {
                //
                //  Changing from real to protected mode. We don't
                //  support this, so we'll throw away what we have
                //  and start from scratch.
                //
                WORD w = (WORD)idx;

                DMSendDebugPacket(dbceModFree16,
                                  hprcx->hpid,
                                  hthdx->htid,
                                  sizeof(WORD),
                                  &w
                                  );

                RemoveDllName( hprcx, idx );
                idx = -1;
            }
        }

        if (idx == -1) {

            LPMODULELOAD lpmdl;

            cb = cb + sizeof(MODULELOAD) + (sn.Segment+1)*sizeof(OBJD);

            lpmdl = (LPMODULELOAD) MHAlloc(cb);

            lpmdl->cobj = sn.Segment+1;

            lpmdl->rgobjd[sn.Segment].wSel = sn.Selector1;
            lpmdl->rgobjd[sn.Segment].cb = (DWORD) -1;
            lpmdl->rgobjd[sn.Segment].wPad = 1;

            lpmdl->mte = InsertDllName(hprcx, sn.FileName);
            _tcscpy((char *) &lpmdl->rgobjd[lpmdl->cobj], sn.FileName);

            lpmdl->fRealMode = FALSE;
            lpmdl->fFlatMode = FALSE;
            lpmdl->fOffset32 = FALSE;

            DMSendRequestReply(dbcModLoad,
                               hprcx->hpid,
                               hthdx->htid,
                               cb,
                               lpmdl,
                               sizeof(HEMI),
                               &hemi
                               );

            hemi = *((HEMI *) abEMReplyBuf);

            MHFree(lpmdl);

            AddQueue( QT_CONTINUE_DEBUG_EVENT,
                      hthdx->hprc->pid,
                      hthdx->tid,
                      DBG_CONTINUE,
                      0);
            //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second);
            //hthdx->tstate |= ts_running;
			hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second));
			hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running));

        } else {

            SLI       sli;

            sli.wSelector = sn.Selector1;
            sli.wSegNo = sn.Segment;
            sli.mte = idx;

            DMSendDebugPacket(dbceSegLoad,
                              hprcx->hpid,
                              hthdx->htid,
                              sizeof(SLI),
                              &sli
                              );
        }

        break;

        /*
         *   SEGMOVE:
         *
         *      This event will be triggered if a selector number
         *      is to be changed.
         *
         *      LOWORD( lpdw[0] ) - SEGMOVE
         *      LOWORD( lpdw[1] ) - old selector number
         *      HIWORD( lpdw[1] ) - new selector number
         */

    case DBG_SEGMOVE:

        lpb = (char *) lpdw[2];
        b = DbgReadMemory(hprcx, (UINT_PTR)lpb, &sn, sizeof(sn), &cbRead);

        if ((b == 0) || (cbRead != sizeof(sn))) {
            b = GetLastError();
            AddQueue( QT_CONTINUE_DEBUG_EVENT,
                      hthdx->hprc->pid,
                      hthdx->tid,
                      DBG_CONTINUE,
                      0);
            //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second);
            //hthdx->tstate |= ts_running;
			hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second));
			hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running));
            return;
        }

        if (sn.FileName[0] == 0) {
            AddQueue( QT_CONTINUE_DEBUG_EVENT,
                      hthdx->hprc->pid,
                      hthdx->tid,
                      DBG_CONTINUE,
                      0);
            //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second);
            //hthdx->tstate |= ts_running;
			hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second));
			hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running));
            return;
        }
        cb = _tcslen(sn.FileName)+1;

        idx = LookupDllName(hprcx, sn.FileName);

        if ( idx != -1 ) {
            SLI       sli;

            assert( sn.Selector1 == 0 );
            sli.wSelector = sn.Selector2;
            sli.wSegNo = sn.Segment;
            sli.mte = idx;

            DMSendDebugPacket(dbceSegMove,
                              hprcx->hpid,
                              hthdx->htid,
                              sizeof(SLI),
                              &sli
                              );
        }

        AddQueue( QT_CONTINUE_DEBUG_EVENT,
                  hthdx->hprc->pid,
                  hthdx->tid,
                  DBG_CONTINUE,
                  0);
        //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second);
        //hthdx->tstate |= ts_running;
		hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second));
		hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running));

        break;

        /*
         *   SEGFREE:
         *
         *      This event is triggered if a selector is freed
         *
         *      LOWORD( lpdw[0] ) - SEGFREE
         *      HIWORD( lpdw[0] ) - fBPRelease
         *      LOWORD( lpdw[1] ) - selector to be freed
         */

    case DBG_SEGFREE:

        AddQueue( QT_CONTINUE_DEBUG_EVENT,
                  hthdx->hprc->pid,
                  hthdx->tid,
                  DBG_CONTINUE,
                  0);
        //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second);
        //hthdx->tstate |= ts_running;

		hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second));
		hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running));
        break;

        /*
         *   MODLOAD:
         *
         *      This event is triggered when a new DLL is loaded
         *
         *      LOWORD( lpdw[0] ) - MODLOAD
         *      HIWORD( lpdw[0] ) - length of module name
         *      HIWORD( lpdw[1] ) - selector
         *      lpdw[2]           - address of module name
         *      lpdw[3]           - image length
         *
         */

    case DBG_MODLOAD:

        lpb = (char *) lpdw[2];
        b = DbgReadMemory(hprcx, (UINT_PTR)lpb, &sn, sizeof(sn), &cbRead);

        if ((b == 0) || (cbRead != sizeof(sn))) {
            b = GetLastError();
            AddQueue( QT_CONTINUE_DEBUG_EVENT,
                      hthdx->hprc->pid,
                      hthdx->tid,
                      DBG_CONTINUE,
                      0);
            //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second);
            //hthdx->tstate |= ts_running;
			hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second));
			hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running));
            return;
        }

        if (sn.FileName[0] == 0) {
            AddQueue( QT_CONTINUE_DEBUG_EVENT,
                      hthdx->hprc->pid,
                      hthdx->tid,
                      DBG_CONTINUE,
                      0);
            //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second);
            //hthdx->tstate |= ts_running;
			hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second));
			hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running));
            return;
        }

        cb = _tcslen(sn.FileName)+1;
        idx = LookupDllName(hprcx, sn.FileName);

        if (idx == -1) {
            LPMODULELOAD lpmdl;
            cb = cb + sizeof(MODULELOAD);

            lpmdl = (LPMODULELOAD) MHAlloc(cb);

            lpmdl->cobj = 0;

            lpmdl->mte = InsertDllName(hprcx, sn.FileName);

            idx = LookupDllName(hprcx, sn.FileName);

            if ( idx != -1 ) {
                hprcx->rgDllList[idx].fReal = TRUE;
            }

            _tcscpy((char *) &lpmdl->rgobjd[lpmdl->cobj], sn.FileName);

            lpmdl->StartingSegment = sn.Segment;

            lpmdl->fRealMode = TRUE;
            lpmdl->fFlatMode = FALSE;
            lpmdl->fOffset32 = FALSE;

            DMSendRequestReply(dbcModLoad,
                               hprcx->hpid,
                               hthdx->htid,
                               cb,
                               lpmdl,
                               sizeof(HEMI),
                               &hemi
                               );

            MHFree(lpmdl);
        }

        AddQueue( QT_CONTINUE_DEBUG_EVENT,
                  hthdx->hprc->pid,
                  hthdx->tid,
                  DBG_CONTINUE,
                  0);
        //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second);
        //hthdx->tstate |= ts_running;
		hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second));
		hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running));

        break;

        /*
         *   MODFREE:
         *
         *      This event is triggered when a DLL is unloaded
         *
         *      LOWORD( lpdw[0] ) - MODFREE
         */

    case DBG_MODFREE:
        lpb = (char *) lpdw[2];
        b = DbgReadMemory(hprcx, (UINT_PTR)lpb, &sn, sizeof(sn), &cbRead);

        if ((b == 0) || (cbRead != sizeof(sn))) {
            b = GetLastError();
            AddQueue( QT_CONTINUE_DEBUG_EVENT,
                      hthdx->hprc->pid,
                      hthdx->tid,
                      DBG_CONTINUE,
                      0);
            //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second);
            //hthdx->tstate |= ts_running;
			hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second));
			hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running));
            return;
        }

        if (sn.FileName[0] == 0) {
            AddQueue( QT_CONTINUE_DEBUG_EVENT,
                      hthdx->hprc->pid,
                      hthdx->tid,
                      DBG_CONTINUE,
                      0);
            //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second);
            //hthdx->tstate |= ts_running;
			hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second));
			hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running));
            return;
        }
        cb = _tcslen(sn.FileName)+1;

        idx = LookupDllName(hprcx, sn.FileName);

        if (idx != -1) {

            WORD w = (WORD)idx;

            DMSendDebugPacket(dbceModFree16,
                              hprcx->hpid,
                              hthdx->htid,
                              sizeof(WORD),
                              &w
                              );

            RemoveDllName( hprcx, idx );
        }

        AddQueue( QT_CONTINUE_DEBUG_EVENT,
                  hthdx->hprc->pid,
                  hthdx->tid,
                  DBG_CONTINUE,
                  0);
        //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second);
        //hthdx->tstate |= ts_running;

		hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second));
		hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running));
        break;

        /*
         *  Int 01h break;
         */

    case DBG_SINGLESTEP:
        hthdx->context.ContextFlags = VDMCONTEXT_FULL;
        (*pfnVDMGetThreadContext)(hthdx->hprc->rwHand, hthdx->rwHand, &hthdx->context);

        eventCode = EXCEPTION_DEBUG_EVENT;
        pde->dwDebugEventCode = EXCEPTION_DEBUG_EVENT;
        pde->u.Exception.ExceptionRecord.ExceptionCode = subClass =
            (DWORD)EXCEPTION_SINGLE_STEP;

        /*
         *  They are not clearing the trace bit
         */

        hthdx->context.EFlags &= ~TF_BIT_MASK;
        hthdx->fContextDirty = TRUE;

        AddrInit(&addr, 
                 0, 
                 (SEGMENT) hthdx->context.SegCs, 
                 SE32To64( hthdx->context.Eip ),
                 FALSE, 
                 FALSE, 
                 FALSE, 
                 FALSE
                 );

        bp = FindBP(hthdx->hprc, hthdx, bptpExec, (BPNS)-1, &addr, FALSE);

        if ( bp ) {
            SetBPFlag( hthdx, bp );
        }

        goto dispatch;

    case DBG_TASKSTART:
        hthdx->context.ContextFlags = VDMCONTEXT_FULL;
        (*pfnVDMGetThreadContext)(hthdx->hprc->rwHand, hthdx->rwHand, &hthdx->context);

        eventCode =
        pde->dwDebugEventCode = ENTRYPOINT_DEBUG_EVENT;

        goto dispatch;

    case DBG_TASKSTOP:
    case DBG_DLLSTART:
    case DBG_DLLSTOP:
    case DBG_ATTACH:
        AddQueue( QT_CONTINUE_DEBUG_EVENT,
                  hthdx->hprc->pid,
                  hthdx->tid,
                  DBG_CONTINUE,
                  0);
        hthdx->tstate &= ~(ts_stopped|ts_first|ts_second);
        hthdx->tstate |= ts_running;
        break;


        /*
         *   Int 03h break
         *
         *      LOWORD(lpdw[0])  --- BREAKPOINT
         *      HIWORD(lpdw[0])  --- Protect Mode
         */

    case DBG_BREAK:
        hthdx->context.ContextFlags = VDMCONTEXT_FULL;
        (*pfnVDMGetThreadContext)(hthdx->hprc->rwHand, hthdx->rwHand, &hthdx->context);

        Set_PC(hthdx, PC(hthdx) - 1);
        hthdx->fContextDirty = TRUE;

        eventCode = pde->dwDebugEventCode = BREAKPOINT_DEBUG_EVENT;

        // NOTENOTE --- jimsch -- assuming only 0xcc not 0xcd 0x3 breakpoints

        AddrInit(&addr, 
                 0, 
                 (SEGMENT) hthdx->context.SegCs, 
                 SE32To64( hthdx->context.Eip ),
                 FALSE, 
                 FALSE, 
                 FALSE, 
                 FALSE
                 );

        bp = FindBP(hthdx->hprc, hthdx, bptpExec, (BPNS)-1, &addr, FALSE);

        if ( bp && bp->isStep ) {

            eventCode             = EXCEPTION_DEBUG_EVENT;
            pde->dwDebugEventCode = EXCEPTION_DEBUG_EVENT;

            pde->u.Exception.ExceptionRecord.ExceptionCode =
                subClass = (DWORD)EXCEPTION_SINGLE_STEP;
                RemoveBP(bp);

        } else {

            if ( bp ) {
                SetBPFlag( hthdx, bp );
            }

            pde->u.Exception.ExceptionRecord.ExceptionCode =
                subClass = (DWORD)bp;
        }

        pde->u.Exception.ExceptionRecord.ExceptionAddress = PC(hthdx);

    dispatch:
        hthdx->fAddrIsReal = FALSE;
        hthdx->fAddrIsFlat = FALSE;

        DebugEvent64To32(pde, &DeWow32);
        if ((*pfnVDMGetThreadSelectorEntry)(&DeWow32,
                                            hthdx->rwHand,
                                            (WORD) hthdx->context.SegCs,
                                            &ldt)) {
            if (ldt.HighWord.Bits.Default_Big) {
                hthdx->fAddrOff32 = TRUE;
            } else {
                hthdx->fAddrOff32 = FALSE;
            }
        } else {
            hthdx->fAddrOff32 = FALSE;
        }

        /*
         *  Check if this debug event was expected
         */

        pee = PeeIsEventExpected(hthdx, eventCode, subClass, TRUE);

        /*
         * If it wasn't, run the standard handler with
         * notifications going to the execution model
         */

        assert((0 < eventCode) && (eventCode < MAX_EVENT_CODE));

        if (pee == NULL) {
            if ((hthdx != NULL) && (hthdx->tstate & ts_funceval)) {
                RgfnFuncEventDispatch[eventCode-EXCEPTION_DEBUG_EVENT](pde, hthdx);
            } else {
                DebugDispatchTable[eventCode-EXCEPTION_DEBUG_EVENT](pde,hthdx);
            }
            return;
        }


        /*
         *  If it was expected then call the action
         * function if one was specified
         */

        if (pee->action) {
            (pee->action)(pde, hthdx, 0, pee->lparam);
        }

        /*
         *  And call the notifier if one was specified
         */

        if (pee->notifier) {
            METHOD  *nm = pee->notifier;
            (nm->notifyFunction)(pde, hthdx, 0, nm->lparam);
        }

        free(pee);
        break;

#if 0  // why is this here??
    case DBG_DIVOVERFLOW:
        pde->dwDebugEventCode = 3;
        goto fault_occured;

    case DBG_INSTRFAULT:
        pde->dwDebugEventCode = 1;
        goto fault_occured;
#endif

    case DBG_DIVOVERFLOW:
    case DBG_INSTRFAULT:
    case DBG_GPFAULT:
        pde->dwDebugEventCode = EXCEPTION_DEBUG_EVENT;

#if 0  // why is this here??
    fault_occured:
#endif

        hthdx->context.ContextFlags = VDMCONTEXT_FULL;
        (*pfnVDMGetThreadContext)(hthdx->hprc->rwHand, hthdx->rwHand, &hthdx->context);
        pde->u.Exception.ExceptionRecord.ExceptionCode = 13;

        hthdx->fAddrIsReal = FALSE;
        hthdx->fAddrIsFlat = FALSE;

        DebugEvent64To32(pde, &DeWow32);
        if ((*pfnVDMGetThreadSelectorEntry)(&DeWow32, hthdx->rwHand,
                                      (WORD) hthdx->context.SegCs, &ldt)) {
            if (ldt.HighWord.Bits.Default_Big) {
                hthdx->fAddrOff32 = TRUE;
            } else {
                hthdx->fAddrOff32 = FALSE;
            }
        } else {
            hthdx->fAddrOff32 = FALSE;
        }

        ProcessExceptionEvent(pde, hthdx);
        break;

    default:
        AddQueue( QT_CONTINUE_DEBUG_EVENT,
                  hthdx->hprc->pid,
                  hthdx->tid,
                  DBG_CONTINUE,
                  0);
        hthdx->tstate &= ~(ts_stopped|ts_first|ts_second);
        hthdx->tstate |= ts_running;
        break;
    }
#endif // i386 && !Win32S
    return;
}                               /* ProcessSegmentLoadEvent() */
Beispiel #7
0
BOOL FExecTrojan(HTHDX pthd, TROJAN *ptrj, LPB rgbBuf, UINT cbBuf, CONTEXT *pcxt)
{
    BOOL    fOK = FALSE;
    CONTEXT cxtOld;
    int             i;
    UINT    ib = 0;
    LPB             lpbOld = NULL;
    BOOL    fRestoreBuf = FALSE;
    DWORD   cbGot;
    DEBUG_EVENT de;
    HPRCX   hprc = pthd->hprc;
    HTHDX   hthdCurr;
    
    
    
    // if we do a GetContext here on NT, the EIP points to one past the initial int 3
    // so we use the cached value instead
    cxtOld = pthd->context;
    
    if (IsChicago()) {
        //
        // On Chicago, we cannot write Trojans into the stack memory space,
        // because Chicago trashes that memory when we return control to
        // the debuggee.  So we instead try to write the Trojan to the
        // current EIP.  If that fails, we'll return FALSE.
        //        
        uoffTrjBase = pthd->context.Eip;
        lpbOld = (LPB)MHAlloc(cbBuf);
        if (!lpbOld) {
            goto end;
        }
        if (!ReadProcessMemory(pthd->hprc->rwHand, (LPCVOID)uoffTrjBase, lpbOld, cbBuf, &cbGot) || (cbGot!=cbBuf) ) {
            goto end;
        }
        fRestoreBuf = TRUE;
    } else {
        //
        // On NT, we'll write the Trojan into the stack memory space.
        // We'll readjust the stack pointer to point just before the
        // Trojan.
        //              Stack before writing Trojan:
        //              +-------------------------------------------------------+
        //              |                                     | user stack data |
        //              +-------------------------------------------------------+
        //                                                   esp
        //
        //              Stack after writing Trojan:
        //              +-------------------------------------------------------+
        //              |       stack used by trojan | trojan | user stack data |
        //              +-------------------------------------------------------+
        //                                          esp
        //
        
        // Round up to DWORD.
        pthd->context.Esp -= ((cbBuf + 3) / 4) * 4;
        uoffTrjBase = pthd->context.Eip = pthd->context.Esp;
    }
    
    clbl = clblref = 0;
    
    for (i=0; ptrj[i].pfn; ++i)
    {
        if (!ptrj[i].pfn(ptrj[i].lsz, rgbBuf, &ib))
            goto end;
    }
    
    assert(ib <= cbBuf);    // make sure we didn't overflow
    
    // Write the trojan code to remote memory
    if (!WriteProcessMemory(pthd->hprc->rwHand, (LPVOID)uoffTrjBase, rgbBuf, cbBuf, &cbGot) || (cbGot!=cbBuf)) {
        goto end;
    }
    
    // set the new EIP/ESP
    VERIFY(SetThreadContext( pthd->rwHand, &pthd->context ));
    
    // Freeze all threads except our one
    for (hthdCurr = hprc->hthdChild; hthdCurr != NULL; hthdCurr = hthdCurr->nextSibling) {
        if (hthdCurr != pthd) {
            if (SuspendThread(hthdCurr->rwHand) == -1L) {
                ; // Internal error;
            }
        }
    }
    
    // let the trojan run, will hit int 3 before sending create thread (we hope!!)
    VERIFY(ContinueDebugEvent(pthd->hprc->pid, pthd->tid, DBG_CONTINUE));
    if (!WaitForDebugEvent(&de, INFINITE)) {
        assert( !"WaitForDebugEvent failed during trojan" );
    } else {
        assert(de.dwDebugEventCode == EXCEPTION_DEBUG_EVENT);
        
        if (de.u.Exception.ExceptionRecord.ExceptionCode != EXCEPTION_BREAKPOINT) {
#if DEBUG
            // didn't hit the bp - get some other info to see what is going on
            CONTEXT cxt;
            DWORD ip;
            BYTE buf[20];
            GetThreadContext(pthd->rwHand, &pthd->context);
            ip = cxt.Eip;
            
            ReadProcessMemory( pthd->hprc->rwHand, (LPCVOID)(ip-10), buf, sizeof(buf), &cbGot );
#endif
            assert( !"Trojan code got unexpected event" );
        }
        
        // Get eax
        VERIFY(GetThreadContext(pthd->rwHand, &pthd->context));
        *pcxt = pthd->context;
    }
    
    /* Resume all threads except this one */
    for (hthdCurr = hprc->hthdChild; hthdCurr != NULL; hthdCurr = hthdCurr->nextSibling) {
        if (hthdCurr != pthd) {
            if (ResumeThread(hthdCurr->rwHand) == -1L) {
                assert(FALSE); // Internal error;
            }
        }
    }
    
    // Read back the new contents of the trojan to get return values etc
    if (!ReadProcessMemory(pthd->hprc->rwHand, (LPCVOID)uoffTrjBase, rgbBuf, cbBuf, &cbGot) || (cbGot!=cbBuf) ) {
        goto end;
    }
    
    fOK = TRUE;
    
end:
    
    // Restore old memory
    if (fRestoreBuf) {
        assert(lpbOld);
        VERIFY(WriteProcessMemory(pthd->hprc->rwHand, (LPVOID)uoffTrjBase, lpbOld, cbBuf, &cbGot) &&
            (cbGot == cbBuf));
    }
    
    // Restore old registers always (after memory in case context is stored there)
    pthd->context = cxtOld;
    VERIFY(SetThreadContext(pthd->rwHand, &pthd->context));
    
    if (lpbOld) {
        MHFree(lpbOld);
    }
    
    return fOK;
}