diff --git a/src/p_w64pep.cpp b/src/p_w64pep.cpp index 7166b9c6..2d90d742 100644 --- a/src/p_w64pep.cpp +++ b/src/p_w64pep.cpp @@ -268,8 +268,6 @@ void PackW64Pep::defineSymbols(unsigned ncsection, unsigned upxsection, void PackW64Pep::pack(OutputFile *fo) { - // FIXME: Relocation stripping disabled for now - Stefan Widmann - opt->win32_pe.strip_relocs = false; super::pack0(fo, 0x0c, 0x0000000140000000ULL); } diff --git a/src/pefile.cpp b/src/pefile.cpp index e6e4164b..aa611cc2 100644 --- a/src/pefile.cpp +++ b/src/pefile.cpp @@ -363,7 +363,7 @@ void PeFile::Reloc::finish(upx_byte *&p,unsigned &siz) void PeFile::processRelocs(Reloc *rel) // pass2 { rel->finish(oxrelocs,soxrelocs); - if (opt->win32_pe.strip_relocs && !isdll /*FIXME ASLR*/) + if (opt->win32_pe.strip_relocs) soxrelocs = 0; } @@ -377,10 +377,13 @@ void PeFile32::processRelocs() // pass1 const unsigned *counts = rel.getcounts(); const unsigned rnum = counts[1] + counts[2] + counts[3]; - if ((opt->win32_pe.strip_relocs && !isdll) || rnum == 0) + if (opt->win32_pe.strip_relocs || rnum == 0) { if (IDSIZE(PEDIR_RELOC)) + { ibuf.fill(IDADDR(PEDIR_RELOC), IDSIZE(PEDIR_RELOC), FILLVAL); + ih.objects = tryremove(IDADDR(PEDIR_RELOC), ih.objects); + } mb_orelocs.alloc(1); orelocs = (upx_byte *)mb_orelocs.getVoidPtr(); sorelocs = 0; @@ -478,10 +481,13 @@ void PeFile64::processRelocs() // pass1 for (ic = 1; ic < 16; ic++) rnum += counts[ic]; - if ((opt->win32_pe.strip_relocs && !isdll) || rnum == 0) + if (opt->win32_pe.strip_relocs || rnum == 0) { if (IDSIZE(PEDIR_RELOC)) + { ibuf.fill(IDADDR(PEDIR_RELOC), IDSIZE(PEDIR_RELOC), FILLVAL); + ih.objects = tryremove(IDADDR(PEDIR_RELOC), ih.objects); + } mb_orelocs.alloc(1); orelocs = (upx_byte *)mb_orelocs.getVoidPtr(); sorelocs = 0; @@ -2161,21 +2167,40 @@ void PeFile::checkHeaderValues(unsigned subsystem, unsigned mask, unsigned PeFile::handleStripRelocs(upx_uint64_t ih_imagebase, upx_uint64_t default_imagebase, - unsigned dllflags) + LE16 &dllflags) { - if (dllflags & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) - opt->win32_pe.strip_relocs = false; - else if (isdll) //do never strip relocations from DLLs - opt->win32_pe.strip_relocs = false; - else if (opt->win32_pe.strip_relocs < 0) - opt->win32_pe.strip_relocs = (ih_imagebase >= default_imagebase); + if (opt->win32_pe.strip_relocs < 0) + { + if (isdll || dllflags & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) + opt->win32_pe.strip_relocs = false; + else + opt->win32_pe.strip_relocs = ih_imagebase >= default_imagebase; + } if (opt->win32_pe.strip_relocs) { - if (ih_imagebase < default_imagebase) - throwCantPack("--strip-relocs is not allowed with this imagebase"); - else - return RELOCS_STRIPPED; + if (isdll) + throwCantPack("--strip-relocs is not allowed with DLL images"); + if (dllflags & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) + { + if (opt->force) // Disable ASLR + { + // The bit is set, so clear it with XOR + dllflags ^= IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE; + // HIGH_ENTROPY_VA has no effect without DYNAMIC_BASE, so clear + // it also if set + dllflags &= ~(unsigned)IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA; + } + else + throwCantPack("--strip-relocs is not allowed with ASLR (use " + "with --force to remove)"); + } + if (!opt->force && ih_imagebase < default_imagebase) + throwCantPack("--strip-relocs may not support this imagebase (try " + "with --force)"); + return RELOCS_STRIPPED; } + else + info("Base relocations stripping is disabled for this image"); return 0; } @@ -2319,9 +2344,6 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, throwCantPack(buf); } - // FIXME: disabled: the uncompressor would not allocate enough memory - //objs = tryremove(IDADDR(PEDIR_RELOC),objs); - // FIXME: if the last object has a bss then this won't work // newvsize = (isection[objs-1].vaddr + isection[objs-1].size + oam1) &~ oam1; // temporary solution: @@ -2589,7 +2611,7 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh, if (rvamin < osection[0].rawdataptr) throwCantPack("object alignment too small"); - if (opt->win32_pe.strip_relocs && !isdll) + if (opt->win32_pe.strip_relocs) oh.flags |= RELOCS_STRIPPED; //for (ic = 0; ic < oh.filealign; ic += 4) diff --git a/src/pefile.h b/src/pefile.h index 6c2efcd5..0232d4bd 100644 --- a/src/pefile.h +++ b/src/pefile.h @@ -59,7 +59,7 @@ protected: unsigned ih_entry, unsigned ih_filealign); unsigned handleStripRelocs(upx_uint64_t ih_imagebase, upx_uint64_t default_imagebase, - unsigned dllflags); + LE16 &dllflags); virtual bool handleForceOption() = 0; virtual void callCompressWithFilters(Filter &, int filter_strategy, @@ -270,6 +270,7 @@ protected: //NEW: DLL characteristics definition for ASLR, ... - Stefan Widmann enum { + IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020, IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040, IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY = 0x0080, IMAGE_DLLCHARACTERISTICS_NX_COMPAT = 0x0100,