VirtualBox

Changeset 66367 in vbox for trunk


Ignore:
Timestamp:
Mar 30, 2017 2:07:17 PM (8 years ago)
Author:
vboxsync
Message:

IPRT: Added RTLDRPROP_INTERNAL_NAME to RTLdrQueryProp/RTLdrQueryPropEx and implemented it for PE and kLdr (i.e. missing for ELF).

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/ldr.h

    r65239 r66367  
    10291029     * This is mainly for PE, NE and LX headers, but also Mach-O FAT. */
    10301030    RTLDRPROP_FILE_OFF_HEADER,
     1031    /** The internal module name.
     1032     * This is the SONAME for ELF, export table name for PE, and zero'th resident
     1033     * name table entry for LX.
     1034     * Returns zero terminated string. */
     1035    RTLDRPROP_INTERNAL_NAME,
    10311036
    10321037    /** End of valid properties.  */
  • trunk/src/VBox/Runtime/common/ldr/ldrEx.cpp

    r64891 r66367  
    640640            AssertReturn(cbBuf == sizeof(uint32_t) || cbBuf == sizeof(uint64_t), VERR_INVALID_PARAMETER);
    641641            break;
     642        case RTLDRPROP_INTERNAL_NAME:
     643            *pcbRet = 0;
     644            break;
    642645
    643646        default:
  • trunk/src/VBox/Runtime/common/ldr/ldrPE.cpp

    r65240 r66367  
    18031803}
    18041804
     1805/**
     1806 * Worker for rtLdrPE_QueryImportModule and rtLdrPE_QueryInternalName that
     1807 * copies a zero termianted string at the given RVA into the RTLdrQueryPropEx
     1808 * output buffer.
     1809 *
     1810 * @returns IPRT status code. If VERR_BUFFER_OVERFLOW, pcbBuf is required size.
     1811 * @param   pThis           The PE module instance.
     1812 * @param   pvBits          Image bits if the caller had them available, NULL if
     1813 *                          not. Saves a couple of file accesses.
     1814 * @param   uRvaString      The RVA of the string to copy.
     1815 * @param   cbMaxString     The max string length.
     1816 * @param   pvBuf           The output buffer.
     1817 * @param   cbBuf           The buffer size.
     1818 * @param   pcbRet          Where to return the number of bytes we've returned
     1819 *                          (or in case of VERR_BUFFER_OVERFLOW would have).
     1820 */
     1821static int rtLdrPE_QueryNameAtRva(PRTLDRMODPE pThis, void const *pvBits, uint32_t uRvaString, uint32_t cbMaxString,
     1822                                  void *pvBuf, size_t cbBuf, size_t *pcbRet)
     1823{
     1824    int rc;
     1825    if (   uRvaString >= pThis->cbHeaders
     1826        && uRvaString < pThis->cbImage)
     1827    {
     1828        /*
     1829         * Limit the string.
     1830         */
     1831        uint32_t cbMax = pThis->cbImage - uRvaString;
     1832        if (cbMax > cbMaxString)
     1833            cbMax = cbMaxString;
     1834        char *pszString;
     1835        rc = rtldrPEReadPartByRva(pThis, pvBits, uRvaString, cbMax, (void const **)&pszString);
     1836        if (RT_SUCCESS(rc))
     1837        {
     1838            /*
     1839             * Make sure it's null terminated and valid UTF-8 encoding.
     1840             *
     1841             * Which encoding this really is isn't defined, I think,
     1842             * but we need to make sure we don't get bogus UTF-8 into
     1843             * the process, so making sure it's valid UTF-8 is a good
     1844             * as anything else since it covers ASCII.
     1845             */
     1846            size_t cchString = RTStrNLen(pszString, cbMaxString);
     1847            if (cchString < cbMaxString)
     1848            {
     1849                rc = RTStrValidateEncodingEx(pszString, cchString, 0 /*fFlags*/);
     1850                if (RT_SUCCESS(rc))
     1851                {
     1852                    /*
     1853                     * Copy out the result and we're done.
     1854                     * (We have to do all the cleanup code though, so no return success here.)
     1855                     */
     1856                    *pcbRet = cchString + 1;
     1857                    if (cbBuf >= cchString + 1)
     1858                        memcpy(pvBuf, pszString, cchString + 1);
     1859                    else
     1860                        rc = VERR_BUFFER_OVERFLOW;
     1861                }
     1862            }
     1863            else
     1864                rc = VERR_BAD_EXE_FORMAT;
     1865            rtldrPEFreePart(pThis, pvBits, pszString);
     1866        }
     1867    }
     1868    else
     1869        rc = VERR_BAD_EXE_FORMAT;
     1870    return rc;
     1871}
     1872
    18051873
    18061874/**
     
    18411909        /*
    18421910         * Retrieve the import table descriptor.
     1911         * Using 1024 as the max name length (should be more than enough).
    18431912         */
    18441913        PCIMAGE_IMPORT_DESCRIPTOR pImpDesc;
     
    18461915        if (RT_SUCCESS(rc))
    18471916        {
    1848             if (   pImpDesc->Name >= pThis->cbHeaders
    1849                 && pImpDesc->Name < pThis->cbImage)
    1850             {
    1851                 /*
    1852                  * Limit the name to 1024 bytes (more than enough for everyone).
    1853                  */
    1854                 uint32_t cchNameMax = pThis->cbImage - pImpDesc->Name;
    1855                 if (cchNameMax > 1024)
    1856                     cchNameMax = 1024;
    1857                 char *pszName;
    1858                 rc = rtldrPEReadPartByRva(pThis, pvBits, pImpDesc->Name, cchNameMax, (void const **)&pszName);
    1859                 if (RT_SUCCESS(rc))
    1860                 {
    1861                     /*
    1862                      * Make sure it's null terminated and valid UTF-8 encoding.
    1863                      *
    1864                      * Which encoding this really is isn't defined, I think,
    1865                      * but we need to make sure we don't get bogus UTF-8 into
    1866                      * the process, so making sure it's valid UTF-8 is a good
    1867                      * as anything else since it covers ASCII.
    1868                      */
    1869                     size_t cchName = RTStrNLen(pszName, cchNameMax);
    1870                     if (cchName < cchNameMax)
    1871                     {
    1872                         rc = RTStrValidateEncodingEx(pszName, cchName, 0 /*fFlags*/);
    1873                         if (RT_SUCCESS(rc))
    1874                         {
    1875                             /*
    1876                              * Copy out the result and we're done.
    1877                              * (We have to do all the cleanup code though, so no return success here.)
    1878                              */
    1879                             *pcbRet = cchName + 1;
    1880                             if (cbBuf >= cchName + 1)
    1881                                 memcpy(pvBuf, pszName, cchName + 1);
    1882                             else
    1883                                 rc = VERR_BUFFER_OVERFLOW;
    1884                         }
    1885                     }
    1886                     else
    1887                         rc = VERR_BAD_EXE_FORMAT;
    1888                     rtldrPEFreePart(pThis, pvBits, pszName);
    1889                 }
    1890             }
    1891             else
    1892                 rc = VERR_BAD_EXE_FORMAT;
     1917            rc = rtLdrPE_QueryNameAtRva(pThis, pvBits, pImpDesc->Name, 1024 /*cchMaxString*/, pvBuf, cbBuf, pcbRet);
    18931918            rtldrPEFreePart(pThis, pvBits, pImpDesc);
    18941919        }
     
    19011926
    19021927    *pcbRet = 0;
     1928    return rc;
     1929}
     1930
     1931
     1932/**
     1933 * Worker for rtLdrPE_QueryProp that retrievs the internal module name.
     1934 *
     1935 * @returns IPRT status code. If VERR_BUFFER_OVERFLOW, pcbBuf is required size.
     1936 * @param   pThis           The PE module instance.
     1937 * @param   pvBits          Image bits if the caller had them available, NULL if
     1938 *                          not. Saves a couple of file accesses.
     1939 * @param   pvBuf           The output buffer.
     1940 * @param   cbBuf           The buffer size.
     1941 * @param   pcbRet          Where to return the number of bytes we've returned
     1942 *                          (or in case of VERR_BUFFER_OVERFLOW would have).
     1943 */
     1944static int rtLdrPE_QueryInternalName(PRTLDRMODPE pThis, void const *pvBits, void *pvBuf, size_t cbBuf, size_t *pcbRet)
     1945{
     1946    *pcbRet = 0;
     1947
     1948    if (   pThis->ExportDir.Size < sizeof(IMAGE_EXPORT_DIRECTORY)
     1949        || pThis->ExportDir.VirtualAddress == 0)
     1950        return VERR_NOT_FOUND;
     1951
     1952    PCIMAGE_EXPORT_DIRECTORY pExpDir;
     1953    int rc = rtldrPEReadPartByRva(pThis, pvBits, pThis->ExportDir.VirtualAddress, sizeof(*pExpDir), (void const **)&pExpDir);
     1954    if (RT_SUCCESS(rc))
     1955    {
     1956        rc = rtLdrPE_QueryNameAtRva(pThis, pvBits, pExpDir->Name, 1024 /*cchMaxString*/, pvBuf, cbBuf, pcbRet);
     1957        rtldrPEFreePart(pThis, pvBits, pExpDir);
     1958    }
     1959
    19031960    return rc;
    19041961}
     
    19712028                *(uint64_t *)pvBuf = pModPe->offNtHdrs;
    19722029            return VINF_SUCCESS;
     2030
     2031        case RTLDRPROP_INTERNAL_NAME:
     2032            return rtLdrPE_QueryInternalName(pModPe, pvBits, pvBuf, cbBuf, pcbRet);
    19732033
    19742034        default:
  • trunk/src/VBox/Runtime/common/ldr/ldrkStuff.cpp

    r65920 r66367  
    846846    PRTLDRMODKLDR pThis = (PRTLDRMODKLDR)pMod;
    847847    int           rc;
     848    size_t const  cbBufAvail = cbBuf;
    848849    switch (enmProp)
    849850    {
     
    854855            AssertReturn(rc == 0, VERR_INVALID_PARAMETER);
    855856            cbBuf = RT_MIN(cbBuf, sizeof(RTUUID));
     857            break;
     858
     859        case RTLDRPROP_INTERNAL_NAME:
     860            if (!pThis->pMod->cchName)
     861                return VERR_NOT_FOUND;
     862            cbBuf = pThis->pMod->cchName + 1;
     863            if (cbBufAvail < cbBuf)
     864            {
     865                if (pcbRet)
     866                    *pcbRet = cbBufAvail;
     867                return VERR_BUFFER_OVERFLOW;
     868            }
     869            memcpy(pvBuf, pThis->pMod->pszName, cbBuf);
    856870            break;
    857871
  • trunk/src/VBox/Runtime/testcase/tstLdr-4.cpp

    r65388 r66367  
    207207                cErrors++;
    208208            }
    209         }
    210     }
    211 
     209
     210            /* While we're here, check a couple of RTLdrQueryProp calls too */
     211            void *pvBits = aLoads[i].pvBits;
     212            for (unsigned iBits = 0; iBits < 2; iBits++, pvBits = NULL)
     213            {
     214                union
     215                {
     216                    char szName[127];
     217                } uBuf;
     218                rc = RTLdrQueryPropEx(aLoads[i].hLdrMod, RTLDRPROP_INTERNAL_NAME, aLoads[i].pvBits,
     219                                      uBuf.szName, sizeof(uBuf.szName), NULL);
     220                if (RT_SUCCESS(rc))
     221                    RTPrintf("tstLdr-4: internal name #%d: '%s'\n", i, uBuf.szName);
     222                else if (rc != VERR_NOT_FOUND || rc != VERR_NOT_SUPPORTED)
     223                    RTPrintf("tstLdr-4: internal name #%d failed: %Rrc\n", i, rc);
     224            }
     225        }
     226    }
    212227
    213228    /*
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