VirtualBox

Ignore:
Timestamp:
Oct 23, 2018 2:24:24 PM (6 years ago)
Author:
vboxsync
Message:

SUPDrv: Adjusted ep validation a little in prep for bugref:9232

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp

    r73097 r75003  
    20082008                 Info.ImageAddress, Info.SectionPointer, Info.ImageLength, pImage->cbImageBits, rcNt, Info.Name.Buffer));
    20092009# ifdef DEBUG_bird
    2010             SUPR0Printf("ImageAddress=%p SectionPointer=%p ImageLength=%#x cbImageBits=%#x rcNt=%#x '%ws'\n",
     2010            SUPR0Printf("ImageAddress=%p SectionPointer=%p ImageLength=%#x cbImageBits=%#x rcNt=%#x '%ls'\n",
    20112011                        Info.ImageAddress, Info.SectionPointer, Info.ImageLength, pImage->cbImageBits, rcNt, Info.Name.Buffer);
    20122012# endif
     
    20882088}
    20892089
    2090 int  VBOXCALL   supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits)
    2091 {
    2092     NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits);
     2090/*
     2091 * Note! Similar code in rtR0DbgKrnlNtParseModule.
     2092 */
     2093int  VBOXCALL   supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv,
     2094                                           const uint8_t *pbImageBits, const char *pszSymbol)
     2095{
     2096#if 1
     2097    RT_NOREF(pDevExt, pbImageBits);
     2098    AssertReturn(pImage->pvNtSectionObj, VERR_INVALID_STATE);
     2099
     2100    /*
     2101     * Locate the export directory in the loaded image.
     2102     */
     2103    uint8_t const  *pbMapping      = (uint8_t const  *)pImage->pvImage;
     2104    uint32_t const  cbMapping      = pImage->cbImageBits;
     2105    uint32_t const  uRvaToValidate = (uint32_t)((uintptr_t)pv - (uintptr_t)pbMapping);
     2106    AssertReturn(uRvaToValidate < cbMapping, VERR_INTERNAL_ERROR_3);
     2107
     2108    uint32_t const  offNtHdrs = *(uint16_t *)pbMapping == IMAGE_DOS_SIGNATURE
     2109                              ? ((IMAGE_DOS_HEADER const *)pbMapping)->e_lfanew
     2110                              : 0;
     2111    AssertLogRelReturn(offNtHdrs + sizeof(IMAGE_NT_HEADERS) < cbMapping, VERR_INTERNAL_ERROR_5);
     2112
     2113    IMAGE_NT_HEADERS const *pNtHdrs = (IMAGE_NT_HEADERS const *)((uintptr_t)pbMapping + offNtHdrs);
     2114    AssertLogRelReturn(pNtHdrs->Signature == IMAGE_NT_SIGNATURE, VERR_INVALID_EXE_SIGNATURE);
     2115    AssertLogRelReturn(pNtHdrs->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR_MAGIC, VERR_BAD_EXE_FORMAT);
     2116    AssertLogRelReturn(pNtHdrs->OptionalHeader.NumberOfRvaAndSizes == IMAGE_NUMBEROF_DIRECTORY_ENTRIES, VERR_BAD_EXE_FORMAT);
     2117
     2118    uint32_t const offEndSectHdrs = offNtHdrs
     2119                                  + sizeof(*pNtHdrs)
     2120                                  + pNtHdrs->FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
     2121    AssertReturn(offEndSectHdrs < cbMapping, VERR_BAD_EXE_FORMAT);
     2122
     2123    /*
     2124     * Find the export directory.
     2125     */
     2126    IMAGE_DATA_DIRECTORY ExpDir = pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
     2127    if (!ExpDir.Size)
     2128    {
     2129        SUPR0Printf("SUPDrv: No exports in %s!\n", pImage->szName);
     2130        return VERR_NOT_FOUND;
     2131    }
     2132    AssertReturn(   ExpDir.Size >= sizeof(IMAGE_EXPORT_DIRECTORY)
     2133                 && ExpDir.VirtualAddress >= offEndSectHdrs
     2134                 && ExpDir.VirtualAddress < cbMapping
     2135                 && ExpDir.VirtualAddress + ExpDir.Size <= cbMapping, VERR_BAD_EXE_FORMAT);
     2136
     2137    IMAGE_EXPORT_DIRECTORY const *pExpDir = (IMAGE_EXPORT_DIRECTORY const *)&pbMapping[ExpDir.VirtualAddress];
     2138
     2139    uint32_t const cNamedExports = pExpDir->NumberOfNames;
     2140    AssertReturn(cNamedExports              < _1M, VERR_BAD_EXE_FORMAT);
     2141    AssertReturn(pExpDir->NumberOfFunctions < _1M, VERR_BAD_EXE_FORMAT);
     2142    if (pExpDir->NumberOfFunctions == 0 || cNamedExports == 0)
     2143    {
     2144        SUPR0Printf("SUPDrv: No exports in %s!\n", pImage->szName);
     2145        return VERR_NOT_FOUND;
     2146    }
     2147
     2148    uint32_t const cExports = RT_MAX(cNamedExports, pExpDir->NumberOfFunctions);
     2149
     2150    AssertReturn(   pExpDir->AddressOfFunctions >= offEndSectHdrs
     2151                 && pExpDir->AddressOfFunctions < cbMapping
     2152                 && pExpDir->AddressOfFunctions + cExports * sizeof(uint32_t) <= cbMapping,
     2153                 VERR_BAD_EXE_FORMAT);
     2154    uint32_t const * const paoffExports = (uint32_t const *)&pbMapping[pExpDir->AddressOfFunctions];
     2155
     2156    AssertReturn(   pExpDir->AddressOfNames >= offEndSectHdrs
     2157                 && pExpDir->AddressOfNames < cbMapping
     2158                 && pExpDir->AddressOfNames + cNamedExports * sizeof(uint32_t) <= cbMapping,
     2159                 VERR_BAD_EXE_FORMAT);
     2160    uint32_t const * const paoffNamedExports = (uint32_t const *)&pbMapping[pExpDir->AddressOfNames];
     2161
     2162    AssertReturn(   pExpDir->AddressOfNameOrdinals >= offEndSectHdrs
     2163                 && pExpDir->AddressOfNameOrdinals < cbMapping
     2164                 && pExpDir->AddressOfNameOrdinals + cNamedExports * sizeof(uint32_t) <= cbMapping,
     2165                 VERR_BAD_EXE_FORMAT);
     2166    uint16_t const * const pau16NameOrdinals = (uint16_t const *)&pbMapping[pExpDir->AddressOfNameOrdinals];
     2167
     2168    /*
     2169     * Validate the entrypoint RVA by scanning the export table.
     2170     */
     2171    uint32_t iExportOrdinal = UINT32_MAX;
     2172    for (uint32_t i = 0; i < cExports; i++)
     2173        if (paoffExports[i] == uRvaToValidate)
     2174        {
     2175            iExportOrdinal = i;
     2176            break;
     2177        }
     2178    if (iExportOrdinal == UINT32_MAX)
     2179    {
     2180        SUPR0Printf("SUPDrv: No export with rva %#x (%s) in %s!\n", uRvaToValidate, pszSymbol, pImage->szName);
     2181        return VERR_NOT_FOUND;
     2182    }
     2183
     2184    /*
     2185     * Can we validate the symbol name too?  If so, just do a linear search.
     2186     */
     2187    if (pszSymbol && RT_C_IS_UPPER(*pszSymbol))
     2188    {
     2189        size_t const cchSymbol  = strlen(pszSymbol);
     2190        for (uint32_t i = 0; i < cNamedExports; i++)
     2191        {
     2192            uint32_t const     offName = paoffNamedExports[i];
     2193            AssertReturn(offName < cbMapping, VERR_BAD_EXE_FORMAT);
     2194            uint32_t const     cchMaxName = cbMapping - offName;
     2195            const char * const pszName    = (const char *)&pbImageBits[offName];
     2196            const char * const pszEnd     = (const char *)memchr(pszName, '\0', cchMaxName);
     2197            AssertReturn(pszEnd, VERR_BAD_EXE_FORMAT);
     2198
     2199            if (   cchSymbol == (size_t)(pszEnd - pszName)
     2200                && memcmp(pszName, pszSymbol, cchSymbol) == 0)
     2201            {
     2202                if (pau16NameOrdinals[i] == iExportOrdinal)
     2203                    return VINF_SUCCESS;
     2204                SUPR0Printf("SUPDrv: Different exports found for %s and rva %#x in %s: %#x vs %#x\n",
     2205                            pszSymbol, uRvaToValidate, pImage->szName, pau16NameOrdinals[i], iExportOrdinal);
     2206                return VERR_LDR_BAD_FIXUP;
     2207            }
     2208        }
     2209        SUPR0Printf("SUPDrv: No export named %s (%#x) in  %s!\n", pszSymbol, uRvaToValidate, pImage->szName);
     2210        return VERR_SYMBOL_NOT_FOUND;
     2211    }
    20932212    return VINF_SUCCESS;
     2213
     2214#else
     2215    NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits); NOREF(pszSymbol);
     2216    return VERR_NOT_SUPPORTED;
     2217#endif
    20942218}
    20952219
     
    21792303        /*
    21802304         * On Windows 10 the ImageBase member of the optional header is sometimes
    2181          * updated with the actual load address and sometimes not.  Try compare
    2182          *
     2305         * updated with the actual load address and sometimes not.
    21832306         */
    21842307        uint32_t const  offNtHdrs = *(uint16_t *)pbImageBits == IMAGE_DOS_SIGNATURE
Note: See TracChangeset for help on using the changeset viewer.

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