/** * Open part with reader. * * @returns iprt status code. * @param pReader The loader reader instance which will provide the raw image bits. * @param fFlags Reserved, MBZ. * @param enmArch Architecture specifier. * @param phMod Where to store the handle. */ int rtldrOpenWithReader(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, PRTLDRMOD phMod) { /* * Read and verify the file signature. */ union { char ach[4]; uint16_t au16[2]; uint32_t u32; } uSign; int rc = pReader->pfnRead(pReader, &uSign, sizeof(uSign), 0); if (RT_FAILURE(rc)) return rc; #ifndef LDR_WITH_KLDR if ( uSign.au16[0] != IMAGE_DOS_SIGNATURE && uSign.u32 != IMAGE_NT_SIGNATURE && uSign.u32 != IMAGE_ELF_SIGNATURE && uSign.au16[0] != IMAGE_LX_SIGNATURE) { Log(("rtldrOpenWithReader: %s: unknown magic %#x / '%.4s\n", pReader->pfnLogName(pReader), uSign.u32, &uSign.ach[0])); return VERR_INVALID_EXE_SIGNATURE; } #endif uint32_t offHdr = 0; if (uSign.au16[0] == IMAGE_DOS_SIGNATURE) { rc = pReader->pfnRead(pReader, &offHdr, sizeof(offHdr), RT_OFFSETOF(IMAGE_DOS_HEADER, e_lfanew)); if (RT_FAILURE(rc)) return rc; if (offHdr <= sizeof(IMAGE_DOS_HEADER)) { Log(("rtldrOpenWithReader: %s: no new header / invalid offset %#RX32\n", pReader->pfnLogName(pReader), offHdr)); return VERR_INVALID_EXE_SIGNATURE; } rc = pReader->pfnRead(pReader, &uSign, sizeof(uSign), offHdr); if (RT_FAILURE(rc)) return rc; if ( uSign.u32 != IMAGE_NT_SIGNATURE && uSign.au16[0] != IMAGE_LX_SIGNATURE && uSign.au16[0] != IMAGE_LE_SIGNATURE && uSign.au16[0] != IMAGE_NE_SIGNATURE) { Log(("rtldrOpenWithReader: %s: unknown new magic %#x / '%.4s\n", pReader->pfnLogName(pReader), uSign.u32, &uSign.ach[0])); return VERR_INVALID_EXE_SIGNATURE; } } /* * Create image interpreter instance depending on the signature. */ if (uSign.u32 == IMAGE_NT_SIGNATURE) #ifdef LDR_WITH_PE rc = rtldrPEOpen(pReader, fFlags, enmArch, offHdr, phMod); #else rc = VERR_PE_EXE_NOT_SUPPORTED; #endif else if (uSign.u32 == IMAGE_ELF_SIGNATURE)
/** * Open an ELF image. * * @returns iprt status code. * @param pReader The loader reader instance which will provide the raw image bits. * @param fFlags Reserved, MBZ. * @param enmArch Architecture specifier. * @param phLdrMod Where to store the handle. */ int rtldrELFOpen(PRTLDRREADER pReader, uint32_t fFlags, RTLDRARCH enmArch, PRTLDRMOD phLdrMod) { const char *pszLogName = pReader->pfnLogName(pReader); NOREF(pszLogName); /* * Read the ident to decide if this is 32-bit or 64-bit * and worth dealing with. */ uint8_t e_ident[EI_NIDENT]; int rc = pReader->pfnRead(pReader, &e_ident, sizeof(e_ident), 0); if (RT_FAILURE(rc)) return rc; if ( e_ident[EI_MAG0] != ELFMAG0 || e_ident[EI_MAG1] != ELFMAG1 || e_ident[EI_MAG2] != ELFMAG2 || e_ident[EI_MAG3] != ELFMAG3 || ( e_ident[EI_CLASS] != ELFCLASS32 && e_ident[EI_CLASS] != ELFCLASS64) ) { Log(("RTLdrELF: %s: Unsupported/invalid ident %.*Rhxs\n", pszLogName, sizeof(e_ident), e_ident)); return VERR_BAD_EXE_FORMAT; } if (e_ident[EI_DATA] != ELFDATA2LSB) { Log(("RTLdrELF: %s: ELF endian %x is unsupported\n", e_ident[EI_DATA])); return VERR_LDRELF_ODD_ENDIAN; } if (e_ident[EI_CLASS] == ELFCLASS32) rc = rtldrELF32Open(pReader, fFlags, enmArch, phLdrMod); else rc = rtldrELF64Open(pReader, fFlags, enmArch, phLdrMod); return rc; }
/** @copydoc KLDRRDROPS::pfnRead */ static int rtkldrRdr_Read( PKRDR pRdr, void *pvBuf, KSIZE cb, KFOFF off) { PRTLDRREADER pReader = ((PRTKLDRRDR)pRdr)->pReader; int rc = pReader->pfnRead(pReader, pvBuf, cb, off); return rtkldrConvertErrorFromIPRT(rc); }