Esempio n. 1
0
/**
 * 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)
Esempio n. 2
0
/**
 * 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;
}
Esempio n. 3
0
/** @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);
}