1
0
mirror of https://github.com/upx/upx synced 2025-09-28 19:06:07 +08:00

More work so that watom/le now uses compressWithFilters().

This commit is contained in:
Markus F.X.J. Oberhumer 2006-12-06 11:08:32 +01:00
parent ae945ed315
commit f2b9dff596
21 changed files with 158 additions and 157 deletions

View File

@ -442,10 +442,13 @@ private:
#define UPX_F_LINUX_ELF32_ARMBE 133 #define UPX_F_LINUX_ELF32_ARMBE 133
// compression methods
#define M_ALL (-1)
#define M_END (-2)
#define M_NONE (-3)
#define M_SKIP (-4)
#define M_ULTRA_BRUTE (-5)
// compression methods - DO NOT CHANGE // compression methods - DO NOT CHANGE
#define M_END (-1)
#define M_SKIP (-2)
#define M_ULTRA_BRUTE (-3)
#define M_NRV2B_LE32 2 #define M_NRV2B_LE32 2
#define M_NRV2B_8 3 #define M_NRV2B_8 3
#define M_NRV2B_LE16 4 #define M_NRV2B_LE16 4
@ -469,10 +472,11 @@ private:
#define M_IS_DEFLATE(x) ((x) == M_DEFLATE) #define M_IS_DEFLATE(x) ((x) == M_DEFLATE)
// filters - DO NOT CHANGE // filters
#define FT_END (-1) #define FT_END (-1)
#define FT_SKIP (-2) #define FT_NONE (-2)
#define FT_ULTRA_BRUTE (-3) #define FT_SKIP (-3)
#define FT_ULTRA_BRUTE (-4)
/************************************************************************* /*************************************************************************

View File

@ -50,9 +50,9 @@ void options_t::reset()
o->crp.reset(); o->crp.reset();
o->cmd = CMD_NONE; o->cmd = CMD_NONE;
o->method = -1; o->method = M_NONE;
o->level = -1; o->level = -1;
o->filter = -1; o->filter = FT_NONE;
o->backup = -1; o->backup = -1;
o->overlay = -1; o->overlay = -1;

View File

@ -123,7 +123,7 @@ const int *PackArmPe::getCompressionMethods(int method, int level) const
if (!use_thumb_stub) if (!use_thumb_stub)
return getDefaultCompressionMethods_8(method, level); return getDefaultCompressionMethods_8(method, level);
if (method == -1) return m_all; if (method == M_ALL) return m_all;
if (M_IS_LZMA(method)) return m_lzma; if (M_IS_LZMA(method)) return m_lzma;
if (M_IS_NRV2B(method)) return m_nrv2b; if (M_IS_NRV2B(method)) return m_nrv2b;
if (M_IS_NRV2E(method)) return m_nrv2e; if (M_IS_NRV2E(method)) return m_nrv2e;
@ -133,7 +133,7 @@ const int *PackArmPe::getCompressionMethods(int method, int level) const
const int *PackArmPe::getFilters() const const int *PackArmPe::getFilters() const
{ {
static const int filters[] = { 0x50, -1 }; static const int filters[] = { 0x50, FT_END };
return filters; return filters;
} }
@ -710,7 +710,7 @@ void PackArmPe::pack(OutputFile *fo)
upx_compress_config_t cconf; cconf.reset(); upx_compress_config_t cconf; cconf.reset();
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
compressWithFilters(&ft, 2048, &cconf, filter_strategy, compressWithFilters(&ft, 2048, &cconf, filter_strategy,
ih.codebase, rvamin); ih.codebase, rvamin, 0, NULL, 0);
// info: see buildLoader() // info: see buildLoader()
newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) &~ oam1; newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) &~ oam1;
/* /*

View File

@ -58,7 +58,7 @@ const int *PackCom::getFilters() const
{ {
static const int filters[] = { static const int filters[] = {
0x06, 0x03, 0x04, 0x01, 0x05, 0x02, 0x06, 0x03, 0x04, 0x01, 0x05, 0x02,
-1 }; FT_END };
return filters; return filters;
} }

View File

@ -69,7 +69,7 @@ const int *PackDjgpp2::getFilters() const
{ {
static const int filters[] = { static const int filters[] = {
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12, 0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12,
-1 }; FT_END };
return filters; return filters;
} }

View File

@ -63,7 +63,7 @@ const int *PackExe::getCompressionMethods(int method, int level) const
static const int m_nrv2d[] = { M_NRV2D_8, M_END }; static const int m_nrv2d[] = { M_NRV2D_8, M_END };
static const int m_nrv2e[] = { M_NRV2E_8, M_END }; static const int m_nrv2e[] = { M_NRV2E_8, M_END };
if (method == -1) return m_all; if (method == M_ALL) return m_all;
if (M_IS_NRV2B(method)) return m_nrv2b; if (M_IS_NRV2B(method)) return m_nrv2b;
if (M_IS_NRV2D(method)) return m_nrv2d; if (M_IS_NRV2D(method)) return m_nrv2d;
if (M_IS_NRV2E(method)) return m_nrv2e; if (M_IS_NRV2E(method)) return m_nrv2e;

View File

@ -249,8 +249,8 @@ int const *
PackLinuxElf32ppc::getFilters() const PackLinuxElf32ppc::getFilters() const
{ {
static const int filters[] = { static const int filters[] = {
0xd0, -1 0xd0,
}; FT_END };
return filters; return filters;
} }
@ -258,8 +258,8 @@ int const *
PackLinuxElf64amd::getFilters() const PackLinuxElf64amd::getFilters() const
{ {
static const int filters[] = { static const int filters[] = {
0x49, -1 0x49,
}; FT_END };
return filters; return filters;
} }
@ -1424,8 +1424,8 @@ using namespace N_BELE_CTP;
static const int * static const int *
ARM_getFilters(bool const isBE) ARM_getFilters(bool const isBE)
{ {
static const int f50[] = { 0x50, -1 }; static const int f50[] = { 0x50, FT_END };
static const int f51[] = { 0x51, -1 }; static const int f51[] = { 0x51, FT_END };
if (isBE) if (isBE)
return f51; return f51;
return f50; return f50;
@ -1857,7 +1857,7 @@ PackLinuxElf32x86::getFilters() const
0x82, 0x85, 0x82, 0x85,
0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12, 0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12,
#endif #endif
-1 }; FT_END };
return filters; return filters;
} }

View File

@ -100,7 +100,7 @@ const int *PackLinuxI386::getFilters() const
0x83, 0x86, 0x80, 0x84, 0x87, 0x81, 0x82, 0x85, 0x83, 0x86, 0x80, 0x84, 0x87, 0x81, 0x82, 0x85,
0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12, 0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12,
#endif #endif
-1 }; FT_END };
return filters; return filters;
} }

View File

@ -85,7 +85,7 @@ PackLinuxI386sh::buildLoader(Filter const *ft)
// get fresh filter // get fresh filter
Filter fold_ft = *ft; Filter fold_ft = *ft;
fold_ft.init(ft->id, ft->addvalue); fold_ft.init(ft->id, ft->addvalue);
int preferred_ctos[2] = {ft->cto, -1}; int preferred_ctos[2] = { ft->cto, -1 };
fold_ft.preferred_ctos = preferred_ctos; fold_ft.preferred_ctos = preferred_ctos;
// filter // filter

View File

@ -60,7 +60,7 @@ const int *PackMachPPC32::getCompressionMethods(int /*method*/, int /*level*/) c
const int *PackMachPPC32::getFilters() const const int *PackMachPPC32::getFilters() const
{ {
static const int filters[] = { 0xd0, -1 }; static const int filters[] = { 0xd0, FT_END };
return filters; return filters;
} }

