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->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;
#undef H4
@ -224,7 +235,9 @@ void PackTmt::pack(OutputFile *fo)
{
for (unsigned ic=4; ic<=rsize; 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;

View File

@ -399,7 +399,7 @@ void PackWcle::preprocessFixups()
delete[] ifixups;
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;
// FIXME: this could be removed if has_extra_code = false
// 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
**************************************************************************/
upx_byte *Packer::optimizeReloc(upx_byte *in, unsigned relocnum, upx_byte *out, upx_byte *image,
int bswap, int *big, int bits) {
upx_byte *Packer::optimizeReloc(
upx_byte *in, unsigned relocnum,
upx_byte *out,
upx_byte *image, unsigned headway,
int bswap, int *big, int bits)
{
if (opt->exact)
throwCantPackExact();
@ -840,6 +844,11 @@ upx_byte *Packer::optimizeReloc(upx_byte *in, unsigned relocnum, upx_byte *out,
fix += 4;
}
pc += oc;
if (headway <= pc) {
char msg[80]; snprintf(msg, sizeof(msg),
"bad reloc[%#x] = %#x", jc, oc);
throwCantPack(msg);
}
if (bswap) {
if (bits == 32)
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;
}
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) {
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) {
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,

View File

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

View File

@ -441,7 +441,7 @@ void PeFile32::processRelocs() // pass1
mb_orelocs.alloc(mem_size(4, rnum, 1024)); // 1024 - safety
orelocs = (upx_byte *)mb_orelocs.getVoidPtr();
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);
delete [] fix[3];
@ -547,7 +547,7 @@ void PeFile64::processRelocs() // pass1
mb_orelocs.alloc(mem_size(4, rnum, 1024)); // 1024 - safety
orelocs = (upx_byte *)mb_orelocs.getVoidPtr();
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);
for (ic = 15; ic; ic--)