Ignore:
Timestamp:
Feb 19, 2009, 1:56:15 AM (16 years ago)
Author:
bird
Message:

A blind shot at FAT Mach-O images.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kLdr/kLdrModMachO.c

    r23 r25  
    127127    void                   *pvMapping;
    128128
     129    /** The offset of the image. (FAT fun.) */
     130    KLDRFOFF                offImage;
    129131    /** The link address. */
    130132    KLDRADDR                LinkAddress;
     
    184186                                    PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser);
    185187
    186 static int  kldrModMachODoCreate(PKRDR pRdr, PKLDRMODMACHO *ppMod);
    187 static int  kldrModMachOPreParseLoadCommands(KU8 *pbLoadCommands, const mach_header_32_t *pHdr, PKRDR pRdr,
     188static int  kldrModMachODoCreate(PKRDR pRdr, KLDRFOFF offImage, PKLDRMODMACHO *ppMod);
     189static int  kldrModMachOPreParseLoadCommands(KU8 *pbLoadCommands, const mach_header_32_t *pHdr, PKRDR pRdr, KLDRFOFF offImage,
    188190                                             KU32 *pcSegments, KU32 *pcSections, KU32 *pcbStringPool);
    189191static int  kldrModMachOParseLoadCommands(PKLDRMODMACHO pModMachO, char *pbStringPool, KU32 cbStringPool);
     
    228230 * @param   pOps            Pointer to the registered method table.
    229231 * @param   pRdr            The file provider instance to use.
     232 * @param   fFlags          Flags, MBZ.
     233 * @param   enmCpuArch      The desired CPU architecture. KCPUARCH_UNKNOWN means
     234 *                          anything goes, but with a preference for the current
     235 *                          host architecture.
    230236 * @param   offNewHdr       The offset of the new header in MZ files. -1 if not found.
    231237 * @param   ppMod           Where to store the module instance pointer.
    232238 */
    233 static int kldrModMachOCreate(PCKLDRMODOPS pOps, PKRDR pRdr, KLDRFOFF offNewHdr, PPKLDRMOD ppMod)
     239static int kldrModMachOCreate(PCKLDRMODOPS pOps, PKRDR pRdr, KU32 fFlags, KCPUARCH enmCpuArch, KLDRFOFF offNewHdr, PPKLDRMOD ppMod)
    234240{
    235241    PKLDRMODMACHO pModMachO;
     
    239245     * Create the instance data and do a minimal header validation.
    240246     */
    241     rc = kldrModMachODoCreate(pRdr, &pModMachO);
     247    rc = kldrModMachODoCreate(pRdr, offNewHdr == -1 ? 0 : offNewHdr, &pModMachO);
    242248    if (!rc)
    243249    {
    244         pModMachO->pMod->pOps = pOps;
    245         pModMachO->pMod->u32Magic = KLDRMOD_MAGIC;
    246         *ppMod = pModMachO->pMod;
    247         return 0;
     250
     251        /*
     252         * Match up against the requested CPU architecture.
     253         */
     254        if (    enmCpuArch == KCPUARCH_UNKNOWN
     255            ||  pModMachO->pMod->enmArch == enmCpuArch)
     256        {
     257            pModMachO->pMod->pOps = pOps;
     258            pModMachO->pMod->u32Magic = KLDRMOD_MAGIC;
     259            *ppMod = pModMachO->pMod;
     260            return 0;
     261        }
     262        rc = KLDR_ERR_CPU_ARCH_MISMATCH;
    248263    }
    249264    if (pModMachO)
     
    260275 * simplify cleanup on failure.
    261276 */
    262 static int kldrModMachODoCreate(PKRDR pRdr, PKLDRMODMACHO *ppModMachO)
     277static int kldrModMachODoCreate(PKRDR pRdr, KLDRFOFF offImage, PKLDRMODMACHO *ppModMachO)
    263278{
    264279    union
     
    286301     * Read the Mach-O header.
    287302     */
    288     rc = kRdrRead(pRdr, &s, sizeof(s), 0);
     303    rc = kRdrRead(pRdr, &s, sizeof(s), offImage);
    289304    if (rc)
    290305        return rc;
     
    327342        return KERR_NO_MEMORY;
    328343    rc = kRdrRead(pRdr, pbLoadCommands, s.Hdr32.sizeofcmds,
    329                         s.Hdr32.magic == IMAGE_MACHO32_SIGNATURE
    330                      || s.Hdr32.magic == IMAGE_MACHO32_SIGNATURE_OE
    331                      ? sizeof(mach_header_32_t) : sizeof(mach_header_64_t));
     344                     s.Hdr32.magic == IMAGE_MACHO32_SIGNATURE
     345                  || s.Hdr32.magic == IMAGE_MACHO32_SIGNATURE_OE
     346                  ? sizeof(mach_header_32_t) + offImage
     347                  : sizeof(mach_header_64_t) + offImage);
    332348    if (!rc)
    333         rc = kldrModMachOPreParseLoadCommands(pbLoadCommands, &s.Hdr32, pRdr, &cSegments, &cSections, &cbStringPool);
     349        rc = kldrModMachOPreParseLoadCommands(pbLoadCommands, &s.Hdr32, pRdr, offImage, &cSegments, &cSections, &cbStringPool);
    334350    if (rc)
    335351    {
     
    354370    *ppModMachO = pModMachO;
    355371    pModMachO->pbLoadCommands = pbLoadCommands;
     372    pModMachO->offImage = offImage;
    356373
    357374    /* KLDRMOD */
     
    475492 * @param   pHdr            The header.
    476493 * @param   pRdr            The file reader.
     494 * @param   offImage        The image header (FAT fun).
    477495 * @param   pcSegments      Where to store the segment count.
    478496 * @param   pcSegments      Where to store the section count.
    479497 * @param   pcbStringPool   Where to store the string pool size.
    480498 */
    481 static int  kldrModMachOPreParseLoadCommands(KU8 *pbLoadCommands, const mach_header_32_t *pHdr, PKRDR pRdr,
     499static int  kldrModMachOPreParseLoadCommands(KU8 *pbLoadCommands, const mach_header_32_t *pHdr, PKRDR pRdr, KLDRFOFF offImage,
    482500                                             KU32 *pcSegments, KU32 *pcSections, KU32 *pcbStringPool)
    483501{
     
    492510        uuid_command_t       *pUuid;
    493511    } u;
    494     const KU64 cbFile = kRdrSize(pRdr);
     512    const KU64 cbFile = kRdrSize(pRdr) - offImage;
    495513    KU32 cSegments = 0;
    496514    KU32 cSections = 0;
     
    10621080                            pSectExtra->RVA = pSect->addr;
    10631081                            pSectExtra->LinkAddress = pSect->addr;
    1064                             pSectExtra->offFile = pSect->offset ? pSect->offset : -1;
     1082                            pSectExtra->offFile = pSect->offset ? pSect->offset + pModMachO->offImage : -1;
    10651083                            pSectExtra->cFixups = pSect->nreloc;
    10661084                            pSectExtra->paFixups = NULL;
    1067                             pSectExtra->offFixups = pSect->nreloc ? pSect->reloff : -1;
     1085                            pSectExtra->offFixups = pSect->nreloc ? pSect->reloff + pModMachO->offImage : -1;
    10681086                            pSectExtra->fFlags = pSect->flags;
    10691087                            pSectExtra->iSegment = pSegExtra - &pModMachO->aSegments[0];
     
    10991117                                pSeg->Alignment = (1 << pSect->align);
    11001118                                pSeg->LinkAddress = pSect->addr;
    1101                                 pSeg->offFile = pSect->offset ? pSect->offset : -1;
     1119                                pSeg->offFile = pSect->offset ? pSect->offset + pModMachO->offImage : -1;
    11021120                                pSeg->cbFile  = pSect->offset ? pSect->size : -1;
    11031121                                pSeg->RVA = pSect->addr - pModMachO->LinkAddress;
     
    11251143                                    &&  pSeg[-1].cbFile == pSeg[-1].cb)
    11261144                                {
    1127                                     int fOk = pSeg[-1].offFile + (pSect->addr - pSeg[-1].LinkAddress) == pSect->offset
     1145                                    int fOk = pSeg[-1].offFile + (pSect->addr - pSeg[-1].LinkAddress) == pSect->offset + pModMachO->offImage
    11281146                                           && pSect[-1].offset
    1129                                            && pSeg[-1].offFile + pSeg[-1].cbFile == pSect[-1].offset + pSect[-1].size;
     1147                                           && pSeg[-1].offFile + pSeg[-1].cbFile == pSect[-1].offset + pModMachO->offImage + pSect[-1].size;
    11301148                                    /* more checks? */
    11311149                                    if (fOk)
     
    11791197                            pSectExtra->RVA = pSect->addr;
    11801198                            pSectExtra->LinkAddress = pSect->addr;
    1181                             pSectExtra->offFile = pSect->offset ? pSect->offset : -1;
     1199                            pSectExtra->offFile = pSect->offset ? pSect->offset + pModMachO->offImage : -1;
    11821200                            pSectExtra->cFixups = pSect->nreloc;
    11831201                            pSectExtra->paFixups = NULL;
    1184                             pSectExtra->offFixups = pSect->nreloc ? pSect->reloff : -1;
     1202                            pSectExtra->offFixups = pSect->nreloc ? pSect->reloff + pModMachO->offImage : -1;
    11851203                            pSectExtra->fFlags = pSect->flags;
    11861204                            pSectExtra->iSegment = pSegExtra - &pModMachO->aSegments[0];
     
    12161234                                pSeg->Alignment = (1 << pSect->align);
    12171235                                pSeg->LinkAddress = pSect->addr;
    1218                                 pSeg->offFile = pSect->offset ? pSect->offset : -1;
     1236                                pSeg->offFile = pSect->offset ? pSect->offset + pModMachO->offImage : -1;
    12191237                                pSeg->cbFile  = pSect->offset ? pSect->size : -1;
    12201238                                pSeg->RVA = pSect->addr - pModMachO->LinkAddress;
     
    12421260                                    &&  pSeg[-1].cbFile == pSeg[-1].cb)
    12431261                                {
    1244                                     int fOk = pSeg[-1].offFile + (pSect->addr - pSeg[-1].LinkAddress) == pSect->offset
     1262                                    int fOk = pSeg[-1].offFile + (pSect->addr - pSeg[-1].LinkAddress) == pSect->offset + pModMachO->offImage
    12451263                                           && pSect[-1].offset
    1246                                            && pSeg[-1].offFile + pSeg[-1].cbFile == pSect[-1].offset + pSect[-1].size;
     1264                                           && pSeg[-1].offFile + pSeg[-1].cbFile == pSect[-1].offset + pModMachO->offImage + pSect[-1].size;
    12471265                                    /* more checks? */
    12481266                                    if (fOk)
     
    12771295                {
    12781296                    case MH_OBJECT:
    1279                         pModMachO->offSymbols = u.pSymTab->symoff;
     1297                        pModMachO->offSymbols = u.pSymTab->symoff + pModMachO->offImage;
    12801298                        pModMachO->cSymbols = u.pSymTab->nsyms;
    1281                         pModMachO->offStrings = u.pSymTab->stroff;
     1299                        pModMachO->offStrings = u.pSymTab->stroff + pModMachO->offImage;
    12821300                        pModMachO->cchStrings = u.pSymTab->strsize;
    12831301                        break;
Note: See TracChangeset for help on using the changeset viewer.