View File

@ -60,7 +60,7 @@ const int *PackTmt::getFilters() const
{ {
static const int filters[] = { static const int filters[] = {
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x12, 0x15, 0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x12, 0x15,
-1 }; FT_END };
return filters; return filters;
} }

View File

@ -346,10 +346,10 @@ void PackUnix::packExtent(
ft->cto = 0; ft->cto = 0;
compressWithFilters(ft, OVERHEAD, NULL_cconf, filter_strategy, compressWithFilters(ft, OVERHEAD, NULL_cconf, filter_strategy,
0, 0, hdr_ibuf, hdr_u_len); 0, 0, 0, hdr_ibuf, hdr_u_len);
} }
else { else {
(void) compress(ibuf, obuf); // ignore return value (void) compress(ibuf, ph.u_len, obuf); // ignore return value
} }
if (ph.c_len < ph.u_len) { if (ph.c_len < ph.u_len) {

View File

@ -68,7 +68,7 @@ const int *PackVmlinuxI386::getFilters() const
{ {
static const int filters[] = { static const int filters[] = {
0x49, 0x46, 0x49, 0x46,
-1 }; FT_END };
return filters; return filters;
} }
@ -358,7 +358,7 @@ void PackVmlinuxI386::pack(OutputFile *fo)
ph.u_len = phdri[0].p_offset; ph.u_len = phdri[0].p_offset;
fi->seek(0, SEEK_SET); fi->seek(0, SEEK_SET);
fi->readx(ibuf, ph.u_len); fi->readx(ibuf, ph.u_len);
compress(ibuf, obuf); compress(ibuf, ph.u_len, obuf);
while (0!=*p++) ; while (0!=*p++) ;
shdro[2].sh_name = ptr_diff(p, shstrtab); shdro[2].sh_name = ptr_diff(p, shstrtab);
@ -383,7 +383,7 @@ void PackVmlinuxI386::pack(OutputFile *fo)
ph.level = 1; ph.level = 1;
} }
} }
compress(ibuf, obuf, &cconf); compress(ibuf, ph.u_len, obuf, &cconf);
ph.level = old_level; ph.level = old_level;
// while (0!=*p++) ; // name is the same // while (0!=*p++) ; // name is the same

