📄 p_armpe.cpp
字号:
/* 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 + -