Пример #1
0
static void *
thread(void *cookie)
{

	start();
	lookups((int)(uintptr_t)cookie);
	end();

	return NULL;
}
Пример #2
0
std::shared_ptr<Visual> CastleWindow::LoadMeshPNT1(std::string const& name)
{
    // Get the positions, normals, and texture coordinates.
    std::string filename = mEnvironment.GetPath(name);
    std::ifstream inFile(filename);
    std::vector<Vector3<float>> positions, normals;
    std::vector<Vector2<float>> tcoords;
    GetTuple3(inFile, positions);
    GetTuple3(inFile, normals);
    GetTuple2(inFile, tcoords);

    // Get the vertices and indices.
    unsigned int numTriangles;
    inFile >> numTriangles;
    std::vector<LookupPNT1> lookups(3 * numTriangles);
    std::vector<LookupPNT1> PNT1Array;
    std::map<LookupPNT1, unsigned int> PNT1Map;
    std::vector<unsigned int> indices;
    for (unsigned int t = 0; t < numTriangles; ++t)
    {
        for (unsigned int j = 0, k = 3 * t; j < 3; ++j, ++k)
        {
            LookupPNT1& lookup = lookups[k];
            inFile >> lookup.PIndex;
            inFile >> lookup.NIndex;
            inFile >> lookup.TIndex;

            auto iter = PNT1Map.find(lookup);
            unsigned int index;
            if (iter != PNT1Map.end())
            {
                // Second or later time the vertex is encountered.
                index = iter->second;
            }
            else
            {
                // First time the vertex is encountered.
                index = static_cast<unsigned int>(PNT1Array.size());
                PNT1Map.insert(std::make_pair(lookup, index));
                PNT1Array.push_back(lookup);
            }
            indices.push_back(index);
        }
    }
    inFile.close();

    // Build the mesh.
    unsigned int numVertices = static_cast<unsigned int>(PNT1Array.size());
    std::shared_ptr<VertexBuffer> vbuffer =
        std::make_shared<VertexBuffer>(mPNT1Format, numVertices);
    VertexPNT1* vertex = vbuffer->Get<VertexPNT1>();
    for (unsigned int i = 0; i < numVertices; ++i)
    {
        LookupPNT1& lookup = PNT1Array[i];
        vertex[i].position = positions[lookup.PIndex];
        vertex[i].normal = normals[lookup.NIndex];
        vertex[i].tcoord = tcoords[lookup.TIndex];
    }

    unsigned int numIndices = static_cast<unsigned int>(indices.size());
    std::shared_ptr<IndexBuffer> ibuffer =
        std::make_shared<IndexBuffer>(IP_TRIMESH, numIndices, sizeof(unsigned int));
    memcpy(ibuffer->GetData(), &indices[0], numIndices * sizeof(unsigned int));

    std::shared_ptr<Visual> mesh = std::make_shared<Visual>(vbuffer, ibuffer);
    return mesh;
}
Пример #3
0
unsigned PackArmPe::processImports() // pass 1
{
    static const unsigned char kernel32dll[] = "COREDLL.dll";
    static const char llgpa[] = "\x0\x0""LoadLibraryW\x0\x0"
                                "GetProcAddressA\x0\x0\x0"
                                "CacheSync";
    //static const char exitp[] = "ExitProcess\x0\x0\x0";

    unsigned dllnum = 0;
    import_desc *im = (import_desc*) (ibuf + IDADDR(PEDIR_IMPORT));
    import_desc * const im_save = im;
    if (IDADDR(PEDIR_IMPORT))
    {
        while (im->dllname)
            dllnum++, im++;
        im = im_save;
    }

    struct udll
    {
        const upx_byte *name;
        const upx_byte *shname;
        unsigned   ordinal;
        unsigned   iat;
        LE32       *lookupt;
        unsigned   npos;
        unsigned   original_position;
        bool       isk32;

        static int __acc_cdecl_qsort compare(const void *p1, const void *p2)
        {
            const udll *u1 = * (const udll * const *) p1;
            const udll *u2 = * (const udll * const *) p2;
            if (u1->isk32) return -1;
            if (u2->isk32) return 1;
            if (!*u1->lookupt) return 1;
            if (!*u2->lookupt) return -1;
            int rc = strcasecmp(u1->name,u2->name);
            if (rc) return rc;
            if (u1->ordinal) return -1;
            if (u2->ordinal) return 1;
            if (!u1->shname) return 1;
            if (!u2->shname) return -1;
            return strlen(u1->shname) - strlen(u2->shname);
        }
    };

    // +1 for dllnum=0
    Array(struct udll, dlls, dllnum+1);
    Array(struct udll *, idlls, dllnum+1);

    soimport = 1024; // safety

    unsigned ic,k32o;
    for (ic = k32o = 0; dllnum && im->dllname; ic++, im++)
    {
        idlls[ic] = dlls + ic;
        dlls[ic].name = ibuf + im->dllname;
        dlls[ic].shname = NULL;
        dlls[ic].ordinal = 0;
        dlls[ic].iat = im->iat;
        dlls[ic].lookupt = (LE32*) (ibuf + (im->oft ? im->oft : im->iat));
        dlls[ic].npos = 0;
        dlls[ic].original_position = ic;
        dlls[ic].isk32 = strcasecmp(kernel32dll,dlls[ic].name) == 0;

        soimport += strlen(dlls[ic].name) + 1 + 4;

        for (IPTR_I(LE32, tarr, dlls[ic].lookupt); *tarr; tarr += 1)
        {
            if (*tarr & 0x80000000)
            {
                importbyordinal = true;
                soimport += 2; // ordinal num: 2 bytes
                dlls[ic].ordinal = *tarr & 0xffff;
                //if (dlls[ic].isk32)
                //    kernel32ordinal = true,k32o++;
            }
            else
            {
                IPTR_I(const upx_byte, n, ibuf + *tarr + 2);
                unsigned len = strlen(n);
                soimport += len + 1;
                if (dlls[ic].shname == NULL || len < strlen (dlls[ic].shname))
                    dlls[ic].shname = n;
            }
            soimport++; // separator
        }
    }
    oimport = new upx_byte[soimport];
    memset(oimport,0,soimport);
    oimpdlls = new upx_byte[soimport];
    memset(oimpdlls,0,soimport);

    qsort(idlls,dllnum,sizeof (udll*),udll::compare);

    unsigned dllnamelen = sizeof (kernel32dll);
    unsigned dllnum2 = 1;
    for (ic = 0; ic < dllnum; ic++)
        if (!idlls[ic]->isk32 && (ic == 0 || strcasecmp(idlls[ic - 1]->name,idlls[ic]->name)))
        {
            dllnum2++;
            dllnamelen += strlen(idlls[ic]->name) + 1;
        }
    //fprintf(stderr,"dllnum=%d dllnum2=%d soimport=%d\n",dllnum,dllnum2,soimport); //

    info("Processing imports: %d DLLs", dllnum);

    // create the new import table
    im = (import_desc*) oimpdlls;

    LE32 *ordinals = (LE32*) (oimpdlls + (dllnum2 + 1) * sizeof(import_desc));
    LE32 *lookuptable = ordinals + 4;// + k32o + (isdll ? 0 : 1);
    upx_byte *dllnames = ((upx_byte*) lookuptable) + (dllnum2 - 1) * 8;
    upx_byte *importednames = dllnames + (dllnamelen &~ 1);

    unsigned k32namepos = ptr_diff(dllnames,oimpdlls);

    memcpy(importednames, llgpa, ALIGN_UP((unsigned) sizeof(llgpa), 2u));
    strcpy(dllnames,kernel32dll);
    im->dllname = k32namepos;
    im->iat = ptr_diff(ordinals,oimpdlls);
    *ordinals++ = ptr_diff(importednames,oimpdlls);             // LoadLibraryW
    *ordinals++ = ptr_diff(importednames,oimpdlls) + 14;        // GetProcAddressA
    *ordinals++ = ptr_diff(importednames,oimpdlls) + 14 + 18;   // CacheSync
    dllnames += sizeof(kernel32dll);
    importednames += sizeof(llgpa);

    im++;
    for (ic = 0; ic < dllnum; ic++)
        if (idlls[ic]->isk32)
        {
            idlls[ic]->npos = k32namepos;
            /*
            if (idlls[ic]->ordinal)
                for (LE32 *tarr = idlls[ic]->lookupt; *tarr; tarr++)
                    if (*tarr & 0x80000000)
                        *ordinals++ = *tarr;
            */
        }
        else if (ic && strcasecmp(idlls[ic-1]->name,idlls[ic]->name) == 0)
            idlls[ic]->npos = idlls[ic-1]->npos;
        else
        {
            im->dllname = idlls[ic]->npos = ptr_diff(dllnames,oimpdlls);
            im->iat = ptr_diff(lookuptable,oimpdlls);

            strcpy(dllnames,idlls[ic]->name);
            dllnames += strlen(idlls[ic]->name)+1;
            if (idlls[ic]->ordinal)
                *lookuptable = idlls[ic]->ordinal + 0x80000000;
            else if (idlls[ic]->shname)
            {
                if (ptr_diff(importednames,oimpdlls) & 1)
                    importednames--;
                *lookuptable = ptr_diff(importednames,oimpdlls);
                importednames += 2;
                strcpy(importednames,idlls[ic]->shname);
                importednames += strlen(idlls[ic]->shname) + 1;
            }
            lookuptable += 2;
            im++;
        }
    soimpdlls = ALIGN_UP(ptr_diff(importednames,oimpdlls),4);

    Interval names(ibuf),iats(ibuf),lookups(ibuf);
    // create the preprocessed data
    //ordinals -= k32o;
    upx_byte *ppi = oimport;  // preprocessed imports
    for (ic = 0; ic < dllnum; ic++)
    {
        LE32 *tarr = idlls[ic]->lookupt;
#if 0 && ENABLE_THIS_AND_UNCOMPRESSION_WILL_BREAK
        if (!*tarr)  // no imports from this dll
            continue;
#endif
        set_le32(ppi,idlls[ic]->npos);
        set_le32(ppi+4,idlls[ic]->iat - rvamin);
        ppi += 8;
        for (; *tarr; tarr++)
            if (*tarr & 0x80000000)
            {
                /*if (idlls[ic]->isk32)
                {
                    *ppi++ = 0xfe; // signed + odd parity
                    set_le32(ppi,ptr_diff(ordinals,oimpdlls));
                    ordinals++;
                    ppi += 4;
                }
                else*/
                {
                    *ppi++ = 0xff;
                    set_le16(ppi,*tarr & 0xffff);
                    ppi += 2;
                }
            }
            else
            {
                *ppi++ = 1;
                unsigned len = strlen(ibuf + *tarr + 2) + 1;
                memcpy(ppi,ibuf + *tarr + 2,len);
                ppi += len;
                names.add(*tarr,len + 2 + 1);
            }
        ppi++;

        unsigned esize = ptr_diff((char *)tarr, (char *)idlls[ic]->lookupt);
        lookups.add(idlls[ic]->lookupt,esize);
        if (ptr_diff(ibuf + idlls[ic]->iat, (char *)idlls[ic]->lookupt))
        {
            memcpy(ibuf + idlls[ic]->iat, idlls[ic]->lookupt, esize);
            iats.add(idlls[ic]->iat,esize);
        }
        names.add(idlls[ic]->name,strlen(idlls[ic]->name) + 1 + 1);
    }
    ppi += 4;
    assert(ppi < oimport+soimport);
    soimport = ptr_diff(ppi,oimport);

    if (soimport == 4)
        soimport = 0;

    //OutputFile::dump("x0.imp", oimport, soimport);
    //OutputFile::dump("x1.imp", oimpdlls, soimpdlls);

    unsigned ilen = 0;
    names.flatten();
    if (names.ivnum > 1)
    {
        // The area occupied by the dll and imported names is not continuous
        // so to still support uncompression, I can't zero the iat area.
        // This decreases compression ratio, so FIXME somehow.
        infoWarning("can't remove unneeded imports");
        ilen += sizeof(import_desc) * dllnum;
#if defined(DEBUG)
        if (opt->verbose > 3)
            names.dump();
#endif
        // do some work for the unpacker
        im = im_save;
        for (ic = 0; ic < dllnum; ic++, im++)
        {
            memset(im,FILLVAL,sizeof(*im));
            im->dllname = ptr_diff(dlls[idlls[ic]->original_position].name,ibuf);
        }
    }
    else
    {
        iats.add(im_save,sizeof(import_desc) * dllnum);
        // zero unneeded data
        iats.clear();
        lookups.clear();
    }
    names.clear();

    iats.add(&names);
    iats.add(&lookups);
    iats.flatten();
    for (ic = 0; ic < iats.ivnum; ic++)
        ilen += iats.ivarr[ic].len;

    info("Imports: original size: %u bytes, preprocessed size: %u bytes",ilen,soimport);
    return names.ivnum == 1 ? names.ivarr[0].start : 0;
}