VirtualBox

Ignore:
Timestamp:
Jul 28, 2014 5:52:58 PM (10 years ago)
Author:
vboxsync
Message:

SUP,IPRT: Implemented forwarder support in RTLdr and cleaned up some the ordinal mess. Resolved imports when doing the process verification/purification runs other than SUPHARDNTVPKIND_CHILD_PURIFICATION. This is necessary since 32-bit windows combine .text with .rdata, and we don't want to overwrite the import table after it has been snapped. Include read-only sections in the verfication runs.

Location:
trunk/src/VBox/Runtime/common/ldr
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/ldr/ldr.cpp

    r51770 r52213  
    6363    {
    6464        RTUINTPTR Value = 0;
    65         rc = pMod->pOps->pfnGetSymbolEx(pMod, NULL, 0, pszSymbol, &Value);
     65        rc = pMod->pOps->pfnGetSymbolEx(pMod, NULL, 0, UINT32_MAX, pszSymbol, &Value);
    6666        if (RT_SUCCESS(rc))
    6767        {
  • trunk/src/VBox/Runtime/common/ldr/ldrELFRelocatable.cpp.h

    r51770 r52213  
    922922
    923923
     924/**
     925 * Worker for pfnGetSymbolEx.
     926 */
     927static int RTLDRELF_NAME(ReturnSymbol)(PRTLDRMODELF pThis, const Elf_Sym *pSym, Elf_Addr uBaseAddr, PRTUINTPTR pValue)
     928{
     929    Elf_Addr Value;
     930    if (pSym->st_shndx == SHN_ABS)
     931        /* absolute symbols are not subject to any relocation. */
     932        Value = pSym->st_value;
     933    else if (pSym->st_shndx < pThis->Ehdr.e_shnum)
     934    {
     935        if (pThis->Ehdr.e_type == ET_REL)
     936            /* relative to the section. */
     937            Value = uBaseAddr + pSym->st_value + pThis->paShdrs[pSym->st_shndx].sh_addr;
     938        else /* Fixed up for link address. */
     939            Value = uBaseAddr + pSym->st_value - pThis->LinkAddress;
     940    }
     941    else
     942    {
     943        AssertMsgFailed(("Arg! pSym->st_shndx=%d\n", pSym->st_shndx));
     944        return VERR_BAD_EXE_FORMAT;
     945    }
     946    AssertMsgReturn(Value == (RTUINTPTR)Value, (FMT_ELF_ADDR "\n", Value), VERR_SYMBOL_VALUE_TOO_BIG);
     947    *pValue = (RTUINTPTR)Value;
     948    return VINF_SUCCESS;
     949}
     950
     951
    924952/** @copydoc RTLDROPS::pfnGetSymbolEx */
    925 static DECLCALLBACK(int) RTLDRELF_NAME(GetSymbolEx)(PRTLDRMODINTERNAL pMod, const void *pvBits, RTUINTPTR BaseAddress, const char *pszSymbol, RTUINTPTR *pValue)
     953static DECLCALLBACK(int) RTLDRELF_NAME(GetSymbolEx)(PRTLDRMODINTERNAL pMod, const void *pvBits, RTUINTPTR BaseAddress,
     954                                                    uint32_t iOrdinal, const char *pszSymbol, RTUINTPTR *pValue)
    926955{
    927956    PRTLDRMODELF pModElf = (PRTLDRMODELF)pMod;
     
    931960     * Validate the input.
    932961     */
    933     Elf_Addr BaseAddr = (Elf_Addr)BaseAddress;
    934     AssertMsgReturn((RTUINTPTR)BaseAddr == BaseAddress, ("#RTptr", BaseAddress), VERR_IMAGE_BASE_TOO_HIGH);
     962    Elf_Addr uBaseAddr = (Elf_Addr)BaseAddress;
     963    AssertMsgReturn((RTUINTPTR)uBaseAddr == BaseAddress, ("#RTptr", BaseAddress), VERR_IMAGE_BASE_TOO_HIGH);
    935964
    936965    /*
     
    944973     * Calc all kinds of pointers before we start iterating the symbol table.
    945974     */
    946     const char         *pStr  = pModElf->pStr;
    947975    const Elf_Sym     *paSyms = pModElf->paSyms;
    948976    unsigned            cSyms = pModElf->cSyms;
    949     for (unsigned iSym = 1; iSym < cSyms; iSym++)
    950     {
    951         /* Undefined symbols are not exports, they are imports. */
    952         if (    paSyms[iSym].st_shndx != SHN_UNDEF
    953             &&  (   ELF_ST_BIND(paSyms[iSym].st_info) == STB_GLOBAL
    954                  || ELF_ST_BIND(paSyms[iSym].st_info) == STB_WEAK))
    955         {
    956             /* Validate the name string and try match with it. */
    957             if (paSyms[iSym].st_name < pModElf->cbStr)
    958             {
    959                 if (!strcmp(pszSymbol, pStr + paSyms[iSym].st_name))
     977    if (iOrdinal == UINT32_MAX)
     978    {
     979        const char     *pStr  = pModElf->pStr;
     980        for (unsigned iSym = 1; iSym < cSyms; iSym++)
     981        {
     982            /* Undefined symbols are not exports, they are imports. */
     983            if (    paSyms[iSym].st_shndx != SHN_UNDEF
     984                &&  (   ELF_ST_BIND(paSyms[iSym].st_info) == STB_GLOBAL
     985                     || ELF_ST_BIND(paSyms[iSym].st_info) == STB_WEAK))
     986            {
     987                /* Validate the name string and try match with it. */
     988                if (paSyms[iSym].st_name < pModElf->cbStr)
    960989                {
    961                     /* matched! */
    962                     Elf_Addr Value;
    963                     if (paSyms[iSym].st_shndx == SHN_ABS)
    964                         /* absolute symbols are not subject to any relocation. */
    965                         Value = paSyms[iSym].st_value;
    966                     else if (paSyms[iSym].st_shndx < pModElf->Ehdr.e_shnum)
     990                    if (!strcmp(pszSymbol, pStr + paSyms[iSym].st_name))
    967991                    {
    968                         if (pModElf->Ehdr.e_type == ET_REL)
    969                             /* relative to the section. */
    970                             Value = BaseAddr + paSyms[iSym].st_value + pModElf->paShdrs[paSyms[iSym].st_shndx].sh_addr;
    971                         else /* Fixed up for link address. */
    972                             Value = BaseAddr + paSyms[iSym].st_value - pModElf->LinkAddress;
     992                        /* matched! */
     993                        return RTLDRELF_NAME(ReturnSymbol)(pModElf, &paSyms[iSym], uBaseAddr, pValue);
    973994                    }
    974                     else
    975                     {
    976                         AssertMsgFailed(("Arg. paSyms[iSym].st_shndx=%d\n", paSyms[iSym].st_shndx));
    977                         return VERR_BAD_EXE_FORMAT;
    978                     }
    979                     AssertMsgReturn(Value == (RTUINTPTR)Value, (FMT_ELF_ADDR "\n", Value), VERR_SYMBOL_VALUE_TOO_BIG);
    980                     *pValue = (RTUINTPTR)Value;
    981                     return VINF_SUCCESS;
    982995                }
    983             }
    984             else
    985             {
    986                 AssertMsgFailed(("String outside string table! iSym=%d paSyms[iSym].st_name=%#x\n", iSym, paSyms[iSym].st_name));
    987                 return VERR_LDRELF_INVALID_SYMBOL_NAME_OFFSET;
    988             }
    989         }
     996                else
     997                {
     998                    AssertMsgFailed(("String outside string table! iSym=%d paSyms[iSym].st_name=%#x\n", iSym, paSyms[iSym].st_name));
     999                    return VERR_LDRELF_INVALID_SYMBOL_NAME_OFFSET;
     1000                }
     1001            }
     1002        }
     1003    }
     1004    else if (iOrdinal < cSyms)
     1005    {
     1006        if (    paSyms[iOrdinal].st_shndx != SHN_UNDEF
     1007            &&  (   ELF_ST_BIND(paSyms[iOrdinal].st_info) == STB_GLOBAL
     1008                 || ELF_ST_BIND(paSyms[iOrdinal].st_info) == STB_WEAK))
     1009            return RTLDRELF_NAME(ReturnSymbol)(pModElf, &paSyms[iOrdinal], uBaseAddr, pValue);
    9901010    }
    9911011
     
    13941414    RTLDRELF_NAME(Relocate),
    13951415    RTLDRELF_NAME(GetSymbolEx),
     1416    NULL /*pfnQueryForwarderInfo*/,
    13961417    RTLDRELF_NAME(EnumDbgInfo),
    13971418    RTLDRELF_NAME(EnumSegments),
  • trunk/src/VBox/Runtime/common/ldr/ldrEx.cpp

    r52204 r52213  
    288288
    289289
    290 /**
    291  * Gets the address of a named exported symbol.
    292  *
    293  * This function differs from the plain one in that it can deal with
    294  * both GC and HC address sizes, and that it can calculate the symbol
    295  * value relative to any given base address.
    296  *
    297  * @returns iprt status code.
    298  * @param   hLdrMod         The loader module handle.
    299  * @param   pvBits          Optional pointer to the loaded image.
    300  *                          Set this to NULL if no RTLdrGetBits() processed image bits are available.
    301  *                          Not supported for RTLdrLoad() images and must be NULL.
    302  * @param   BaseAddress     Image load address.
    303  *                          Not supported for RTLdrLoad() images and must be 0.
    304  * @param   pszSymbol       Symbol name.
    305  * @param   pValue          Where to store the symbol value.
    306  */
    307 RTDECL(int) RTLdrGetSymbolEx(RTLDRMOD hLdrMod, const void *pvBits, RTLDRADDR BaseAddress, const char *pszSymbol,
    308                              PRTLDRADDR pValue)
    309 {
    310     LogFlow(("RTLdrGetSymbolEx: hLdrMod=%RTldrm pvBits=%p BaseAddress=%RTptr pszSymbol=%p:{%s} pValue\n",
    311              hLdrMod, pvBits, BaseAddress, pszSymbol, pszSymbol, pValue));
    312 
    313     /*
    314      * Validate input.
    315      */
    316     AssertMsgReturn(rtldrIsValid(hLdrMod), ("hLdrMod=%p\n", hLdrMod), VERR_INVALID_HANDLE);
    317     AssertMsgReturn(!pvBits || VALID_PTR(pvBits), ("pvBits=%p\n", pvBits), VERR_INVALID_PARAMETER);
    318     AssertMsgReturn(pszSymbol, ("pszSymbol=%p\n", pszSymbol), VERR_INVALID_PARAMETER);
    319     AssertMsgReturn(VALID_PTR(pValue), ("pValue=%p\n", pvBits), VERR_INVALID_PARAMETER);
    320     PRTLDRMODINTERNAL pMod = (PRTLDRMODINTERNAL)hLdrMod;
    321     //AssertMsgReturn(pMod->eState == LDR_STATE_OPENED, ("eState=%d\n", pMod->eState), VERR_WRONG_ORDER);
     290RTDECL(int) RTLdrGetSymbolEx(RTLDRMOD hLdrMod, const void *pvBits, RTLDRADDR BaseAddress,
     291                             uint32_t iOrdinal, const char *pszSymbol, PRTLDRADDR pValue)
     292{
     293    LogFlow(("RTLdrGetSymbolEx: hLdrMod=%RTldrm pvBits=%p BaseAddress=%RTptr iOrdinal=%#x pszSymbol=%p:{%s} pValue\n",
     294             hLdrMod, pvBits, BaseAddress, iOrdinal, pszSymbol, pszSymbol, pValue));
     295
     296    /*
     297     * Validate input.
     298     */
     299    AssertMsgReturn(rtldrIsValid(hLdrMod), ("hLdrMod=%p\n", hLdrMod), VERR_INVALID_HANDLE);
     300    AssertPtrNullReturn(pvBits, VERR_INVALID_POINTER);
     301    AssertPtrNullReturn(pszSymbol, VERR_INVALID_POINTER);
     302    AssertReturn(pszSymbol || iOrdinal != UINT32_MAX, VERR_INVALID_PARAMETER);
     303    AssertPtrReturn(pValue, VERR_INVALID_POINTER);
     304    PRTLDRMODINTERNAL pMod = (PRTLDRMODINTERNAL)hLdrMod;
    322305
    323306    /*
     
    326309    int rc;
    327310    if (pMod->pOps->pfnGetSymbolEx)
    328         rc = pMod->pOps->pfnGetSymbolEx(pMod, pvBits, BaseAddress, pszSymbol, pValue);
    329     else if (!BaseAddress && !pvBits)
     311        rc = pMod->pOps->pfnGetSymbolEx(pMod, pvBits, BaseAddress, iOrdinal, pszSymbol, pValue);
     312    else if (!BaseAddress && !pvBits && iOrdinal == UINT32_MAX)
    330313    {
    331314        void *pvValue;
     
    340323}
    341324RT_EXPORT_SYMBOL(RTLdrGetSymbolEx);
     325
     326
     327RTDECL(int) RTLdrQueryForwarderInfo(RTLDRMOD hLdrMod, const void *pvBits, uint32_t iOrdinal, const char *pszSymbol,
     328                                    PRTLDRIMPORTINFO pInfo, size_t cbInfo)
     329{
     330    LogFlow(("RTLdrQueryForwarderInfo: hLdrMod=%RTldrm pvBits=%p iOrdinal=%#x pszSymbol=%p:{%s} pInfo=%p cbInfo=%zu\n",
     331             hLdrMod, pvBits, iOrdinal, pszSymbol, pszSymbol, pInfo, cbInfo));
     332
     333    /*
     334     * Validate input.
     335     */
     336    AssertMsgReturn(rtldrIsValid(hLdrMod), ("hLdrMod=%p\n", hLdrMod), VERR_INVALID_HANDLE);
     337    AssertPtrNullReturn(pvBits, VERR_INVALID_POINTER);
     338    AssertMsgReturn(pszSymbol, ("pszSymbol=%p\n", pszSymbol), VERR_INVALID_PARAMETER);
     339    AssertPtrReturn(pInfo, VERR_INVALID_PARAMETER);
     340    AssertReturn(cbInfo >= sizeof(*pInfo), VERR_INVALID_PARAMETER);
     341    PRTLDRMODINTERNAL pMod = (PRTLDRMODINTERNAL)hLdrMod;
     342
     343    /*
     344     * Do it.
     345     */
     346    int rc;
     347    if (pMod->pOps->pfnQueryForwarderInfo)
     348    {
     349        rc = pMod->pOps->pfnQueryForwarderInfo(pMod, pvBits, iOrdinal, pszSymbol, pInfo, cbInfo);
     350        if (RT_SUCCESS(rc))
     351            LogFlow(("RTLdrQueryForwarderInfo: returns %Rrc pInfo={%#x,%#x,%s,%s}\n", rc,
     352                     pInfo->iSelfOrdinal, pInfo->iOrdinal, pInfo->pszSymbol, pInfo->szModule));
     353        else
     354            LogFlow(("RTLdrQueryForwarderInfo: returns %Rrc\n", rc));
     355    }
     356    else
     357    {
     358        LogFlow(("RTLdrQueryForwarderInfo: returns VERR_NOT_SUPPORTED\n"));
     359        rc = VERR_NOT_SUPPORTED;
     360    }
     361    return rc;
     362
     363}
     364RT_EXPORT_SYMBOL(RTLdrQueryForwarderInfo);
    342365
    343366
  • trunk/src/VBox/Runtime/common/ldr/ldrNative.cpp

    r51770 r52213  
    7575    NULL,
    7676    NULL,
     77    NULL /*pfnQueryForwarderInfo*/,
    7778    NULL,
    7879    NULL,
  • trunk/src/VBox/Runtime/common/ldr/ldrPE.cpp

    r52204 r52213  
    897897
    898898
    899 /** @copydoc RTLDROPS::pfnGetSymbolEx. */
    900 static DECLCALLBACK(int) rtldrPEGetSymbolEx(PRTLDRMODINTERNAL pMod, const void *pvBits, RTUINTPTR BaseAddress, const char *pszSymbol, RTUINTPTR *pValue)
    901 {
    902     PRTLDRMODPE pModPe = (PRTLDRMODPE)pMod;
    903 
     899/**
     900 * Internal worker for pfnGetSymbolEx and pfnQueryForwarderInfo.
     901 *
     902 * @returns IPRT status code.
     903 * @param   pModPe              The PE module instance.
     904 * @param   iOrdinal            The symbol ordinal, UINT32_MAX if named symbol.
     905 * @param   pszSymbol           The symbol name.
     906 * @param   ppvBits             The image bits pointer (input/output).
     907 * @param   puRvaExport         Where to return the symbol RVA.
     908 * @param   puOrdinal           Where to return the ordinal number. Optional.
     909 */
     910static int rtLdrPE_ExportToRva(PRTLDRMODPE pModPe, uint32_t iOrdinal, const char *pszSymbol,
     911                               const void **ppvBits, uint32_t *puRvaExport, uint32_t *puOrdinal)
     912{
    904913    /*
    905914     * Check if there is actually anything to work on.
     
    912921     * No bits supplied? Do we need to read the bits?
    913922     */
     923    void const *pvBits = *ppvBits;
    914924    if (!pvBits)
    915925    {
     
    920930                return rc;
    921931        }
    922         pvBits = pModPe->pvBits;
     932        *ppvBits = pvBits = pModPe->pvBits;
    923933    }
    924934
    925935    PIMAGE_EXPORT_DIRECTORY pExpDir = PE_RVA2TYPE(pvBits, pModPe->ExportDir.VirtualAddress, PIMAGE_EXPORT_DIRECTORY);
    926936    int                     iExpOrdinal = 0;    /* index into address table. */
    927     if ((uintptr_t)pszSymbol <= 0xffff)
     937    if (iOrdinal != UINT32_MAX)
    928938    {
    929939        /*
    930940         * Find ordinal export: Simple table lookup.
    931941         */
    932         unsigned uOrdinal = (uintptr_t)pszSymbol & 0xffff;
    933         if (    uOrdinal >= pExpDir->Base + RT_MAX(pExpDir->NumberOfNames, pExpDir->NumberOfFunctions)
    934             ||  uOrdinal < pExpDir->Base)
     942        if (    iOrdinal >= pExpDir->Base + RT_MAX(pExpDir->NumberOfNames, pExpDir->NumberOfFunctions)
     943            ||  iOrdinal < pExpDir->Base)
    935944            return VERR_SYMBOL_NOT_FOUND;
    936         iExpOrdinal = uOrdinal - pExpDir->Base;
     945        iExpOrdinal = iOrdinal - pExpDir->Base;
    937946    }
    938947    else
     
    951960            if (iStart > iEnd)
    952961            {
    953             #ifdef RT_STRICT
     962#ifdef RT_STRICT
    954963                /* do a linear search just to verify the correctness of the above algorithm */
    955964                for (unsigned i = 0; i < pExpDir->NumberOfNames; i++)
     
    960969                              ("bug in binary export search!!!\n"));
    961970                }
    962             #endif
     971#endif
    963972                return VERR_SYMBOL_NOT_FOUND;
    964973            }
     
    982991     * Found export (iExpOrdinal).
    983992     */
    984     uint32_t *  paAddress = PE_RVA2TYPE(pvBits, pExpDir->AddressOfFunctions, uint32_t *);
    985     unsigned    uRVAExport = paAddress[iExpOrdinal];
    986 
    987     if (    uRVAExport > pModPe->ExportDir.VirtualAddress
    988         &&  uRVAExport < pModPe->ExportDir.VirtualAddress + pModPe->ExportDir.Size)
    989     {
    990         /* Resolve forwarder. */
    991         AssertMsgFailed(("Forwarders are not supported!\n"));
    992         return VERR_SYMBOL_NOT_FOUND;
    993     }
    994 
    995     /* Get plain export address */
    996     *pValue = PE_RVA2TYPE(BaseAddress, uRVAExport, RTUINTPTR);
    997 
     993    uint32_t *paAddress = PE_RVA2TYPE(pvBits, pExpDir->AddressOfFunctions, uint32_t *);
     994    *puRvaExport = paAddress[iExpOrdinal];
     995    if (puOrdinal)
     996        *puOrdinal = iExpOrdinal;
    998997    return VINF_SUCCESS;
     998}
     999
     1000
     1001/** @copydoc RTLDROPS::pfnGetSymbolEx. */
     1002static DECLCALLBACK(int) rtldrPEGetSymbolEx(PRTLDRMODINTERNAL pMod, const void *pvBits, RTUINTPTR BaseAddress,
     1003                                            uint32_t iOrdinal, const char *pszSymbol, RTUINTPTR *pValue)
     1004{
     1005    PRTLDRMODPE pThis = (PRTLDRMODPE)pMod;
     1006    uint32_t uRvaExport;
     1007    int rc = rtLdrPE_ExportToRva(pThis, iOrdinal, pszSymbol, &pvBits, &uRvaExport, NULL);
     1008    if (RT_SUCCESS(rc))
     1009    {
     1010
     1011        uint32_t offForwarder = uRvaExport - pThis->ExportDir.VirtualAddress;
     1012        if (offForwarder >= pThis->ExportDir.Size)
     1013            /* Get plain export address */
     1014            *pValue = PE_RVA2TYPE(BaseAddress, uRvaExport, RTUINTPTR);
     1015        else
     1016        {
     1017            /* Return the approximate length of the forwarder buffer. */
     1018            const char *pszForwarder = PE_RVA2TYPE(pvBits, uRvaExport, const char *);
     1019            *pValue = sizeof(RTLDRIMPORTINFO) + RTStrNLen(pszForwarder, offForwarder - pThis->ExportDir.Size);
     1020            rc = VERR_LDR_FORWARDER;
     1021        }
     1022    }
     1023    return rc;
     1024}
     1025
     1026
     1027/** @copydoc RTLDROPS::pfnQueryForwarderInfo. */
     1028static DECLCALLBACK(int) rtldrPE_QueryForwarderInfo(PRTLDRMODINTERNAL pMod, const void *pvBits,  uint32_t iOrdinal,
     1029                                                    const char *pszSymbol, PRTLDRIMPORTINFO pInfo, size_t cbInfo)
     1030{
     1031    AssertReturn(cbInfo >= sizeof(*pInfo), VERR_INVALID_PARAMETER);
     1032
     1033    PRTLDRMODPE pThis = (PRTLDRMODPE)pMod;
     1034    uint32_t uRvaExport;
     1035    int rc = rtLdrPE_ExportToRva(pThis, iOrdinal, pszSymbol, &pvBits, &uRvaExport, &iOrdinal);
     1036    if (RT_SUCCESS(rc))
     1037    {
     1038        uint32_t offForwarder = uRvaExport - pThis->ExportDir.VirtualAddress;
     1039        if (offForwarder < pThis->ExportDir.Size)
     1040        {
     1041            const char *pszForwarder = PE_RVA2TYPE(pvBits, uRvaExport, const char *);
     1042
     1043            /*
     1044             * Parse and validate the string.  We must make sure it's valid
     1045             * UTF-8, so we restrict it to ASCII.
     1046             */
     1047            const char *pszEnd = RTStrEnd(pszForwarder, offForwarder - pThis->ExportDir.Size);
     1048            if (pszEnd)
     1049            {
     1050                /* The module name. */
     1051                char ch;
     1052                uint32_t off = 0;
     1053                while ((ch = pszForwarder[off]) != '.' && ch != '\0')
     1054                {
     1055                    if (RT_UNLIKELY((uint8_t)ch >= 0x80))
     1056                        return VERR_LDR_BAD_FORWARDER;
     1057                    off++;
     1058                }
     1059                if (RT_UNLIKELY(ch != '.'))
     1060                    return VERR_LDR_BAD_FORWARDER;
     1061                uint32_t const offDot = off;
     1062                off++;
     1063
     1064                /* The function name or ordinal number. Ordinals starts with a hash. */
     1065                uint32_t iImpOrdinal;
     1066                if (pszForwarder[off] != '#')
     1067                {
     1068                    iImpOrdinal = UINT32_MAX;
     1069                    while ((ch = pszForwarder[off]) != '\0')
     1070                    {
     1071                        if (RT_UNLIKELY((uint8_t)ch >= 0x80))
     1072                            return VERR_LDR_BAD_FORWARDER;
     1073                        off++;
     1074                    }
     1075                    if (RT_UNLIKELY(off == offDot + 1))
     1076                        return VERR_LDR_BAD_FORWARDER;
     1077                }
     1078                else
     1079                {
     1080                    rc = RTStrToUInt32Full(&pszForwarder[off + 1], 10, &iImpOrdinal);
     1081                    if (RT_UNLIKELY(rc != VINF_SUCCESS || iImpOrdinal > UINT16_MAX))
     1082                        return VERR_LDR_BAD_FORWARDER;
     1083                }
     1084
     1085                /*
     1086                 * Enough buffer?
     1087                 */
     1088                uint32_t cbNeeded = RT_OFFSETOF(RTLDRIMPORTINFO, szModule[iImpOrdinal != UINT32_MAX ? offDot + 1 : off + 1]);
     1089                if (cbNeeded > cbInfo)
     1090                    return VERR_BUFFER_OVERFLOW;
     1091
     1092                /*
     1093                 * Fill in the return buffer.
     1094                 */
     1095                pInfo->iSelfOrdinal = iOrdinal;
     1096                pInfo->iOrdinal     = iImpOrdinal;
     1097                if (iImpOrdinal == UINT32_MAX)
     1098                {
     1099                    pInfo->pszSymbol = &pInfo->szModule[offDot + 1];
     1100                    memcpy(&pInfo->szModule[0], pszForwarder, off + 1);
     1101                }
     1102                else
     1103                {
     1104                    pInfo->pszSymbol = NULL;
     1105                    memcpy(&pInfo->szModule[0], pszForwarder, offDot);
     1106                }
     1107                pInfo->szModule[offDot] = '\0';
     1108                rc = VINF_SUCCESS;
     1109            }
     1110            else
     1111                rc = VERR_LDR_BAD_FORWARDER;
     1112        }
     1113        else
     1114            rc = VERR_LDR_NOT_FORWARDER;
     1115    }
     1116    return rc;
    9991117}
    10001118
     
    25422660        rtldrPERelocate,
    25432661        rtldrPEGetSymbolEx,
     2662        rtldrPE_QueryForwarderInfo,
    25442663        rtldrPE_EnumDbgInfo,
    25452664        rtldrPE_EnumSegments,
     
    25752694        rtldrPERelocate,
    25762695        rtldrPEGetSymbolEx,
     2696        rtldrPE_QueryForwarderInfo,
    25772697        rtldrPE_EnumDbgInfo,
    25782698        rtldrPE_EnumSegments,
  • trunk/src/VBox/Runtime/common/ldr/ldrkStuff.cpp

    r51770 r52213  
    561561/** @copydoc RTLDROPS::pfnGetSymbolEx */
    562562static DECLCALLBACK(int) rtkldr_GetSymbolEx(PRTLDRMODINTERNAL pMod, const void *pvBits, RTUINTPTR BaseAddress,
    563                                             const char *pszSymbol, RTUINTPTR *pValue)
     563                                            uint32_t iOrdinal, const char *pszSymbol, RTUINTPTR *pValue)
    564564{
    565565    PKLDRMOD pModkLdr = ((PRTLDRMODKLDR)pMod)->pMod;
     
    581581
    582582    int rc = kLdrModQuerySymbol(pModkLdr, pvBits, BaseAddress,
    583                                 NIL_KLDRMOD_SYM_ORDINAL, pszSymbol, strlen(pszSymbol), NULL,
    584                                 NULL, NULL, &uValue, NULL);
     583                                iOrdinal == UINT32_MAX ? NIL_KLDRMOD_SYM_ORDINAL : iOrdinal,
     584                                pszSymbol, strlen(pszSymbol), NULL,
     585                                NULL, NULL,
     586                                &uValue, NULL);
    585587    if (!rc)
    586588    {
     
    873875    rtkldr_Relocate,
    874876    rtkldr_GetSymbolEx,
     877    NULL /*pfnQueryForwarderInfo*/,
    875878    rtkldr_EnumDbgInfo,
    876879    rtkldr_EnumSegments,
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