Improve --strip-relocs

- Remove .reloc section
- Enable for 64-bit images
- Abort if explicitly set on unsupported image
- Use with --force to remove ASLR / apply when imagebase < default
This commit is contained in:
bitraid
2021-04-25 20:15:07 +03:00
committed by Markus F.X.J. Oberhumer
parent 181c752488
commit 144010295e
3 changed files with 42 additions and 21 deletions
-2
View File
@@ -268,8 +268,6 @@ void PackW64Pep::defineSymbols(unsigned ncsection, unsigned upxsection,
void PackW64Pep::pack(OutputFile *fo) void PackW64Pep::pack(OutputFile *fo)
{ {
// FIXME: Relocation stripping disabled for now - Stefan Widmann
opt->win32_pe.strip_relocs = false;
super::pack0(fo, 0x0c, 0x0000000140000000ULL); super::pack0(fo, 0x0c, 0x0000000140000000ULL);
} }
+40 -18
View File
@@ -363,7 +363,7 @@ void PeFile::Reloc::finish(upx_byte *&p,unsigned &siz)
void PeFile::processRelocs(Reloc *rel) // pass2 void PeFile::processRelocs(Reloc *rel) // pass2
{ {
rel->finish(oxrelocs,soxrelocs); rel->finish(oxrelocs,soxrelocs);
if (opt->win32_pe.strip_relocs && !isdll /*FIXME ASLR*/) if (opt->win32_pe.strip_relocs)
soxrelocs = 0; soxrelocs = 0;
} }
@@ -377,10 +377,13 @@ void PeFile32::processRelocs() // pass1
const unsigned *counts = rel.getcounts(); const unsigned *counts = rel.getcounts();
const unsigned rnum = counts[1] + counts[2] + counts[3]; 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)) if (IDSIZE(PEDIR_RELOC))
{
ibuf.fill(IDADDR(PEDIR_RELOC), IDSIZE(PEDIR_RELOC), FILLVAL); ibuf.fill(IDADDR(PEDIR_RELOC), IDSIZE(PEDIR_RELOC), FILLVAL);
ih.objects = tryremove(IDADDR(PEDIR_RELOC), ih.objects);
}
mb_orelocs.alloc(1); mb_orelocs.alloc(1);
orelocs = (upx_byte *)mb_orelocs.getVoidPtr(); orelocs = (upx_byte *)mb_orelocs.getVoidPtr();
sorelocs = 0; sorelocs = 0;
@@ -478,10 +481,13 @@ void PeFile64::processRelocs() // pass1
for (ic = 1; ic < 16; ic++) for (ic = 1; ic < 16; ic++)
rnum += counts[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)) if (IDSIZE(PEDIR_RELOC))
{
ibuf.fill(IDADDR(PEDIR_RELOC), IDSIZE(PEDIR_RELOC), FILLVAL); ibuf.fill(IDADDR(PEDIR_RELOC), IDSIZE(PEDIR_RELOC), FILLVAL);
ih.objects = tryremove(IDADDR(PEDIR_RELOC), ih.objects);
}
mb_orelocs.alloc(1); mb_orelocs.alloc(1);
orelocs = (upx_byte *)mb_orelocs.getVoidPtr(); orelocs = (upx_byte *)mb_orelocs.getVoidPtr();
sorelocs = 0; sorelocs = 0;
@@ -2161,21 +2167,40 @@ void PeFile::checkHeaderValues(unsigned subsystem, unsigned mask,
unsigned PeFile::handleStripRelocs(upx_uint64_t ih_imagebase, unsigned PeFile::handleStripRelocs(upx_uint64_t ih_imagebase,
upx_uint64_t default_imagebase, upx_uint64_t default_imagebase,
unsigned dllflags) LE16 &dllflags)
{ {
if (dllflags & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) if (opt->win32_pe.strip_relocs < 0)
opt->win32_pe.strip_relocs = false; {
else if (isdll) //do never strip relocations from DLLs if (isdll || dllflags & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE)
opt->win32_pe.strip_relocs = false; opt->win32_pe.strip_relocs = false;
else if (opt->win32_pe.strip_relocs < 0) else
opt->win32_pe.strip_relocs = (ih_imagebase >= default_imagebase); opt->win32_pe.strip_relocs = ih_imagebase >= default_imagebase;
}
if (opt->win32_pe.strip_relocs) if (opt->win32_pe.strip_relocs)
{ {
if (ih_imagebase < default_imagebase) if (isdll)
throwCantPack("--strip-relocs is not allowed with this imagebase"); throwCantPack("--strip-relocs is not allowed with DLL images");
else if (dllflags & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE)
return RELOCS_STRIPPED; {
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; return 0;
} }
@@ -2319,9 +2344,6 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh,
throwCantPack(buf); 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 // FIXME: if the last object has a bss then this won't work
// newvsize = (isection[objs-1].vaddr + isection[objs-1].size + oam1) &~ oam1; // newvsize = (isection[objs-1].vaddr + isection[objs-1].size + oam1) &~ oam1;
// temporary solution: // temporary solution:
@@ -2589,7 +2611,7 @@ void PeFile::pack0(OutputFile *fo, ht &ih, ht &oh,
if (rvamin < osection[0].rawdataptr) if (rvamin < osection[0].rawdataptr)
throwCantPack("object alignment too small"); throwCantPack("object alignment too small");
if (opt->win32_pe.strip_relocs && !isdll) if (opt->win32_pe.strip_relocs)
oh.flags |= RELOCS_STRIPPED; oh.flags |= RELOCS_STRIPPED;
//for (ic = 0; ic < oh.filealign; ic += 4) //for (ic = 0; ic < oh.filealign; ic += 4)
+2 -1
View File
@@ -59,7 +59,7 @@ protected:
unsigned ih_entry, unsigned ih_filealign); unsigned ih_entry, unsigned ih_filealign);
unsigned handleStripRelocs(upx_uint64_t ih_imagebase, unsigned handleStripRelocs(upx_uint64_t ih_imagebase,
upx_uint64_t default_imagebase, upx_uint64_t default_imagebase,
unsigned dllflags); LE16 &dllflags);
virtual bool handleForceOption() = 0; virtual bool handleForceOption() = 0;
virtual void callCompressWithFilters(Filter &, int filter_strategy, virtual void callCompressWithFilters(Filter &, int filter_strategy,
@@ -270,6 +270,7 @@ protected:
//NEW: DLL characteristics definition for ASLR, ... - Stefan Widmann //NEW: DLL characteristics definition for ASLR, ... - Stefan Widmann
enum { enum {
IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020,
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040, IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040,
IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY = 0x0080, IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY = 0x0080,
IMAGE_DLLCHARACTERISTICS_NX_COMPAT = 0x0100, IMAGE_DLLCHARACTERISTICS_NX_COMPAT = 0x0100,