コード例 #1
0
static bool getResourceFromMappedFile(const char * filename, const byte * start_addr, MemoryBuffer &data, const char * type, unsigned id)
{
#if defined(_WIN32) || defined (_USE_BINUTILS)
    throwUnexpected();
#elif defined(__APPLE__)
    VStringBuffer sectname("%s_%u", type, id);
    // The first bytes are the Mach-O header
    const struct mach_header_64 *mh = (const struct mach_header_64 *) start_addr;
    if (mh->magic != MH_MAGIC_64)
    {
        DBGLOG("Failed to extract resource %s: Does not appear to be a Mach-O 64-bit binary", filename);
        return false;
    }

    unsigned long len = 0;
    unsigned char *data2 = getsectiondata(mh, "__TEXT", sectname.str(), &len);
    data.append(len, data2);
    return true;
#else
    // The first bytes are the ELF header
    const Elf64_Ehdr * hdr = (const Elf64_Ehdr *) start_addr;
    if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0)
    {
        DBGLOG("Failed to extract resource %s: Does not appear to be a ELF binary", filename);
        return false;
    }
    if (hdr->e_ident[EI_CLASS] != ELFCLASS64)
    {
        DBGLOG("Failed to extract resource %s: Does not appear to be a ELF 64-bit binary", filename);
        return false;
    }

    //Check that there is a symbol table for the sections.
    if (hdr->e_shstrndx == SHN_UNDEF)
    {
        DBGLOG("Failed to extract resource %s: Does not include a section symbol table", filename);
        return false;
    }

    //Now walk the sections comparing the section names
    Elf64_Half numSections = hdr->e_shnum;
    const Elf64_Shdr * sectionHeaders = reinterpret_cast<const Elf64_Shdr *>(start_addr + hdr->e_shoff);
    const Elf64_Shdr & symbolTableSection = sectionHeaders[hdr->e_shstrndx];
    const char * symbolTable = (const char *)start_addr + symbolTableSection.sh_offset;
    VStringBuffer sectname("%s_%u", type, id);
    for (unsigned iSect= 0; iSect < numSections; iSect++)
    {
        const Elf64_Shdr & section = sectionHeaders[iSect];
        const char * sectionName = symbolTable + section.sh_name;
        if (streq(sectionName, sectname))
        {
            data.append(section.sh_size, start_addr + section.sh_offset);
            return true;
        }
    }

    DBGLOG("Failed to extract resource %s: Does not include a matching entry", filename);
    return false;
#endif
}
コード例 #2
0
ファイル: thorplugin.cpp プロジェクト: hhy5277/HPCC-Platform
extern bool getResourceFromFile(const char *filename, MemoryBuffer &data, const char * type, unsigned id)
{
#ifdef _WIN32
    HINSTANCE dllHandle = LoadLibraryEx(filename, NULL, LOAD_LIBRARY_AS_DATAFILE|LOAD_LIBRARY_AS_IMAGE_RESOURCE);
    if (dllHandle == NULL)
        dllHandle = LoadLibraryEx(filename, NULL, LOAD_LIBRARY_AS_DATAFILE); // the LOAD_LIBRARY_AS_IMAGE_RESOURCE flag is not supported on all versions of Windows
    if (dllHandle == NULL)
    {
        DBGLOG("Failed to load library %s: %d", filename, GetLastError());
        return false;
    }
    HRSRC hrsrc = FindResource(dllHandle, MAKEINTRESOURCE(id), type);
    if (!hrsrc)
        return false;
    size32_t len = SizeofResource(dllHandle, hrsrc);
    const void *rdata = (const void *) LoadResource(dllHandle, hrsrc);
    data.append(len, rdata);
    FreeLibrary(dllHandle);
    return true;
#elif defined (_USE_BINUTILS)
    CriticalBlock block(bfdCs);
    bfd_init ();
    bfd *file = bfd_openr(filename, NULL);
    if (file)
    {
        StringBuffer sectionName;
        sectionName.append(type).append("_").append(id).append(".data");
        SecScanParam param(data, sectionName.str());
        if (bfd_check_format (file, bfd_object))
            bfd_map_over_sections (file, secscan, &param);
        bfd_close (file);
   }
   return data.length() != 0;
#else
    struct stat stat_buf;
    VStringBuffer sectname("%s_%u", type, id);
    int fd = open(filename, O_RDONLY);
    if (fd == -1 || fstat(fd, &stat_buf) == -1)
    {
        DBGLOG("Failed to load library %s: %d", filename, errno);
        return false;
    }

    bool ok = false;
    __uint64 size = stat_buf.st_size;
    const byte *start_addr = (const byte *) mmap(0, size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
    if (start_addr == MAP_FAILED)
    {
        DBGLOG("Failed to load library %s: %d", filename, errno);
    }
    else
    {
        ok = getResourceFromMappedFile(filename, start_addr, data, type, id);
        munmap((void *)start_addr, size);
    }
    close(fd);
    return ok;
#endif
}