View File

@ -69,7 +69,7 @@ const int *PackVmlinuzI386::getFilters() const
static const int filters[] = { static const int filters[] = {
0x49, 0x49,
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12, 0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12,
-1 }; FT_END };
return filters; return filters;
} }

View File

@ -804,7 +804,7 @@ void PackW32Pe::pack(OutputFile *fo)
} }
compressWithFilters(&ft, 2048, NULL_cconf, filter_strategy, compressWithFilters(&ft, 2048, NULL_cconf, filter_strategy,
ih.codebase, rvamin); ih.codebase, rvamin, 0, NULL, 0);
// info: see buildLoader() // info: see buildLoader()
newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) &~ oam1; newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) &~ oam1;
if (tlsindex && ((newvsize - ph.c_len - 1024 + oam1) &~ oam1) > tlsindex + 4) if (tlsindex && ((newvsize - ph.c_len - 1024 + oam1) &~ oam1) > tlsindex + 4)

View File

@ -77,7 +77,7 @@ const int *PackWcle::getFilters() const
{ {
static const int filters[] = { static const int filters[] = {
0x26, 0x24, 0x14, 0x11, 0x16, 0x13, 0x25, 0x12, 0x15, 0x26, 0x24, 0x14, 0x11, 0x16, 0x13, 0x25, 0x12, 0x15,
-1 }; FT_END };
return filters; return filters;
} }
@ -428,7 +428,7 @@ void PackWcle::preprocessFixups()
#define RESERVED 0x1000 #define RESERVED 0x1000
void PackWcle::encodeImage(const Filter *ft) void PackWcle::encodeImage(Filter *ft)
{ {
// concatenate image & preprocessed fixups // concatenate image & preprocessed fixups
unsigned isize = soimage + sofixups; unsigned isize = soimage + sofixups;
@ -438,16 +438,18 @@ void PackWcle::encodeImage(const Filter *ft)
delete[] ifixups; ifixups = NULL; delete[] ifixups; ifixups = NULL;
// compress
oimage.allocForCompression(isize, RESERVED+512); oimage.allocForCompression(isize, RESERVED+512);
ph.filter = ft->id; // prepare packheader
ph.filter_cto = ft->cto;
ph.u_len = isize; ph.u_len = isize;
// reserve RESERVED bytes for the decompressor // prepare filter [already done]
if (!compress(ibuf,oimage+RESERVED)) // compress
throwNotCompressible(); upx_compress_config_t cconf; cconf.reset();
ph.overlap_overhead = findOverlapOverhead(oimage+RESERVED, 512); cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
buildLoader(ft); compressWithFilters(ibuf, isize,
oimage + RESERVED,
ibuf + ft->addvalue, ft->buf_len,
NULL, 0,
ft, 512, &cconf, 0);
ibuf.dealloc(); ibuf.dealloc();
soimage = ph.c_len; soimage = ph.c_len;
@ -506,15 +508,13 @@ void PackWcle::pack(OutputFile *fo)
ifixups[sofixups+12] = (unsigned char) (unsigned) objects; ifixups[sofixups+12] = (unsigned char) (unsigned) objects;
sofixups += 13; sofixups += 13;
// filter // prepare filter
Filter ft(ph.level); Filter ft(ph.level);
tryFilters(&ft, iimage+text_vaddr, text_size, text_vaddr); ft.buf_len = text_size;
ft.addvalue = text_vaddr;
// compress
encodeImage(&ft); encodeImage(&ft);
// verify filter
ft.verifyUnfilter();
const unsigned lsize = getLoaderSize(); const unsigned lsize = getLoaderSize();
neweip = getLoaderSection("WCLEMAIN"); neweip = getLoaderSection("WCLEMAIN");
int e_len = getLoaderSectionStart("WCLECUTP"); int e_len = getLoaderSectionStart("WCLECUTP");

View File

@ -74,7 +74,7 @@ protected:
virtual void encodeFixups(); virtual void encodeFixups();
virtual void decodeFixups(); virtual void decodeFixups();
virtual void encodeImage(const Filter *ft); virtual void encodeImage(Filter *ft);
virtual void decodeImage(); virtual void decodeImage();
static void virt2rela(const le_object_table_entry_t *, unsigned *objn, unsigned *addr); static void virt2rela(const le_object_table_entry_t *, unsigned *objn, unsigned *addr);

View File

@ -177,9 +177,10 @@ bool ph_skipVerify(const PackHeader &ph)
// compress - wrap call to low-level upx_compress() // compress - wrap call to low-level upx_compress()
**************************************************************************/ **************************************************************************/
bool Packer::compress(upx_bytep in, upx_bytep out, bool Packer::compress(upx_bytep i_ptr, unsigned i_len, upx_bytep o_ptr,
const upx_compress_config_t *cconf_parm) const upx_compress_config_t *cconf_parm)
{ {
ph.u_len = i_len;
ph.c_len = 0; ph.c_len = 0;
assert(ph.level >= 1); assert(ph.level <= 10); assert(ph.level >= 1); assert(ph.level <= 10);
@ -190,7 +191,7 @@ bool Packer::compress(upx_bytep in, upx_bytep out,
ph.saved_u_adler = ph.u_adler; ph.saved_u_adler = ph.u_adler;
ph.saved_c_adler = ph.c_adler; ph.saved_c_adler = ph.c_adler;
// update checksum of uncompressed data // update checksum of uncompressed data
ph.u_adler = upx_adler32(in, ph.u_len, ph.u_adler); ph.u_adler = upx_adler32(i_ptr, ph.u_len, ph.u_adler);
// set compression paramters // set compression paramters
upx_compress_config_t cconf; cconf.reset(); upx_compress_config_t cconf; cconf.reset();
@ -236,7 +237,7 @@ bool Packer::compress(upx_bytep in, upx_bytep out,
//OutputFile::dump("data.raw", in, ph.u_len); //OutputFile::dump("data.raw", in, ph.u_len);
// compress // compress
int r = upx_compress(in, ph.u_len, out, &ph.c_len, int r = upx_compress(i_ptr, ph.u_len, o_ptr, &ph.c_len,
uip->getCallback(), uip->getCallback(),
ph.method, ph.level, &cconf, &ph.compress_result); ph.method, ph.level, &cconf, &ph.compress_result);
@ -274,13 +275,13 @@ bool Packer::compress(upx_bytep in, upx_bytep out,
return false; return false;
// update checksum of compressed data // update checksum of compressed data
ph.c_adler = upx_adler32(out, ph.c_len, ph.c_adler); ph.c_adler = upx_adler32(o_ptr, ph.c_len, ph.c_adler);
// Decompress and verify. Skip this when using the fastest level. // Decompress and verify. Skip this when using the fastest level.
if (!ph_skipVerify(ph)) if (!ph_skipVerify(ph))
{ {
// decompress // decompress
unsigned new_len = ph.u_len; unsigned new_len = ph.u_len;
r = upx_decompress(out, ph.c_len, in, &new_len, ph.method, &ph.compress_result); r = upx_decompress(o_ptr, ph.c_len, i_ptr, &new_len, ph.method, &ph.compress_result);
//printf("%d %d: %d %d %d\n", ph.method, r, ph.c_len, ph.u_len, new_len); //printf("%d %d: %d %d %d\n", ph.method, r, ph.c_len, ph.u_len, new_len);
if (r != UPX_E_OK) if (r != UPX_E_OK)
throwInternalError("decompression failed"); throwInternalError("decompression failed");
@ -288,7 +289,7 @@ bool Packer::compress(upx_bytep in, upx_bytep out,
throwInternalError("decompression failed (size error)"); throwInternalError("decompression failed (size error)");
// verify decompression // verify decompression
if (ph.u_adler != upx_adler32(in, ph.u_len, ph.saved_u_adler)) if (ph.u_adler != upx_adler32(i_ptr, ph.u_len, ph.saved_u_adler))
throwInternalError("decompression failed (checksum error)"); throwInternalError("decompression failed (checksum error)");
} }
return true; return true;
@ -627,7 +628,7 @@ void Packer::initPackHeader()
memset(&ph, 0, sizeof(ph)); memset(&ph, 0, sizeof(ph));
ph.version = getVersion(); ph.version = getVersion();
ph.format = getFormat(); ph.format = getFormat();
ph.method = -1; ph.method = M_NONE;
ph.level = -1; ph.level = -1;
ph.u_adler = ph.c_adler = ph.saved_u_adler = ph.saved_c_adler = upx_adler32(NULL,0); ph.u_adler = ph.c_adler = ph.saved_u_adler = ph.saved_c_adler = upx_adler32(NULL,0);
ph.buf_offset = -1; ph.buf_offset = -1;
@ -1139,8 +1140,8 @@ void Packer::relocateLoader()
// //
// - updates this->ph // - updates this->ph
// - updates *ft // - updates *ft
// - ibuf[] is restored to the original unfiltered version // - i_ptr[] is restored to the original unfiltered version
// - obuf[] contains the best compressed version // - o_ptr[] contains the best compressed version
// //
// filter_strategy: // filter_strategy:
// n: try the first N filters, use best one // n: try the first N filters, use best one
@ -1258,23 +1259,23 @@ done:
} }
void Packer::compressWithFilters(Filter *parm_ft, void Packer::compressWithFilters(upx_bytep i_ptr, unsigned i_len,
upx_bytep o_ptr,
upx_bytep f_ptr, unsigned f_len,
const upx_bytep hdr_ptr, unsigned hdr_len,
Filter *parm_ft,
const unsigned overlap_range, const unsigned overlap_range,
const upx_compress_config_t *cconf, const upx_compress_config_t *cconf,
int filter_strategy, int filter_strategy)
unsigned filter_off, unsigned compress_buf_off,
const upx_bytep hdr_buf, unsigned hdr_u_len)
{ {
parm_ft->buf_len = f_len;
// struct copies // struct copies
const PackHeader orig_ph = this->ph; const PackHeader orig_ph = this->ph;
PackHeader best_ph = this->ph; PackHeader best_ph = this->ph;
const Filter orig_ft = *parm_ft; const Filter orig_ft = *parm_ft;
Filter best_ft = *parm_ft; Filter best_ft = *parm_ft;
// //
const unsigned compress_buf_len = orig_ph.u_len; best_ph.c_len = i_len;
const unsigned filter_len = orig_ft.buf_len ? orig_ft.buf_len : compress_buf_len;
//
best_ph.c_len = orig_ph.u_len;
best_ph.overlap_overhead = 0; best_ph.overlap_overhead = 0;
unsigned best_ph_lsize = 0; unsigned best_ph_lsize = 0;
unsigned best_hdr_c_len = 0; unsigned best_hdr_c_len = 0;
@ -1282,11 +1283,10 @@ void Packer::compressWithFilters(Filter *parm_ft,
// preconditions // preconditions
assert(orig_ph.filter == 0); assert(orig_ph.filter == 0);
assert(orig_ft.id == 0); assert(orig_ft.id == 0);
assert(filter_off + filter_len <= compress_buf_off + compress_buf_len);
// prepare methods and filters // prepare methods and filters
int methods[256]; int methods[256];
int nmethods = prepareMethods(methods, ph.method, getCompressionMethods(-1, ph.level)); int nmethods = prepareMethods(methods, ph.method, getCompressionMethods(M_ALL, ph.level));
assert(nmethods > 0); assert(nmethods < 256); assert(nmethods > 0); assert(nmethods < 256);
int filters[256]; int filters[256];
int nfilters = prepareFilters(filters, filter_strategy, getFilters()); int nfilters = prepareFilters(filters, filter_strategy, getFilters());
@ -1307,9 +1307,9 @@ void Packer::compressWithFilters(Filter *parm_ft,
else else
uip->ui_total_passes += nfilters * nmethods; uip->ui_total_passes += nfilters * nmethods;
// Working buffer for compressed data. Don't waste memory. // Working buffer for compressed data. Don't waste memory and allocate as needed.
MemBuffer *otemp = &obuf; upx_bytep o_tmp = o_ptr;
MemBuffer otemp_buf; MemBuffer o_tmp_buf;
// compress using all methods/filters // compress using all methods/filters
int nfilters_success_total = 0; int nfilters_success_total = 0;
@ -1317,27 +1317,25 @@ void Packer::compressWithFilters(Filter *parm_ft,
{ {
assert(isValidCompressionMethod(methods[mm])); assert(isValidCompressionMethod(methods[mm]));
unsigned hdr_c_len = 0; unsigned hdr_c_len = 0;
if (hdr_buf && hdr_u_len) if (hdr_ptr != NULL && hdr_len)
{ {
if (nfilters_success_total != 0 && otemp == &obuf) if (nfilters_success_total != 0 && o_tmp == o_ptr)
{ {
// do not overwrite obuf // do not overwrite o_ptr
otemp_buf.allocForCompression(compress_buf_len); o_tmp_buf.allocForCompression(UPX_MAX(hdr_len, i_len));
otemp = &otemp_buf; o_tmp = o_tmp_buf;
} }
int r = upx_compress(hdr_buf, hdr_u_len, *otemp, &hdr_c_len, int r = upx_compress(hdr_ptr, hdr_len, o_tmp, &hdr_c_len,
NULL, methods[mm], 10, NULL, NULL); NULL, methods[mm], 10, NULL, NULL);
if (r != UPX_E_OK) if (r != UPX_E_OK)
throwInternalError("header compression failed"); throwInternalError("header compression failed");
if (hdr_c_len >= hdr_u_len) if (hdr_c_len >= hdr_len)
throwInternalError("header compression size increase"); throwInternalError("header compression size increase");
} }
int nfilters_success_mm = 0; int nfilters_success_mm = 0;
for (int ff = 0; ff < nfilters; ff++) // for all filters for (int ff = 0; ff < nfilters; ff++) // for all filters
{ {
assert(isValidFilter(filters[ff])); assert(isValidFilter(filters[ff]));
ibuf.checkState();
obuf.checkState();
// get fresh packheader // get fresh packheader
ph = orig_ph; ph = orig_ph;
ph.method = methods[mm]; ph.method = methods[mm];
@ -1347,8 +1345,8 @@ void Packer::compressWithFilters(Filter *parm_ft,
Filter ft = orig_ft; Filter ft = orig_ft;
ft.init(ph.filter, orig_ft.addvalue); ft.init(ph.filter, orig_ft.addvalue);
// filter // filter
optimizeFilter(&ft, ibuf + filter_off, filter_len); optimizeFilter(&ft, f_ptr, f_len);
bool success = ft.filter(ibuf + filter_off, filter_len); bool success = ft.filter(f_ptr, f_len);
if (ft.id != 0 && ft.calls == 0) if (ft.id != 0 && ft.calls == 0)
{ {
// filter did not do anything - no need to call ft.unfilter() // filter did not do anything - no need to call ft.unfilter()
@ -1370,23 +1368,23 @@ void Packer::compressWithFilters(Filter *parm_ft,
printf("filter: id 0x%02x size %6d, calls %5d/%5d/%3d/%5d/%5d, cto 0x%02x\n", printf("filter: id 0x%02x size %6d, calls %5d/%5d/%3d/%5d/%5d, cto 0x%02x\n",
ft.id, ft.buf_len, ft.calls, ft.noncalls, ft.wrongcalls, ft.firstcall, ft.lastcall, ft.cto); ft.id, ft.buf_len, ft.calls, ft.noncalls, ft.wrongcalls, ft.firstcall, ft.lastcall, ft.cto);
#endif #endif
if (nfilters_success_total != 0 && otemp == &obuf) if (nfilters_success_total != 0 && o_tmp == o_ptr)
{ {
otemp_buf.allocForCompression(compress_buf_len); o_tmp_buf.allocForCompression(i_len);
otemp = &otemp_buf; o_tmp = o_tmp_buf;
} }
nfilters_success_total++; nfilters_success_total++;
nfilters_success_mm++; nfilters_success_mm++;
ph.filter_cto = ft.cto; ph.filter_cto = ft.cto;
ph.n_mru = ft.n_mru; ph.n_mru = ft.n_mru;
// compress // compress
if (compress(ibuf + compress_buf_off, *otemp, cconf)) if (compress(i_ptr, i_len, o_tmp, cconf))
{ {
unsigned lsize = 0; unsigned lsize = 0;
if (ph.c_len + lsize + hdr_c_len <= best_ph.c_len + best_ph_lsize + best_hdr_c_len) if (ph.c_len + lsize + hdr_c_len <= best_ph.c_len + best_ph_lsize + best_hdr_c_len)
{ {
// get results // get results
ph.overlap_overhead = findOverlapOverhead(*otemp, overlap_range); ph.overlap_overhead = findOverlapOverhead(o_tmp, overlap_range);
buildLoader(&ft); buildLoader(&ft);
lsize = getLoaderSize(); lsize = getLoaderSize();
assert(lsize > 0); assert(lsize > 0);
@ -1414,9 +1412,9 @@ void Packer::compressWithFilters(Filter *parm_ft,
if (update) if (update)
{ {
assert((int)ph.overlap_overhead > 0); assert((int)ph.overlap_overhead > 0);
// update obuf[] with best version // update o_ptr[] with best version
if (otemp != &obuf) if (o_tmp != o_ptr)
memcpy(obuf, *otemp, ph.c_len); memcpy(o_ptr, o_tmp, ph.c_len);
// save compression results // save compression results
best_ph = ph; best_ph = ph;
best_ph_lsize = lsize; best_ph_lsize = lsize;
@ -1424,13 +1422,8 @@ void Packer::compressWithFilters(Filter *parm_ft,
best_ft = ft; best_ft = ft;
} }
} }
// restore ibuf[] - unfilter with verify // restore - unfilter with verify
ft.unfilter(ibuf + filter_off, filter_len, true); ft.unfilter(f_ptr, f_len, true);
//
ibuf.checkState();
obuf.checkState();
otemp->checkState();
//
if (filter_strategy < 0) if (filter_strategy < 0)
break; break;
} }
@ -1462,6 +1455,49 @@ void Packer::compressWithFilters(Filter *parm_ft,
} }
/*************************************************************************
//
**************************************************************************/
void Packer::compressWithFilters(Filter *ft,
const unsigned overlap_range,
const upx_compress_config_t *cconf,
int filter_strategy)
{
compressWithFilters(ft, overlap_range, cconf, filter_strategy,
0, 0, 0, NULL, 0);
}
void Packer::compressWithFilters(Filter *ft,
const unsigned overlap_range,
const upx_compress_config_t *cconf,
int filter_strategy,
unsigned filter_off,
unsigned ibuf_off,
unsigned obuf_off,
const upx_bytep hdr_ptr, unsigned hdr_len)
{
ibuf.checkState(); obuf.checkState();
upx_bytep i_ptr = ibuf + ibuf_off;
unsigned i_len = ph.u_len;
upx_bytep o_ptr = obuf + obuf_off;
upx_bytep f_ptr = ibuf + filter_off;
unsigned f_len = ft->buf_len ? ft->buf_len : i_len;
assert(f_ptr + f_len <= i_ptr + i_len);
compressWithFilters(i_ptr, i_len,
o_ptr,
f_ptr, f_len,
hdr_ptr, hdr_len,
ft, overlap_range, cconf, filter_strategy);
ibuf.checkState(); obuf.checkState();
}
/* /*
vi:ts=4:et:nowrap vi:ts=4:et:nowrap
*/ */

View File

@ -169,7 +169,7 @@ public:
protected: protected:
// main compression drivers // main compression drivers
virtual bool compress(upx_bytep in, upx_bytep out, virtual bool compress(upx_bytep i_ptr, unsigned i_len, upx_bytep o_ptr,
const upx_compress_config_t *cconf = NULL); const upx_compress_config_t *cconf = NULL);
virtual void decompress(const upx_bytep in, upx_bytep out, virtual void decompress(const upx_bytep in, upx_bytep out,
bool verify_checksum = true, Filter *ft = NULL); bool verify_checksum = true, Filter *ft = NULL);
@ -181,11 +181,24 @@ protected:
void compressWithFilters(Filter *ft, void compressWithFilters(Filter *ft,
const unsigned overlap_range, const unsigned overlap_range,
const upx_compress_config_t *cconf, const upx_compress_config_t *cconf,
int filter_strategy = 0, int filter_strategy = 0);
unsigned filter_buf_off = 0, void compressWithFilters(Filter *ft,
unsigned compress_buf_off = 0, const unsigned overlap_range,
const upx_bytep header_buffer = NULL, const upx_compress_config_t *cconf,
unsigned header_length = 0); int filter_strategy,
unsigned filter_buf_off,
unsigned compress_ibuf_off,
unsigned compress_obuf_off,
const upx_bytep hdr_ptr, unsigned hdr_len);
// real compression driver
void compressWithFilters(upx_bytep i_ptr, unsigned i_len,
upx_bytep o_ptr,
upx_bytep f_ptr, unsigned f_len,
const upx_bytep hdr_ptr, unsigned hdr_len,
Filter *ft,
const unsigned overlap_range,
const upx_compress_config_t *cconf,
int filter_strategy);
// util for verifying overlapping decompresion // util for verifying overlapping decompresion
// non-destructive test // non-destructive test
@ -233,10 +246,6 @@ protected:
// filter handling [see packer_f.cpp] // filter handling [see packer_f.cpp]
virtual bool isValidFilter(int filter_id) const; virtual bool isValidFilter(int filter_id) const;
virtual void tryFilters(Filter *ft, upx_byte *buf, unsigned buf_len,
unsigned addvalue=0) const;
virtual void scanFilters(Filter *ft, const upx_byte *buf, unsigned buf_len,
unsigned addvalue=0) const;
virtual void optimizeFilter(Filter *, const upx_byte *, unsigned) const virtual void optimizeFilter(Filter *, const upx_byte *, unsigned) const
{ } { }
virtual void addFilter32(int filter_id); virtual void addFilter32(int filter_id);

View File

@ -60,7 +60,7 @@ const int *Packer::getDefaultCompressionMethods_8(int method, int level, int sma
static const int m_nrv2d[] = { M_NRV2D_8, M_END }; static const int m_nrv2d[] = { M_NRV2D_8, M_END };
static const int m_nrv2e[] = { M_NRV2E_8, M_END }; static const int m_nrv2e[] = { M_NRV2E_8, M_END };
if (method == -1) return m_all; if (method == M_ALL) return m_all;
//if (M_IS_CL1B(method)) return m_cl1b; //if (M_IS_CL1B(method)) return m_cl1b;
if (M_IS_LZMA(method)) return m_lzma; if (M_IS_LZMA(method)) return m_lzma;
if (M_IS_NRV2B(method)) return m_nrv2b; if (M_IS_NRV2B(method)) return m_nrv2b;
@ -83,7 +83,7 @@ const int *Packer::getDefaultCompressionMethods_le32(int method, int level, int
static const int m_nrv2d[] = { M_NRV2D_LE32, M_END }; static const int m_nrv2d[] = { M_NRV2D_LE32, M_END };
static const int m_nrv2e[] = { M_NRV2E_LE32, M_END }; static const int m_nrv2e[] = { M_NRV2E_LE32, M_END };
if (method == -1) return m_all; if (method == M_ALL) return m_all;
//if (M_IS_CL1B(method)) return m_cl1b; //if (M_IS_CL1B(method)) return m_cl1b;
if (M_IS_LZMA(method)) return m_lzma; if (M_IS_LZMA(method)) return m_lzma;
if (M_IS_NRV2B(method)) return m_nrv2b; if (M_IS_NRV2B(method)) return m_nrv2b;

View File

@ -41,54 +41,6 @@ bool Packer::isValidFilter(int filter_id) const
} }
void Packer::tryFilters(Filter *ft, upx_byte *buf, unsigned buf_len,
unsigned addvalue) const
{
// debug
//scanFilters(ft, buf, buf_len, addvalue);
ft->init();
if (opt->filter == 0)
return;
for (const int *f = getFilters(); f && *f >= 0; f++)
{
if (*f == 0) // skip no-filter
continue;
if (opt->filter < 0 || *f == opt->filter)
{
ft->init(*f, addvalue);
optimizeFilter(ft, buf, buf_len);
if (ft->filter(buf, buf_len) && ft->calls > 0)
break; // success
ft->init();
}
}
}
void Packer::scanFilters(Filter *ft, const upx_byte *buf, unsigned buf_len,
unsigned addvalue) const
{
ft->init();
if (opt->filter == 0)
return;
for (const int *f = getFilters(); f && *f >= 0; f++)
{
if (*f == 0) // skip no-filter
continue;
ft->init(*f, addvalue);
//static const int ctos[] = { 0xff, 0xfe, 0x80, 0x22, -1 };
//ft->preferred_ctos = ctos;
if (ft->scan(buf, buf_len))
{
printf("scanFilters: id 0x%02x size: %6d: calls %5d/%5d/%3d, cto 0x%02x\n",
ft->id, ft->buf_len, ft->calls, ft->noncalls, ft->wrongcalls, ft->cto);
}
ft->init();
}
}
/************************************************************************* /*************************************************************************
// addFilter32 // addFilter32
**************************************************************************/ **************************************************************************/