Ignore:
Timestamp:
Oct 14, 2013, 4:11:57 AM (12 years ago)
Author:
bird
Message:

Mach-O: Accept to open MH_BUNDLE file (but not load), symbol enum fixes and hacks.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kLdr/kLdrModMachO.c

    r60 r61  
    355355        && s.Hdr32.filetype != MH_EXECUTE
    356356        && s.Hdr32.filetype != MH_DYLIB
     357        && s.Hdr32.filetype != MH_BUNDLE
    357358        && s.Hdr32.filetype != MH_DSYM
    358359        && s.Hdr32.filetype != MH_KEXT_BUNDLE)
     
    463464        case MH_EXECUTE:    pMod->enmType = KLDRTYPE_EXECUTABLE_FIXED; break;
    464465        case MH_DYLIB:      pMod->enmType = KLDRTYPE_SHARED_LIBRARY_RELOCATABLE; break;
     466        case MH_BUNDLE:     pMod->enmType = KLDRTYPE_SHARED_LIBRARY_RELOCATABLE; break;
    465467        case MH_KEXT_BUNDLE:pMod->enmType = KLDRTYPE_SHARED_LIBRARY_RELOCATABLE; break;
    466468        case MH_DSYM:       pMod->enmType = KLDRTYPE_DEBUG_INFO; break;
     
    709711                                KLDRMODMACHO_CHECK_RETURN(!pSect->reserved1, KLDR_ERR_MACHO_BAD_SECTION); \
    710712                                /* reserved2 == stub size. 0 has been seen (corecrypto.kext) */ \
    711                                 KLDRMODMACHO_CHECK_RETURN(pSect->reserved2 > 64, KLDR_ERR_MACHO_BAD_SECTION); \
     713                                KLDRMODMACHO_CHECK_RETURN(pSect->reserved2 < 64, KLDR_ERR_MACHO_BAD_SECTION); \
    712714                                fFileBits = 1; \
    713715                                break; \
     
    815817                            case MH_EXECUTE: \
    816818                            case MH_DYLIB: \
     819                            case MH_BUNDLE: \
    817820                            case MH_DSYM: \
    818821                            case MH_KEXT_BUNDLE: \
     
    10291032        case MH_EXECUTE:
    10301033        case MH_DYLIB:
     1034        case MH_BUNDLE:
    10311035        case MH_DSYM:
    10321036        case MH_KEXT_BUNDLE:
     
    11921196                        /* Section data extract. */ \
    11931197                        pSectExtra->cb = pSect->size; \
    1194                         pSectExtra->RVA = pSect->addr; \
     1198                        pSectExtra->RVA = pSect->addr - pDstSeg->LinkAddress; \
    11951199                        pSectExtra->LinkAddress = pSect->addr; \
    11961200                        if (pSect->offset) \
     
    12461250                    case MH_EXECUTE:
    12471251                    case MH_DYLIB: /** @todo ??? */
     1252                    case MH_BUNDLE:  /** @todo ??? */
    12481253                    case MH_DSYM:
    12491254                    case MH_KEXT_BUNDLE:
     
    12671272    kHlpAssert(pDstSeg == &pModMachO->pMod->aSegments[cSegments - pModMachO->fMakeGot]);
    12681273
    1269 #if 0
    1270     {
    1271         /*
    1272          * Make sure the segments are sorted by link address, or we'll get screwed
    1273          * further down.
    1274          */
    1275         KLDRADDR cb1;
    1276         KSIZE cb2;
    1277         KU32 i;
    1278         KU32 c = pDstSeg - &pModMachO->pMod->aSegments[0];
    1279 
    1280         pDstSeg = &pModMachO->pMod->aSegments[0];
    1281         for (i = 0; i < c - 1; i++)
    1282         {
    1283             KLDRADDR LinkAddress = pDstSeg[i + 1].LinkAddress;
    1284             if (LinkAddress < pDstSeg[i].LinkAddress)
    1285             {
    1286                 /* Gotta move the next segment, find the correct location. */
    1287                 KLDRMODMACHOSEG TmpSegExtra;
    1288                 KLDRSEG TmpSeg;
    1289                 KU32 j = i;
    1290                 KU32 cShift = 1;
    1291 
    1292                 while (j > 0 && LinkAddress < pDstSeg[j - 1].LinkAddress)
    1293                     j--, cShift++;
    1294 
    1295                 TmpSegExtra = pModMachO->aSegments[i + 1];
    1296                 kHlpMemMove(&pModMachO->aSegments[j + 1], &pModMachO->aSegments[j],
    1297                             cShift * sizeof(pModMachO->aSegments[0]));
    1298                 pModMachO->aSegments[j] = TmpSegExtra;
    1299 
    1300                 TmpSeg = pDstSeg[i + 1];
    1301                 kHlpMemMove(&pDstSeg[j + 1], &pDstSeg[j], cShift * sizeof(pDstSeg[0]));
    1302                 pDstSeg[j] = TmpSeg;
    1303             }
    1304         }
    1305 
    1306         /*
    1307          * Adjust mapping addresses calculating the image size.
    1308          */
    1309         pDstSeg = &pModMachO->pMod->aSegments[0];
    1310         for (i = 0; i < cSegments - 1; i++)
    1311         {
    1312             cb1 = pDstSeg[i + 1].LinkAddress - pDstSeg[i].LinkAddress;
    1313             cb2 = (KSIZE)cb1;
    1314             pDstSeg[i].cbMapped = cb2 == cb1 ? cb2 : ~(KSIZE)0;
    1315         }
    1316         cb1 = KLDR_ALIGN_ADDR(pDstSeg[i].cb, pDstSeg[i].Alignment);
    1317         cb2 = (KSIZE)cb1;
    1318         pDstSeg[i].cbMapped = cb2 == cb1 ? cb2 : ~(KSIZE)0;
    1319 
    1320         pModMachO->cbImage = pDstSeg[i].RVA + cb1;
    1321     }
    1322 #else
    13231274    /*
    13241275     * Adjust mapping addresses calculating the image size.
    13251276     */
    13261277    {
    1327         KLDRADDR uNextRVA = 0;
    1328         KLDRADDR cb;
    1329         KU32     c;
     1278        PKLDRMODMACHOSECT   pSectExtraItr;
     1279        KLDRADDR            uNextRVA = 0;
     1280        KLDRADDR            cb;
     1281        KU32                c;
    13301282
    13311283        /* Adjust RVAs. */
     
    13531305        pDstSeg->cbMapped = (KSIZE)cb == cb ? (KSIZE)cb : KSIZE_MAX;
    13541306
    1355         /* And finally, the image size. */
     1307        /* Set the image size. */
    13561308        pModMachO->cbImage = pDstSeg->RVA + cb;
    1357     }
    1358 #endif
    1359 
     1309
     1310        /* Fixup the section RVA (internal). */
     1311        c        = cSegments - pModMachO->fMakeGot;
     1312        uNextRVA = pModMachO->cbImage;
     1313        pDstSeg  = &pModMachO->pMod->aSegments[0];
     1314        for (pSectExtraItr = pModMachO->paSections; pSectExtraItr != pSectExtra; pSectExtraItr++)
     1315        {
     1316            if (pSectExtraItr->iSegment < c)
     1317                pSectExtraItr->RVA += pDstSeg[pSectExtraItr->iSegment].RVA;
     1318            else
     1319            {
     1320                pSectExtraItr->RVA = uNextRVA;
     1321                uNextRVA += KLDR_ALIGN_ADDR(pSectExtraItr->cb, 64);
     1322            }
     1323        }
     1324    }
    13601325
    13611326    /*
     
    16461611        || pModMachO->Hdr.filetype == MH_EXECUTE /** @todo dylib, execute, dsym: symbols */
    16471612        || pModMachO->Hdr.filetype == MH_DYLIB
     1613        || pModMachO->Hdr.filetype == MH_BUNDLE
    16481614        || pModMachO->Hdr.filetype == MH_DSYM
    16491615        || pModMachO->Hdr.filetype == MH_KEXT_BUNDLE)
     
    17791745        {
    17801746            PKLDRMODMACHOSECT pSect;
    1781             KLDRADDR RVA;
    1782             if ((KU32)(paSyms[iSymbol].n_sect - 1) >= pModMachO->cSections)
    1783                 return KLDR_ERR_MACHO_BAD_SYMBOL;
     1747            KLDRADDR offSect;
     1748            KLDRMODMACHO_CHECK_RETURN((KU32)(paSyms[iSymbol].n_sect - 1) < pModMachO->cSections, KLDR_ERR_MACHO_BAD_SYMBOL);
    17841749            pSect = &pModMachO->paSections[paSyms[iSymbol].n_sect - 1];
    17851750
    1786             RVA = paSyms[iSymbol].n_value - pModMachO->LinkAddress;
    1787             if (RVA - pSect->RVA >= pSect->cb)
    1788                 return KLDR_ERR_MACHO_BAD_SYMBOL;
     1751            offSect = paSyms[iSymbol].n_value - pSect->LinkAddress;
     1752            KLDRMODMACHO_CHECK_RETURN(   offSect <= pSect->cb
     1753                                      || (   paSyms[iSymbol].n_sect == 1 /* special hack for __mh_execute_header */
     1754                                          && offSect == 0U - pSect->RVA
     1755                                          && pModMachO->Hdr.filetype != MH_OBJECT),
     1756                                      KLDR_ERR_MACHO_BAD_SYMBOL);
    17891757            if (puValue)
    1790                 *puValue = RVA + BaseAddress;
     1758                *puValue = BaseAddress + pSect->RVA + offSect;
    17911759
    17921760            if (    pfKind
     
    19051873        {
    19061874            PKLDRMODMACHOSECT pSect;
    1907             KLDRADDR RVA;
    1908             if ((KU32)(paSyms[iSymbol].n_sect - 1) >= pModMachO->cSections)
    1909                 return KLDR_ERR_MACHO_BAD_SYMBOL;
     1875            KLDRADDR offSect;
     1876            KLDRMODMACHO_CHECK_RETURN((KU32)(paSyms[iSymbol].n_sect - 1) < pModMachO->cSections, KLDR_ERR_MACHO_BAD_SYMBOL);
    19101877            pSect = &pModMachO->paSections[paSyms[iSymbol].n_sect - 1];
    19111878
    1912             RVA = paSyms[iSymbol].n_value - pModMachO->LinkAddress;
    1913             if (RVA - pSect->RVA >= pSect->cb)
    1914                 return KLDR_ERR_MACHO_BAD_SYMBOL;
     1879            offSect = paSyms[iSymbol].n_value - pSect->LinkAddress;
     1880            KLDRMODMACHO_CHECK_RETURN(   offSect <= pSect->cb
     1881                                      || (   paSyms[iSymbol].n_sect == 1 /* special hack for __mh_execute_header */
     1882                                          && offSect == 0U - pSect->RVA
     1883                                          && pModMachO->Hdr.filetype != MH_OBJECT),
     1884                                      KLDR_ERR_MACHO_BAD_SYMBOL);
    19151885            if (puValue)
    1916                 *puValue = RVA + BaseAddress;
     1886                *puValue = BaseAddress + pSect->RVA + offSect;
    19171887
    19181888            if (    pfKind
     
    19601930        || pModMachO->Hdr.filetype == MH_EXECUTE /** @todo dylib, execute, dsym: symbols */
    19611931        || pModMachO->Hdr.filetype == MH_DYLIB
     1932        || pModMachO->Hdr.filetype == MH_BUNDLE
    19621933        || pModMachO->Hdr.filetype == MH_DSYM
    19631934        || pModMachO->Hdr.filetype == MH_KEXT_BUNDLE)
     
    20402011
    20412012        /* name */
    2042         if ((KU32)paSyms[iSym].n_un.n_strx >= cchStrings)
    2043             return KLDR_ERR_MACHO_BAD_SYMBOL;
     2013        KLDRMODMACHO_CHECK_RETURN((KU32)paSyms[iSym].n_un.n_strx < cchStrings, KLDR_ERR_MACHO_BAD_SYMBOL);
    20442014        psz = &pchStrings[paSyms[iSym].n_un.n_strx];
    20452015        cch = kHlpStrLen(psz);
     
    20562026            {
    20572027                PKLDRMODMACHOSECT pSect;
    2058                 if ((KU32)(paSyms[iSym].n_sect - 1) >= pModMachO->cSections)
    2059                     return KLDR_ERR_MACHO_BAD_SYMBOL;
     2028                KLDRMODMACHO_CHECK_RETURN((KU32)(paSyms[iSym].n_sect - 1) < pModMachO->cSections, KLDR_ERR_MACHO_BAD_SYMBOL);
    20602029                pSect = &pModMachO->paSections[paSyms[iSym].n_sect - 1];
    20612030
    2062                 uValue = paSyms[iSym].n_value - pModMachO->LinkAddress;
    2063                 if (uValue - pSect->RVA > pSect->cb)
    2064                     return KLDR_ERR_MACHO_BAD_SYMBOL;
    2065                 uValue += BaseAddress;
     2031                uValue = paSyms[iSym].n_value - pSect->LinkAddress;
     2032                KLDRMODMACHO_CHECK_RETURN(   uValue <= pSect->cb
     2033                                          || (   paSyms[iSym].n_sect == 1 /* special hack for __mh_execute_header */
     2034                                              && uValue == 0U - pSect->RVA
     2035                                              && pModMachO->Hdr.filetype != MH_OBJECT),
     2036                                          KLDR_ERR_MACHO_BAD_SYMBOL);
     2037                uValue += BaseAddress + pSect->RVA;
    20662038
    20672039                if (pSect->fFlags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SELF_MODIFYING_CODE))
     
    21512123
    21522124        /* name */
    2153         if ((KU32)paSyms[iSym].n_un.n_strx >= cchStrings)
    2154             return KLDR_ERR_MACHO_BAD_SYMBOL;
     2125        KLDRMODMACHO_CHECK_RETURN((KU32)paSyms[iSym].n_un.n_strx < cchStrings, KLDR_ERR_MACHO_BAD_SYMBOL);
    21552126        psz = &pchStrings[paSyms[iSym].n_un.n_strx];
    21562127        cch = kHlpStrLen(psz);
     
    21672138            {
    21682139                PKLDRMODMACHOSECT pSect;
    2169                 if ((KU32)(paSyms[iSym].n_sect - 1) >= pModMachO->cSections)
    2170                     return KLDR_ERR_MACHO_BAD_SYMBOL;
     2140                KLDRMODMACHO_CHECK_RETURN((KU32)(paSyms[iSym].n_sect - 1) < pModMachO->cSections, KLDR_ERR_MACHO_BAD_SYMBOL);
    21712141                pSect = &pModMachO->paSections[paSyms[iSym].n_sect - 1];
    21722142
    2173                 uValue = paSyms[iSym].n_value - pModMachO->LinkAddress;
    2174                 if (uValue - pSect->RVA > pSect->cb)
    2175                     return KLDR_ERR_MACHO_BAD_SYMBOL;
    2176                 uValue += BaseAddress;
     2143                uValue = paSyms[iSym].n_value - pSect->LinkAddress;
     2144                KLDRMODMACHO_CHECK_RETURN(   uValue <= pSect->cb
     2145                                          || (   paSyms[iSym].n_sect == 1 /* special hack for __mh_execute_header */
     2146                                              && uValue == 0U - pSect->RVA
     2147                                              && pModMachO->Hdr.filetype != MH_OBJECT),
     2148                                          KLDR_ERR_MACHO_BAD_SYMBOL);
     2149                uValue += BaseAddress + pSect->RVA;
    21772150
    21782151                if (pSect->fFlags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SELF_MODIFYING_CODE))
     
    25522525
    25532526                /* Get the symbol name. */
    2554                 if ((KU32)paSyms[iSym].n_un.n_strx >= pModMachO->cchStrings)
    2555                     return KLDR_ERR_MACHO_BAD_SYMBOL;
     2527                KLDRMODMACHO_CHECK_RETURN((KU32)paSyms[iSym].n_un.n_strx < pModMachO->cchStrings, KLDR_ERR_MACHO_BAD_SYMBOL);
    25562528                pszSymbol = &pModMachO->pchStrings[paSyms[iSym].n_un.n_strx];
    25572529                cchSymbol = kHlpStrLen(pszSymbol);
     
    26132585
    26142586                 /* Get the symbol name. */
    2615                 if (paSyms[iSym].n_un.n_strx >= pModMachO->cchStrings)
    2616                     return KLDR_ERR_MACHO_BAD_SYMBOL;
     2587                KLDRMODMACHO_CHECK_RETURN(paSyms[iSym].n_un.n_strx < pModMachO->cchStrings, KLDR_ERR_MACHO_BAD_SYMBOL);
    26172588                pszSymbol = &pModMachO->pchStrings[paSyms[iSym].n_un.n_strx];
    26182589                cchSymbol = kHlpStrLen(pszSymbol);
     
    28182789                    {
    28192790                        PKLDRMODMACHOSECT pSymSect;
    2820                         if ((KU32)pSym->n_sect - 1 > pModMachO->cSections)
    2821                             return KLDR_ERR_MACHO_BAD_SYMBOL;
     2791                        KLDRMODMACHO_CHECK_RETURN((KU32)pSym->n_sect - 1 <= pModMachO->cSections, KLDR_ERR_MACHO_BAD_SYMBOL);
    28222792                        pSymSect = &pModMachO->paSections[pSym->n_sect - 1];
    28232793
     
    30743044                        case MACHO_N_UNDF:
    30753045                            /* branch to an external symbol may have to take a short detour. */
    3076                             if (    Fixup.r.r_type == X86_64_RELOC_BRANCH
    3077                                 &&      SymAddr + Fixup.r.r_address + pFixupSect->RVA + NewBaseAddress
    3078                                       - pSym->n_value
    3079                                       + KU64_C(0x80000000)
     3046                            if (   Fixup.r.r_type == X86_64_RELOC_BRANCH
     3047                                &&       SymAddr + Fixup.r.r_address + pFixupSect->RVA + NewBaseAddress
     3048                                       - pSym->n_value
     3049                                       + KU64_C(0x80000000)
    30803050                                    >= KU64_C(0xffffff20))
    30813051                                SymAddr += pModMachO->cbJmpStub * Fixup.r.r_symbolnum + pModMachO->JmpStubsRVA + NewBaseAddress;
Note: See TracChangeset for help on using the changeset viewer.