VirtualBox

Changeset 46108 in vbox


Ignore:
Timestamp:
May 15, 2013 7:22:38 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
85796
Message:

Got the NT4 ntfs.sys case working. Turned out to be some memory saving strategy applied to some images during early (?) loading.

Location:
trunk/src/VBox
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Debugger/DBGPlugInWinNt.cpp

    r46101 r46108  
    327327                return rc;
    328328
    329             /* Patch it? */
     329            /* Apply SizeOfImage patch? */
    330330            if (   pThis->offSizeOfImage != UINT32_MAX
    331331                && offFile            < pThis->offSizeOfImage + 4
     
    333333            {
    334334                uint32_t SizeOfImage = pThis->cbCorrectImageSize;
     335                uint32_t cbPatch     = sizeof(SizeOfImage);
    335336                int32_t  offPatch    = pThis->offSizeOfImage - offFile;
    336337                uint8_t *pbPatch     = (uint8_t *)pvBuf + offPatch;
    337                 uint32_t cbPatch     = sizeof(uint32_t);
    338338                if (offFile + cbToRead < pThis->offSizeOfImage + cbPatch)
    339339                    cbPatch = offFile + cbToRead - pThis->offSizeOfImage;
     
    397397 * @param   paShs               Pointer to the section headers.
    398398 * @param   cShs                Number of headers.
    399  * @param   cbImage             The image size.
    400  */
    401 static bool dbgDiggerWinNtIsSectionHeaderOk(PCIMAGE_SECTION_HEADER paShs, uint32_t cShs, uint32_t cbImage)
    402 {
     399 * @param   cbImage             The image size reported by NT.
     400 * @param   uRvaRsrc            The RVA of the resource directory. UINT32_MAX if
     401 *                              no resource directory.
     402 * @param   cbSectAlign         The section alignment specified in the header.
     403 * @param   pcbImageCorrect     The corrected image size.  This is derived from
     404 *                              cbImage and virtual range of the section tables.
     405 *
     406 *                              The problem is that NT may choose to drop the
     407 *                              last pages in images it loads early, starting at
     408 *                              the resource directory.  These images will have
     409 *                              a page aligned cbImage.
     410 */
     411static bool dbgDiggerWinNtCheckSectHdrsAndImgSize(PCIMAGE_SECTION_HEADER paShs, uint32_t cShs, uint32_t cbImage,
     412                                                  uint32_t uRvaRsrc, uint32_t cbSectAlign, uint32_t *pcbImageCorrect)
     413{
     414    *pcbImageCorrect = cbImage;
     415
    403416    for (uint32_t i = 0; i < cShs; i++)
    404417    {
     
    411424        if (paShs[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)
    412425            continue;
    413         if (paShs[i].VirtualAddress >= cbImage)
    414         {
    415             Log(("DigWinNt: Section header #%u has a virtual address beyond the image: %#x cbImage=%#x\n",
    416                  i, paShs[i].VirtualAddress, cbImage));
     426
     427        /* Check that sizes are within the same range and that both sizes and
     428           addresses are within reasonable limits. */
     429        if (   RT_ALIGN(paShs[i].Misc.VirtualSize, _64K) > RT_ALIGN(paShs[i].SizeOfRawData, _64K)
     430            || paShs[i].Misc.VirtualSize >= _1G
     431            || paShs[i].SizeOfRawData    >= _1G)
     432        {
     433            Log(("DigWinNt: Section header #%u has a VirtualSize=%#x and SizeOfRawData=%#x, that's too much data!\n",
     434                 i, paShs[i].Misc.VirtualSize, paShs[i].SizeOfRawData));
    417435            return false;
    418436        }
    419         if (paShs[i].Misc.VirtualSize >= cbImage) /* we don't check too strictly here becuase NT4 SP1 ntfs.sys. */
    420         {
    421             Log(("DigWinNt: Section header #%u has a end beyond the image: VirtualAddress=%#x VirtualSize=%#x cbImage=%#x\n",
    422                  i, paShs[i].VirtualAddress, paShs[i].Misc.VirtualSize, cbImage));
     437        uint32_t uRvaEnd = paShs[i].VirtualAddress + paShs[i].Misc.VirtualSize;
     438        if (uRvaEnd >= _1G || uRvaEnd < paShs[i].VirtualAddress)
     439        {
     440            Log(("DigWinNt: Section header #%u has a VirtualSize=%#x and VirtualAddr=%#x, %#x in total, that's too much!\n",
     441                 i, paShs[i].Misc.VirtualSize, paShs[i].VirtualAddress, uRvaEnd));
    423442            return false;
    424443        }
    425     }
     444
     445        /* Check for images chopped off around '.rsrc'. */
     446        if (    cbImage < uRvaEnd
     447            &&  uRvaEnd >= uRvaRsrc)
     448            cbImage = RT_ALIGN(uRvaEnd, cbSectAlign);
     449
     450        /* Check that the section is within the image. */
     451        if (uRvaEnd > cbImage)
     452        {
     453            Log(("DigWinNt: Section header #%u has a virtual address range beyond the image: %#x TO %#x cbImage=%#x\n",
     454                 i, paShs[i].VirtualAddress, uRvaEnd, cbImage));
     455            return false;
     456        }
     457    }
     458
     459    Assert(*pcbImageCorrect == cbImage || !(*pcbImageCorrect & 0xfff));
     460    *pcbImageCorrect = cbImage;
    426461    return true;
    427462}
     
    455490     * image if it's in the buffer (it should be).
    456491     */
     492    uint32_t uRvaRsrc = UINT32_MAX;
     493    if (WINNT_UNION(pThis, pHdrs, OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]).Size > 0)
     494        uRvaRsrc = WINNT_UNION(pThis, pHdrs, OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]).VirtualAddress;
    457495    uint32_t offShs = offHdrs
    458496                    + (  pThis->f32Bit
     
    462500    PCIMAGE_SECTION_HEADER paShs = (PCIMAGE_SECTION_HEADER)(pbBuf + offShs);
    463501    if (   offShs + cbShs <= RT_MIN(cbImage, cbBuf)
    464         && dbgDiggerWinNtIsSectionHeaderOk(paShs, cShs, cbImage))
     502        && dbgDiggerWinNtCheckSectHdrsAndImgSize(paShs, cShs, cbImage, uRvaRsrc,
     503                                                 WINNT_UNION(pThis, pHdrs, OptionalHeader.SectionAlignment),
     504                                                 &pRdr->cbCorrectImageSize))
    465505    {
    466506        pRdr->cMappings = 0;
     
    514554    }
    515555
     556    /* Enable the SizeOfImage patching if necessary. */
     557    if (pRdr->cbCorrectImageSize != cbImage)
     558    {
     559        Log(("DigWinNT: The image is really %#x bytes long, not %#x as mapped by NT!\n", pRdr->cbCorrectImageSize, cbImage));
     560        pRdr->offSizeOfImage = pThis->f32Bit
     561                             ? offHdrs + RT_OFFSETOF(IMAGE_NT_HEADERS32, OptionalHeader.SizeOfImage)
     562                             : offHdrs + RT_OFFSETOF(IMAGE_NT_HEADERS64, OptionalHeader.SizeOfImage);
     563    }
     564
    516565    /*
    517566     * Call the loader to open the PE image for debugging.
     
    629678        return;
    630679    }
    631 
    632680
    633681    /*
  • trunk/src/VBox/Runtime/common/dbg/dbgcfg.cpp

    r46078 r46108  
    864864                memcpy(pszPath, pchCache, cchCache);
    865865                pszPath[cchCache] = '\0';
     866                RTPathChangeToUnixSlashes(pszPath, false);
     867
    866868                rcCache = rc2 = rtDbgCfgTryOpenCache(pThis, pszPath, pszCacheSubDir, pSplitFn, fFlags,
    867869                                                     pfnCallback, pvUser1, pvUser2);
     
    875877                memcpy(pszPath, pchCache, cchCache);
    876878                pszPath[cchCache] = '\0';
     879                RTPathChangeToUnixSlashes(pszPath, false);
     880
    877881                rc2 = rtDbgCfgTryDownloadAndOpen(pThis, pszServer, pszPath, pszCacheSubDir, pSplitFn, fFlags,
    878882                                                 pfnCallback, pvUser1, pvUser2);
     
    895899            memcpy(pszPath, pchCache, cchCache);
    896900            pszPath[cchCache] = '\0';
     901            RTPathChangeToUnixSlashes(pszPath, false);
     902
    897903            rcCache = rc2 = rtDbgCfgTryOpenCache(pThis, pszPath, pszCacheSubDir, pSplitFn, fFlags,
    898904                                                 pfnCallback, pvUser1, pvUser2);
     
    923929            memcpy(pszPath, pszDir, cchDir);
    924930            pszPath[cchDir] = '\0';
     931            RTPathChangeToUnixSlashes(pszPath, false);
    925932
    926933            rc2 = rtDbgCfgTryOpenDir(pThis, pszPath, pSplitFn, fFlagsDir, pfnCallback, pvUser1, pvUser2);
     
    10041011        rc2 = RTPathSplitReassemble(pSplitFn, RTPATH_STR_F_STYLE_HOST, szPath, sizeof(szPath));
    10051012        if (RT_SUCCESS(rc2) && RTFileExists(szPath))
     1013        {
     1014            RTPathChangeToUnixSlashes(szPath, false);
     1015            rtDbgCfgLog1(pThis, "Trying '%s'...\n", szPath);
    10061016            rc2 = pfnCallback(pThis, pszFilename, pvUser1, pvUser2);
     1017            if (rc2 == VINF_CALLBACK_RETURN)
     1018                rtDbgCfgLog1(pThis, "Found '%s'.\n", szPath);
     1019            else if (rc2 == VERR_CALLBACK_RETURN)
     1020                rtDbgCfgLog1(pThis, "Error opening '%s'.\n", szPath);
     1021            else
     1022                rtDbgCfgLog1(pThis, "Error %Rrc opening '%s'.\n", rc2, szPath);
     1023        }
    10071024    }
    10081025    if (   rc2 != VINF_CALLBACK_RETURN
     
    10161033        if (RT_FAILURE(rc2))
    10171034            strcpy(szPath, ".");
     1035        RTPathChangeToUnixSlashes(szPath, false);
     1036
    10181037        rc2 = rtDbgCfgTryOpenDir(pThis, szPath, pSplitFn, fFlags, pfnCallback, pvUser1, pvUser2);
    10191038        if (RT_FAILURE(rc2) && RT_SUCCESS_NP(rcRet))
  • trunk/src/VBox/Runtime/common/dbg/dbgmod.cpp

    r46106 r46108  
    971971    if (RT_SUCCESS(rc))
    972972    {
    973         pDbgMod->pszName = RTStrCacheEnter(g_hDbgModStrCache, pszName);
     973        pDbgMod->pszName = RTStrCacheEnterLower(g_hDbgModStrCache, pszName);
    974974        if (pDbgMod->pszName)
    975975        {
  • trunk/src/VBox/Runtime/common/dbg/dbgmoddbghelp.cpp

    r46078 r46108  
    213213{
    214214    RTDBGMODBGHELPARGS *pArgs  = (RTDBGMODBGHELPARGS *)pvUser;
     215
     216    if (pLineInfo->Address < pArgs->uModAddr)
     217    {
     218        Log((" %#018x %05u  %s  [SKIPPED - INVALID ADDRESS!]\n", pLineInfo->Address, pLineInfo->LineNumber));
     219        return TRUE;
     220    }
    215221
    216222    /*
     
    304310{
    305311    RTDBGMODBGHELPARGS *pArgs = (RTDBGMODBGHELPARGS *)pvUser;
     312    if (pSymInfo->Address < pArgs->uModAddr) /* NT4 SP1 ntfs.dbg */
     313    {
     314        Log(("  %#018x LB %#07x  %s  [SKIPPED - INVALID ADDRESS!]\n", pSymInfo->Address, cbSymbol, pSymInfo->Name));
     315        return TRUE;
     316    }
    306317
    307318    int rc = RTDbgModSymbolAdd(pArgs->hCnt, pSymInfo->Name, RTDBGSEGIDX_RVA,
  • trunk/src/VBox/Runtime/common/ldr/ldrPE.cpp

    r46101 r46108  
    17301730            return VERR_BAD_EXE_FORMAT;
    17311731        }
    1732         if (    pDir->Size > cb - pDir->VirtualAddress
    1733             && !(fFlags & RTLDR_O_FOR_DEBUG) /* NT4 SP1 ntfs.sys base relocs. */ )
     1732        if (pDir->Size > cb - pDir->VirtualAddress)
    17341733        {
    17351734            Log(("rtldrPEOpen: %s: dir no. %d Size=%#x is invalid (rva=%#x, limit=%#x)!!!\n",
  • trunk/src/VBox/Runtime/common/string/strcache.cpp

    r46101 r46108  
    174174
    175175    char *pszRet = (char *)RTMemPoolDupEx((RTMEMPOOL)hStrCache, pchString, cchString, 1);
    176     if (!pszRet)
     176    if (pszRet)
    177177        RTStrToLower(pszRet);
    178178    return pszRet;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette