1
0
mirror of https://github.com/upx/upx synced 2025-10-05 19:20:23 +08:00

Check when optimizeRelocs()

https://github.com/upx/upx/issues/513
	modified:   packer.h
	modified:   packer.cpp
	modified:   pefile.cpp
	modified:   p_wcle.cpp
	modified:   p_tmt.cpp
This commit is contained in:
John Reiser 2021-12-29 16:57:52 -08:00 committed by Markus F.X.J. Oberhumer
parent be23f93ee6
commit ea567a8b14
5 changed files with 48 additions and 19 deletions

View File

@ -172,7 +172,18 @@ int PackTmt::readFileHeader()
fi->seek(adam_offset,SEEK_SET); fi->seek(adam_offset,SEEK_SET);
fi->readx(&ih,sizeof(ih)); fi->readx(&ih,sizeof(ih));
// FIXME: should add some checks for the values in 'ih' // FIXME: should add more checks for the values in 'ih'
unsigned const imagesize = get_le32(&ih.imagesize);
unsigned const entry = get_le32(&ih.entry);
unsigned const relocsize = get_le32(&ih.relocsize);
if (!imagesize
|| file_size <= imagesize
|| file_size <= entry
|| file_size <= relocsize) {
printWarn(getName(), "bad header; imagesize=%#x entry=%#x relocsize=%#x",
imagesize, entry, relocsize);
return 0;
}
return UPX_F_TMT_ADAM; return UPX_F_TMT_ADAM;
#undef H4 #undef H4
@ -224,7 +235,9 @@ void PackTmt::pack(OutputFile *fo)
{ {
for (unsigned ic=4; ic<=rsize; ic+=4) for (unsigned ic=4; ic<=rsize; ic+=4)
set_le32(wrkmem+ic,get_le32(wrkmem+ic)-4); set_le32(wrkmem+ic,get_le32(wrkmem+ic)-4);
relocsize = ptr_diff(optimizeReloc32(wrkmem+4,rsize/4,wrkmem,ibuf,1,&big_relocs), wrkmem); relocsize = ptr_diff(
optimizeReloc32(wrkmem+4,rsize/4,wrkmem,ibuf,file_size,1,&big_relocs),
wrkmem);
} }
wrkmem[relocsize++] = 0; wrkmem[relocsize++] = 0;

View File

@ -399,7 +399,7 @@ void PackWcle::preprocessFixups()
delete[] ifixups; delete[] ifixups;
ifixups = new upx_byte[1000]; ifixups = new upx_byte[1000];
} }
fix = optimizeReloc32 (rl,rc,ifixups,iimage,1,&big_relocs); fix = optimizeReloc32 (rl,rc,ifixups,iimage,file_size,1,&big_relocs);
has_extra_code = srf != selector_fixups; has_extra_code = srf != selector_fixups;
// FIXME: this could be removed if has_extra_code = false // FIXME: this could be removed if has_extra_code = false
// but then we'll need a flag // but then we'll need a flag

View File

@ -805,8 +805,12 @@ int Packer::patch_le32(void *b, int blen, const void *old, unsigned new_) {
// relocation util // relocation util
**************************************************************************/ **************************************************************************/
upx_byte *Packer::optimizeReloc(upx_byte *in, unsigned relocnum, upx_byte *out, upx_byte *image, upx_byte *Packer::optimizeReloc(
int bswap, int *big, int bits) { upx_byte *in, unsigned relocnum,
upx_byte *out,
upx_byte *image, unsigned headway,
int bswap, int *big, int bits)
{
if (opt->exact) if (opt->exact)
throwCantPackExact(); throwCantPackExact();
@ -840,6 +844,11 @@ upx_byte *Packer::optimizeReloc(upx_byte *in, unsigned relocnum, upx_byte *out,
fix += 4; fix += 4;
} }
pc += oc; pc += oc;
if (headway <= pc) {
char msg[80]; snprintf(msg, sizeof(msg),
"bad reloc[%#x] = %#x", jc, oc);
throwCantPack(msg);
}
if (bswap) { if (bswap) {
if (bits == 32) if (bits == 32)
set_be32(image + pc, get_le32(image + pc)); set_be32(image + pc, get_le32(image + pc));
@ -853,14 +862,14 @@ upx_byte *Packer::optimizeReloc(upx_byte *in, unsigned relocnum, upx_byte *out,
return fix; return fix;
} }
upx_byte *Packer::optimizeReloc32(upx_byte *in, unsigned relocnum, upx_byte *out, upx_byte *image, upx_byte *Packer::optimizeReloc32(upx_byte *in, unsigned relocnum, upx_byte *out, upx_byte *image, unsigned headway,
int bswap, int *big) { int bswap, int *big) {
return optimizeReloc(in, relocnum, out, image, bswap, big, 32); return optimizeReloc(in, relocnum, out, image, headway, bswap, big, 32);
} }
upx_byte *Packer::optimizeReloc64(upx_byte *in, unsigned relocnum, upx_byte *out, upx_byte *image, upx_byte *Packer::optimizeReloc64(upx_byte *in, unsigned relocnum, upx_byte *out, upx_byte *image, unsigned headway,
int bswap, int *big) { int bswap, int *big) {
return optimizeReloc(in, relocnum, out, image, bswap, big, 64); return optimizeReloc(in, relocnum, out, image, headway, bswap, big, 64);
} }
unsigned Packer::unoptimizeReloc(upx_byte **in, upx_byte *image, MemBuffer *out, int bswap, unsigned Packer::unoptimizeReloc(upx_byte **in, upx_byte *image, MemBuffer *out, int bswap,

View File

@ -269,15 +269,22 @@ protected:
void checkPatch(void *b, int blen, int boff, int size); void checkPatch(void *b, int blen, int boff, int size);
// relocation util // relocation util
static upx_byte *optimizeReloc(upx_byte *in, unsigned relocnum, upx_byte *out, upx_byte *image, static upx_byte *optimizeReloc(
int bs, int *big, int bits); upx_byte *in, unsigned relocnum,
static unsigned unoptimizeReloc(upx_byte **in, upx_byte *image, MemBuffer *out, int bs, upx_byte *out, upx_byte *image, unsigned headway,
int bits); int bs, int *big, int bits);
static upx_byte *optimizeReloc32(upx_byte *in, unsigned relocnum, upx_byte *out, static unsigned unoptimizeReloc(upx_byte **in, upx_byte *image, MemBuffer *out, int bs, int bits);
upx_byte *image, int bs, int *big);
static upx_byte *optimizeReloc32(
upx_byte *in, unsigned relocnum,
upx_byte *out, upx_byte *image, unsigned headway,
int bs, int *big);
static unsigned unoptimizeReloc32(upx_byte **in, upx_byte *image, MemBuffer *out, int bs); static unsigned unoptimizeReloc32(upx_byte **in, upx_byte *image, MemBuffer *out, int bs);
static upx_byte *optimizeReloc64(upx_byte *in, unsigned relocnum, upx_byte *out,
upx_byte *image, int bs, int *big); static upx_byte *optimizeReloc64(
upx_byte *in, unsigned relocnum,
upx_byte *out, upx_byte *image, unsigned headway,
int bs, int *big);
static unsigned unoptimizeReloc64(upx_byte **in, upx_byte *image, MemBuffer *out, int bs); static unsigned unoptimizeReloc64(upx_byte **in, upx_byte *image, MemBuffer *out, int bs);
// target endianness abstraction // target endianness abstraction

View File

@ -441,7 +441,7 @@ void PeFile32::processRelocs() // pass1
mb_orelocs.alloc(mem_size(4, rnum, 1024)); // 1024 - safety mb_orelocs.alloc(mem_size(4, rnum, 1024)); // 1024 - safety
orelocs = (upx_byte *)mb_orelocs.getVoidPtr(); orelocs = (upx_byte *)mb_orelocs.getVoidPtr();
sorelocs = ptr_diff(optimizeReloc32((upx_byte*) fix[3], xcounts[3], sorelocs = ptr_diff(optimizeReloc32((upx_byte*) fix[3], xcounts[3],
orelocs, ibuf + rvamin, 1, &big_relocs), orelocs, ibuf + rvamin, file_size - rvamin, 1, &big_relocs),
orelocs); orelocs);
delete [] fix[3]; delete [] fix[3];
@ -547,7 +547,7 @@ void PeFile64::processRelocs() // pass1
mb_orelocs.alloc(mem_size(4, rnum, 1024)); // 1024 - safety mb_orelocs.alloc(mem_size(4, rnum, 1024)); // 1024 - safety
orelocs = (upx_byte *)mb_orelocs.getVoidPtr(); orelocs = (upx_byte *)mb_orelocs.getVoidPtr();
sorelocs = ptr_diff(optimizeReloc64((upx_byte*) fix[10], xcounts[10], sorelocs = ptr_diff(optimizeReloc64((upx_byte*) fix[10], xcounts[10],
orelocs, ibuf + rvamin, 1, &big_relocs), orelocs, ibuf + rvamin, file_size - rvamin, 1, &big_relocs),
orelocs); orelocs);
for (ic = 15; ic; ic--) for (ic = 15; ic; ic--)