⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p_armpe.cpp

📁 UPX 源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* p_armpe.cpp --   This file is part of the UPX executable compressor.   Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer   Copyright (C) 1996-2007 Laszlo Molnar   All Rights Reserved.   UPX and the UCL library are free software; you can redistribute them   and/or modify them under the terms of the GNU General Public License as   published by the Free Software Foundation; either version 2 of   the License, or (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; see the file COPYING.   If not, write to the Free Software Foundation, Inc.,   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.   Markus F.X.J. Oberhumer              Laszlo Molnar   <mfx@users.sourceforge.net>          <ml1050@users.sourceforge.net> */#include "conf.h"#include "file.h"#include "filter.h"#include "packer.h"#include "pefile.h"#include "p_armpe.h"#include "linker.h"static const#include "stub/arm.v4a-wince.pe.h"static const#include "stub/arm.v4t-wince.pe.h"#define IDSIZE(x)       ih.ddirs[x].size#define IDADDR(x)       ih.ddirs[x].vaddr#define ODSIZE(x)       oh.ddirs[x].size#define ODADDR(x)       oh.ddirs[x].vaddr#define isdll           ((ih.flags & DLL_FLAG) != 0)#define FILLVAL         0/*************************************************************************//**************************************************************************/#if defined(__BORLANDC__)#  undef strcpy#  define strcpy(a,b)   strcpy((char *)(a),(const char *)(b))#endif#if (__ACC_CXX_HAVE_PLACEMENT_DELETE) || defined(__DJGPP__)#include "bptr.h"#define IPTR(type, var)         BoundedPtr<type> var(ibuf, ibuf.getSize())#define OPTR(type, var)         BoundedPtr<type> var(obuf, obuf.getSize())#define IPTR_I(type, var, v)    BoundedPtr<type> var(ibuf, ibuf.getSize(), v)#define OPTR_I(type, var, v)    BoundedPtr<type> var(obuf, obuf.getSize(), v)#define IPTR_C(type, var, v)    const BoundedPtr<type> var(ibuf, ibuf.getSize(), v)#define OPTR_C(type, var, v)    const BoundedPtr<type> var(obuf, obuf.getSize(), v)#else#define IPTR(type, var)         type* var = 0#define OPTR(type, var)         type* var = 0#define IPTR_I(type, var, v)    type* var = (v)#define OPTR_I(type, var, v)    type* var = (v)#define IPTR_C(type, var, v)    type* const var = (v)#define OPTR_C(type, var, v)    type* const var = (v)#endifstatic void xcheck(const void *p, size_t plen, const void *b, size_t blen){    const char *pp = (const char *) p;    const char *bb = (const char *) b;    if (pp < bb || pp > bb + blen || pp + plen > bb + blen)        throwCantUnpack("pointer out of range; take care!");}#if 0static void xcheck(size_t poff, size_t plen, const void *b, size_t blen){    ACC_UNUSED(b);    if (poff > blen || poff + plen > blen)        throwCantUnpack("pointer out of range; take care!");}#endif#define ICHECK(x, size)     xcheck(x, size, ibuf, ibuf.getSize())#define OCHECK(x, size)     xcheck(x, size, obuf, obuf.getSize())#define imemset(a,b,c)      ICHECK(a,c), memset(a,b,c)#define omemset(a,b,c)      OCHECK(a,c), memset(a,b,c)#define imemcpy(a,b,c)      ICHECK(a,c), memcpy(a,b,c)#define omemcpy(a,b,c)      OCHECK(a,c), memcpy(a,b,c)/*************************************************************************//**************************************************************************/PackArmPe::PackArmPe(InputFile *f) : super(f){    use_thumb_stub = false;}PackArmPe::~PackArmPe(){}const int *PackArmPe::getCompressionMethods(int method, int level) const{    static const int m_all[]   = { M_NRV2B_8, M_NRV2E_8, M_LZMA, M_END };    static const int m_lzma[]  = { M_LZMA, M_END };    static const int m_nrv2b[] = { M_NRV2B_8, M_END };    static const int m_nrv2e[] = { M_NRV2E_8, M_END };    if (!use_thumb_stub)        return getDefaultCompressionMethods_8(method, level);    if (method == M_ALL)    return m_all;    if (M_IS_LZMA(method))  return m_lzma;    if (M_IS_NRV2B(method)) return m_nrv2b;    if (M_IS_NRV2E(method)) return m_nrv2e;    return m_nrv2e;}const int *PackArmPe::getFilters() const{    static const int filters[] = { 0x50, FT_END };    return filters;}Linker* PackArmPe::newLinker() const{    return new ElfLinkerArmLE;}/*************************************************************************// import handling**************************************************************************/struct import_desc{    LE32  oft;      // orig first thunk    char  _[8];    LE32  dllname;    LE32  iat;      // import address table}__attribute_packed;void PackArmPe::processImports(unsigned myimport, unsigned iat_off) // pass 2{    COMPILE_TIME_ASSERT(sizeof(import_desc) == 20);    // adjust import data    for (import_desc *im = (import_desc*) oimpdlls; im->dllname; im++)    {        if (im->dllname < myimport)            im->dllname += myimport;        LE32 *p = (LE32*) (oimpdlls + im->iat);        im->iat += myimport;        im->oft = im->iat;        while (*p)            if ((*p++ & 0x80000000) == 0)  // import by name?                p[-1] += myimport;        im->iat = im == (import_desc*) oimpdlls ? iat_off : iat_off + 12;    }}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;        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;            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].isk32 = strcasecmp(kernel32dll,dlls[ic].name) == 0;        soimport += strlen(dlls[ic].name) + 1 + 4;        for (LE32 *tarr = dlls[ic].lookupt; *tarr; tarr++)        {            if (*tarr & 0x80000000)            {                importbyordinal = true;                soimport += 2; // ordinal num: 2 bytes                dlls[ic].ordinal = *tarr & 0xffff;                //if (dlls[ic].isk32)                //    kernel32ordinal = true,k32o++;            }            else            {                unsigned len = strlen(ibuf + *tarr + 2);                soimport += len + 1;                if (dlls[ic].shname == NULL || len < strlen (dlls[ic].shname))                    dlls[ic].shname = ibuf + *tarr + 2;            }            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 (!*tarr)  // no imports from this dll            continue;        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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -