From 40e19293f909c03870b0914003b901e5881f0b1a Mon Sep 17 00:00:00 2001 From: "Markus F.X.J. Oberhumer" Date: Tue, 8 May 2007 15:28:35 +0200 Subject: [PATCH 1/3] Added throwOutOfMemoryException(). --- src/except.cpp | 8 ++++++++ src/except.h | 1 + src/linker.cpp | 4 +++- src/mem.cpp | 6 +----- src/p_lx_elf.cpp | 2 ++ src/p_ps1.cpp | 2 ++ src/packer.cpp | 8 +++++++- 7 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/except.cpp b/src/except.cpp index fad78307..4e029c43 100644 --- a/src/except.cpp +++ b/src/except.cpp @@ -161,6 +161,14 @@ void throwBadLoader() } +void throwOutOfMemoryException(const char *msg) +{ + if (msg == NULL) + msg = "out of memory"; + throw OutOfMemoryException(msg); +} + + void throwIOException(const char *msg, int e) { throw IOException(msg, e); diff --git a/src/except.h b/src/except.h index f69c7308..65f9bbbb 100644 --- a/src/except.h +++ b/src/except.h @@ -220,6 +220,7 @@ void throwBadLoader() NORET; void throwChecksumError() NORET; void throwCompressedDataViolation() NORET; void throwInternalError(const char *msg) NORET; +void throwOutOfMemoryException(const char *msg = NULL) NORET; void throwIOException(const char *msg = NULL, int e = 0) NORET; void throwEOFException(const char *msg = NULL, int e = 0) NORET; diff --git a/src/linker.cpp b/src/linker.cpp index 245e7576..529118ba 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -159,7 +159,9 @@ void ElfLinker::init(const void *pdata_v, int plen) input = new upx_byte[inputlen + 1]; unsigned new_len = u_len; int r = upx_decompress(pdata, c_len, input, &new_len, method, NULL); - if (r != 0 || new_len != u_len) + if (r == UPX_E_OUT_OF_MEMORY) + throwOutOfMemoryException(); + if (r != UPX_E_OK || new_len != u_len) throwBadLoader(); } else diff --git a/src/mem.cpp b/src/mem.cpp index 120c3b30..af4914e8 100644 --- a/src/mem.cpp +++ b/src/mem.cpp @@ -192,11 +192,7 @@ void MemBuffer::alloc(unsigned size) assert((int)total > 0); unsigned char *p = (unsigned char *) malloc(total); if (!p) - { - //throw bad_alloc(); - throw OutOfMemoryException("out of memory"); - //exit(1); - } + throwOutOfMemoryException(); b_size = size; if (use_mcheck) { diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index 6b38dc75..12c75d21 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -481,6 +481,8 @@ PackLinuxElf32::buildLinuxLoader( unsigned char *tmp = new unsigned char[tmp_len]; memset(tmp, 0, tmp_len); r = upx_decompress(sizeof(h) + cprLoader, h.sz_cpr, tmp, &tmp_len, h.b_method, NULL); + if (r == UPX_E_OUT_OF_MEMORY) + throwOutOfMemoryException(); printf("\n%d %d: %d %d %d\n", h.b_method, r, h.sz_cpr, h.sz_unc, tmp_len); for (unsigned j=0; j < h.sz_unc; ++j) if (tmp[j]!=uncLoader[j]) { printf("%d: %x %x\n", j, tmp[j], uncLoader[j]); diff --git a/src/p_ps1.cpp b/src/p_ps1.cpp index 54ae6aad..09969ee2 100644 --- a/src/p_ps1.cpp +++ b/src/p_ps1.cpp @@ -194,6 +194,8 @@ bool PackPs1::getBkupHeader(unsigned char *p, unsigned char *dst) unsigned sz_bh = SZ_IH_BKUP; int r = upx_decompress((const unsigned char *)&src->ih_bkup, src->len, unc_bh, &sz_bh, M_NRV2E_8, NULL ); + if (r == UPX_E_OUT_OF_MEMORY) + throwOutOfMemoryException(); if (r != UPX_E_OK || sz_bh != SZ_IH_BKUP) throwInternalError("header decompression failed"); unsigned ad = upx_adler32(unc_bh, SZ_IH_BKUP); diff --git a/src/packer.cpp b/src/packer.cpp index 8b2cff85..369980ce 100644 --- a/src/packer.cpp +++ b/src/packer.cpp @@ -245,7 +245,7 @@ bool Packer::compress(upx_bytep i_ptr, unsigned i_len, upx_bytep o_ptr, uip->endCallback(); if (r == UPX_E_OUT_OF_MEMORY) - throwCantPack("out of memory"); + throwOutOfMemoryException(); if (r != UPX_E_OK) throwInternalError("compression failed"); @@ -282,6 +282,8 @@ bool Packer::compress(upx_bytep i_ptr, unsigned i_len, upx_bytep o_ptr, // decompress unsigned new_len = ph.u_len; r = upx_decompress(o_ptr, ph.c_len, i_ptr, &new_len, ph.method, &ph.compress_result); + if (r == UPX_E_OUT_OF_MEMORY) + throwOutOfMemoryException(); //printf("%d %d: %d %d %d\n", ph.method, r, ph.c_len, ph.u_len, new_len); if (r != UPX_E_OK) throwInternalError("decompression failed"); @@ -360,6 +362,8 @@ void ph_decompress(PackHeader &ph, const upx_bytep in, upx_bytep out, // decompress unsigned new_len = ph.u_len; int r = upx_decompress(in, ph.c_len, out, &new_len, ph.method, &ph.compress_result); + if (r == UPX_E_OUT_OF_MEMORY) + throwOutOfMemoryException(); if (r != UPX_E_OK || new_len != ph.u_len) throwCompressedDataViolation(); @@ -412,6 +416,8 @@ bool ph_testOverlappingDecompression(const PackHeader &ph, int r = upx_test_overlap(buf - src_off, tbuf, src_off, ph.c_len, &new_len, ph.method, &ph.compress_result); + if (r == UPX_E_OUT_OF_MEMORY) + throwOutOfMemoryException(); return (r == UPX_E_OK && new_len == ph.u_len); } From f340f84de732f9572c0d193399326a5a88f1fff5 Mon Sep 17 00:00:00 2001 From: "Markus F.X.J. Oberhumer" Date: Tue, 8 May 2007 16:12:42 +0200 Subject: [PATCH 2/3] Avoid warnings. --- src/p_vmlinx.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/p_vmlinx.cpp b/src/p_vmlinx.cpp index 1c6642db..85377fa5 100644 --- a/src/p_vmlinx.cpp +++ b/src/p_vmlinx.cpp @@ -320,7 +320,7 @@ void PackVmlinuxBase::pack(OutputFile *fo) hdr_info.b_cto8 = 0; hdr_info.b_unused = 0; fo->write(&hdr_info, sizeof(hdr_info)); fo_off += sizeof(hdr_info); - unsigned const frag = (3& -len_cpr); + unsigned const frag = (3& (0u-len_cpr)); ppc32_extra += sizeof(hdr_info) + len_cpr + frag; fo_off += len_cpr + frag; fo->write(cpr_hdr, len_cpr + frag); @@ -333,12 +333,12 @@ void PackVmlinuxBase::pack(OutputFile *fo) && (Shdr::SHF_ALLOC & shdr->sh_flags) && (Shdr::SHF_EXECINSTR & shdr->sh_flags)) { // shdr[1] is instructions (probably .text) - f_ptr = ibuf + (shdr->sh_offset - phdri[0].p_offset); + f_ptr = ibuf + (unsigned) (shdr->sh_offset - phdri[0].p_offset); f_len = shdr->sh_size; ++shdr; - for (int j= -2+ ehdri.e_shnum; --j>=0; ++shdr) { + for (int j= ehdri.e_shnum - 2; --j>=0; ++shdr) { unsigned prev_end = shdr[-1].sh_size + shdr[-1].sh_offset; - prev_end += ~(-shdr[0].sh_addralign) & -prev_end; // align_up + prev_end += ~(0u-shdr[0].sh_addralign) & (0u-prev_end); // align_up if ((Shdr::SHF_ALLOC & shdr->sh_flags) && (Shdr::SHF_EXECINSTR & shdr->sh_flags) && shdr[0].sh_offset==prev_end) { @@ -368,7 +368,7 @@ void PackVmlinuxBase::pack(OutputFile *fo) fo->write(&hdr_info, sizeof(hdr_info)); fo_off += sizeof(hdr_info); ppc32_extra += sizeof(hdr_info); if (ph.u_len!=f_len) { - set_be32(&hdr_info.sz_unc, f_ptr - ibuf); + set_be32(&hdr_info.sz_unc, f_ptr - (upx_bytep) ibuf); set_be32(&hdr_info.sz_cpr, f_len); fo->write(&hdr_info, 2*sizeof(unsigned)); fo_off += 2*sizeof(unsigned); ppc32_extra += 2*sizeof(unsigned); From 48236ecd3c042e85acba8e6fee81d951dd71ac2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3=20Moln=C3=A1r?= Date: Tue, 8 May 2007 18:23:41 +0200 Subject: [PATCH 3/3] fixed an incorrect error message caused by a bug in relocation handling --- NEWS | 2 ++ src/p_exe.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 6b6a2344..380b3676 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,8 @@ User visible changes for UPX ================================================================== Changes in 3.01 (XX XXX 2007): + * dos/exe: fixed an incorrect error message caused by a bug in + relocation handling Changes in 3.00 (27 Apr 2007): * watcom/le & tmt/adam: fixed a problem when using certain filters diff --git a/src/p_exe.cpp b/src/p_exe.cpp index d1700882..d2922af1 100644 --- a/src/p_exe.cpp +++ b/src/p_exe.cpp @@ -478,7 +478,7 @@ void PackExe::pack(OutputFile *fo) for (ic = 0; ic < ih.relocs; ic++) { unsigned jc = get_le32(wr+4*ic); - set_le32(wr+4*ic, (jc>>16)*16+(jc&0xffff)); + set_le32(wr+4*ic, ((jc>>16)*16+(jc&0xffff)) & 0xfffff); } qsort(wr,ih.relocs,4,le32_compare); relocsize = optimize_relocs(ibuf, ih_imagesize, wr, ih.relocs, w, &has_9a);