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:
parent
ae945ed315
commit
f2b9dff596
16
src/conf.h
16
src/conf.h
|
@ -442,10 +442,13 @@ private:
|
|||
#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
|
||||
#define M_END (-1)
|
||||
#define M_SKIP (-2)
|
||||
#define M_ULTRA_BRUTE (-3)
|
||||
#define M_NRV2B_LE32 2
|
||||
#define M_NRV2B_8 3
|
||||
#define M_NRV2B_LE16 4
|
||||
|
@ -469,10 +472,11 @@ private:
|
|||
#define M_IS_DEFLATE(x) ((x) == M_DEFLATE)
|
||||
|
||||
|
||||
// filters - DO NOT CHANGE
|
||||
// filters
|
||||
#define FT_END (-1)
|
||||
#define FT_SKIP (-2)
|
||||
#define FT_ULTRA_BRUTE (-3)
|
||||
#define FT_NONE (-2)
|
||||
#define FT_SKIP (-3)
|
||||
#define FT_ULTRA_BRUTE (-4)
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
|
|
|
@ -50,9 +50,9 @@ void options_t::reset()
|
|||
o->crp.reset();
|
||||
|
||||
o->cmd = CMD_NONE;
|
||||
o->method = -1;
|
||||
o->method = M_NONE;
|
||||
o->level = -1;
|
||||
o->filter = -1;
|
||||
o->filter = FT_NONE;
|
||||
|
||||
o->backup = -1;
|
||||
o->overlay = -1;
|
||||
|
|
|
@ -123,7 +123,7 @@ const int *PackArmPe::getCompressionMethods(int method, int level) const
|
|||
if (!use_thumb_stub)
|
||||
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_NRV2B(method)) return m_nrv2b;
|
||||
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
|
||||
{
|
||||
static const int filters[] = { 0x50, -1 };
|
||||
static const int filters[] = { 0x50, FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
|
@ -710,7 +710,7 @@ void PackArmPe::pack(OutputFile *fo)
|
|||
upx_compress_config_t cconf; cconf.reset();
|
||||
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||
compressWithFilters(&ft, 2048, &cconf, filter_strategy,
|
||||
ih.codebase, rvamin);
|
||||
ih.codebase, rvamin, 0, NULL, 0);
|
||||
// info: see buildLoader()
|
||||
newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) &~ oam1;
|
||||
/*
|
||||
|
|
|
@ -58,7 +58,7 @@ const int *PackCom::getFilters() const
|
|||
{
|
||||
static const int filters[] = {
|
||||
0x06, 0x03, 0x04, 0x01, 0x05, 0x02,
|
||||
-1 };
|
||||
FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ const int *PackDjgpp2::getFilters() const
|
|||
{
|
||||
static const int filters[] = {
|
||||
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12,
|
||||
-1 };
|
||||
FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
|
|
|
@ -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_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_NRV2D(method)) return m_nrv2d;
|
||||
if (M_IS_NRV2E(method)) return m_nrv2e;
|
||||
|
|
|
@ -249,8 +249,8 @@ int const *
|
|||
PackLinuxElf32ppc::getFilters() const
|
||||
{
|
||||
static const int filters[] = {
|
||||
0xd0, -1
|
||||
};
|
||||
0xd0,
|
||||
FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
|
@ -258,8 +258,8 @@ int const *
|
|||
PackLinuxElf64amd::getFilters() const
|
||||
{
|
||||
static const int filters[] = {
|
||||
0x49, -1
|
||||
};
|
||||
0x49,
|
||||
FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
|
@ -1424,8 +1424,8 @@ using namespace N_BELE_CTP;
|
|||
static const int *
|
||||
ARM_getFilters(bool const isBE)
|
||||
{
|
||||
static const int f50[] = { 0x50, -1 };
|
||||
static const int f51[] = { 0x51, -1 };
|
||||
static const int f50[] = { 0x50, FT_END };
|
||||
static const int f51[] = { 0x51, FT_END };
|
||||
if (isBE)
|
||||
return f51;
|
||||
return f50;
|
||||
|
@ -1857,7 +1857,7 @@ PackLinuxElf32x86::getFilters() const
|
|||
0x82, 0x85,
|
||||
0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12,
|
||||
#endif
|
||||
-1 };
|
||||
FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ const int *PackLinuxI386::getFilters() const
|
|||
0x83, 0x86, 0x80, 0x84, 0x87, 0x81, 0x82, 0x85,
|
||||
0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12,
|
||||
#endif
|
||||
-1 };
|
||||
FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ PackLinuxI386sh::buildLoader(Filter const *ft)
|
|||
// get fresh filter
|
||||
Filter fold_ft = *ft;
|
||||
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;
|
||||
|
||||
// filter
|
||||
|
|
|
@ -60,7 +60,7 @@ const int *PackMachPPC32::getCompressionMethods(int /*method*/, int /*level*/) c
|
|||
|
||||
const int *PackMachPPC32::getFilters() const
|
||||
{
|
||||
static const int filters[] = { 0xd0, -1 };
|
||||
static const int filters[] = { 0xd0, FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ const int *PackTmt::getFilters() const
|
|||
{
|
||||
static const int filters[] = {
|
||||
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x12, 0x15,
|
||||
-1 };
|
||||
FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
|
|
|
@ -346,10 +346,10 @@ void PackUnix::packExtent(
|
|||
ft->cto = 0;
|
||||
|
||||
compressWithFilters(ft, OVERHEAD, NULL_cconf, filter_strategy,
|
||||
0, 0, hdr_ibuf, hdr_u_len);
|
||||
0, 0, 0, hdr_ibuf, hdr_u_len);
|
||||
}
|
||||
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) {
|
||||
|
|
|
@ -68,7 +68,7 @@ const int *PackVmlinuxI386::getFilters() const
|
|||
{
|
||||
static const int filters[] = {
|
||||
0x49, 0x46,
|
||||
-1 };
|
||||
FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
|
@ -358,7 +358,7 @@ void PackVmlinuxI386::pack(OutputFile *fo)
|
|||
ph.u_len = phdri[0].p_offset;
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(ibuf, ph.u_len);
|
||||
compress(ibuf, obuf);
|
||||
compress(ibuf, ph.u_len, obuf);
|
||||
|
||||
while (0!=*p++) ;
|
||||
shdro[2].sh_name = ptr_diff(p, shstrtab);
|
||||
|
@ -383,7 +383,7 @@ void PackVmlinuxI386::pack(OutputFile *fo)
|
|||
ph.level = 1;
|
||||
}
|
||||
}
|
||||
compress(ibuf, obuf, &cconf);
|
||||
compress(ibuf, ph.u_len, obuf, &cconf);
|
||||
ph.level = old_level;
|
||||
|
||||
// while (0!=*p++) ; // name is the same
|
||||
|
|
|
@ -69,7 +69,7 @@ const int *PackVmlinuzI386::getFilters() const
|
|||
static const int filters[] = {
|
||||
0x49,
|
||||
0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12,
|
||||
-1 };
|
||||
FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
|
|
|
@ -804,7 +804,7 @@ void PackW32Pe::pack(OutputFile *fo)
|
|||
}
|
||||
|
||||
compressWithFilters(&ft, 2048, NULL_cconf, filter_strategy,
|
||||
ih.codebase, rvamin);
|
||||
ih.codebase, rvamin, 0, NULL, 0);
|
||||
// info: see buildLoader()
|
||||
newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) &~ oam1;
|
||||
if (tlsindex && ((newvsize - ph.c_len - 1024 + oam1) &~ oam1) > tlsindex + 4)
|
||||
|
|
|
@ -77,7 +77,7 @@ const int *PackWcle::getFilters() const
|
|||
{
|
||||
static const int filters[] = {
|
||||
0x26, 0x24, 0x14, 0x11, 0x16, 0x13, 0x25, 0x12, 0x15,
|
||||
-1 };
|
||||
FT_END };
|
||||
return filters;
|
||||
}
|
||||
|
||||
|
@ -428,7 +428,7 @@ void PackWcle::preprocessFixups()
|
|||
|
||||
|
||||
#define RESERVED 0x1000
|
||||
void PackWcle::encodeImage(const Filter *ft)
|
||||
void PackWcle::encodeImage(Filter *ft)
|
||||
{
|
||||
// concatenate image & preprocessed fixups
|
||||
unsigned isize = soimage + sofixups;
|
||||
|
@ -438,16 +438,18 @@ void PackWcle::encodeImage(const Filter *ft)
|
|||
|
||||
delete[] ifixups; ifixups = NULL;
|
||||
|
||||
// compress
|
||||
oimage.allocForCompression(isize, RESERVED+512);
|
||||
ph.filter = ft->id;
|
||||
ph.filter_cto = ft->cto;
|
||||
// prepare packheader
|
||||
ph.u_len = isize;
|
||||
// reserve RESERVED bytes for the decompressor
|
||||
if (!compress(ibuf,oimage+RESERVED))
|
||||
throwNotCompressible();
|
||||
ph.overlap_overhead = findOverlapOverhead(oimage+RESERVED, 512);
|
||||
buildLoader(ft);
|
||||
// prepare filter [already done]
|
||||
// compress
|
||||
upx_compress_config_t cconf; cconf.reset();
|
||||
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||
compressWithFilters(ibuf, isize,
|
||||
oimage + RESERVED,
|
||||
ibuf + ft->addvalue, ft->buf_len,
|
||||
NULL, 0,
|
||||
ft, 512, &cconf, 0);
|
||||
|
||||
ibuf.dealloc();
|
||||
soimage = ph.c_len;
|
||||
|
@ -506,15 +508,13 @@ void PackWcle::pack(OutputFile *fo)
|
|||
ifixups[sofixups+12] = (unsigned char) (unsigned) objects;
|
||||
sofixups += 13;
|
||||
|
||||
// filter
|
||||
// prepare filter
|
||||
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);
|
||||
|
||||
// verify filter
|
||||
ft.verifyUnfilter();
|
||||
|
||||
const unsigned lsize = getLoaderSize();
|
||||
neweip = getLoaderSection("WCLEMAIN");
|
||||
int e_len = getLoaderSectionStart("WCLECUTP");
|
||||
|
|
|
@ -74,7 +74,7 @@ protected:
|
|||
virtual void encodeFixups();
|
||||
virtual void decodeFixups();
|
||||
|
||||
virtual void encodeImage(const Filter *ft);
|
||||
virtual void encodeImage(Filter *ft);
|
||||
virtual void decodeImage();
|
||||
|
||||
static void virt2rela(const le_object_table_entry_t *, unsigned *objn, unsigned *addr);
|
||||
|
|
132
src/packer.cpp
132
src/packer.cpp
|
@ -177,9 +177,10 @@ bool ph_skipVerify(const PackHeader &ph)
|
|||
// 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)
|
||||
{
|
||||
ph.u_len = i_len;
|
||||
ph.c_len = 0;
|
||||
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_c_adler = ph.c_adler;
|
||||
// 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
|
||||
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);
|
||||
|
||||
// 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(),
|
||||
ph.method, ph.level, &cconf, &ph.compress_result);
|
||||
|
||||
|
@ -274,13 +275,13 @@ bool Packer::compress(upx_bytep in, upx_bytep out,
|
|||
return false;
|
||||
|
||||
// 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.
|
||||
if (!ph_skipVerify(ph))
|
||||
{
|
||||
// decompress
|
||||
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);
|
||||
if (r != UPX_E_OK)
|
||||
throwInternalError("decompression failed");
|
||||
|
@ -288,7 +289,7 @@ bool Packer::compress(upx_bytep in, upx_bytep out,
|
|||
throwInternalError("decompression failed (size error)");
|
||||
|
||||
// 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)");
|
||||
}
|
||||
return true;
|
||||
|
@ -627,7 +628,7 @@ void Packer::initPackHeader()
|
|||
memset(&ph, 0, sizeof(ph));
|
||||
ph.version = getVersion();
|
||||
ph.format = getFormat();
|
||||
ph.method = -1;
|
||||
ph.method = M_NONE;
|
||||
ph.level = -1;
|
||||
ph.u_adler = ph.c_adler = ph.saved_u_adler = ph.saved_c_adler = upx_adler32(NULL,0);
|
||||
ph.buf_offset = -1;
|
||||
|
@ -1139,8 +1140,8 @@ void Packer::relocateLoader()
|
|||
//
|
||||
// - updates this->ph
|
||||
// - updates *ft
|
||||
// - ibuf[] is restored to the original unfiltered version
|
||||
// - obuf[] contains the best compressed version
|
||||
// - i_ptr[] is restored to the original unfiltered version
|
||||
// - o_ptr[] contains the best compressed version
|
||||
//
|
||||
// filter_strategy:
|
||||
// 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 upx_compress_config_t *cconf,
|
||||
int filter_strategy,
|
||||
unsigned filter_off, unsigned compress_buf_off,
|
||||
const upx_bytep hdr_buf, unsigned hdr_u_len)
|
||||
int filter_strategy)
|
||||
{
|
||||
parm_ft->buf_len = f_len;
|
||||
// struct copies
|
||||
const PackHeader orig_ph = this->ph;
|
||||
PackHeader best_ph = this->ph;
|
||||
const Filter orig_ft = *parm_ft;
|
||||
Filter best_ft = *parm_ft;
|
||||
//
|
||||
const unsigned compress_buf_len = orig_ph.u_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.c_len = i_len;
|
||||
best_ph.overlap_overhead = 0;
|
||||
unsigned best_ph_lsize = 0;
|
||||
unsigned best_hdr_c_len = 0;
|
||||
|
@ -1282,11 +1283,10 @@ void Packer::compressWithFilters(Filter *parm_ft,
|
|||
// preconditions
|
||||
assert(orig_ph.filter == 0);
|
||||
assert(orig_ft.id == 0);
|
||||
assert(filter_off + filter_len <= compress_buf_off + compress_buf_len);
|
||||
|
||||
// prepare methods and filters
|
||||
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);
|
||||
int filters[256];
|
||||
int nfilters = prepareFilters(filters, filter_strategy, getFilters());
|
||||
|
@ -1307,9 +1307,9 @@ void Packer::compressWithFilters(Filter *parm_ft,
|
|||
else
|
||||
uip->ui_total_passes += nfilters * nmethods;
|
||||
|
||||
// Working buffer for compressed data. Don't waste memory.
|
||||
MemBuffer *otemp = &obuf;
|
||||
MemBuffer otemp_buf;
|
||||
// Working buffer for compressed data. Don't waste memory and allocate as needed.
|
||||
upx_bytep o_tmp = o_ptr;
|
||||
MemBuffer o_tmp_buf;
|
||||
|
||||
// compress using all methods/filters
|
||||
int nfilters_success_total = 0;
|
||||
|
@ -1317,27 +1317,25 @@ void Packer::compressWithFilters(Filter *parm_ft,
|
|||
{
|
||||
assert(isValidCompressionMethod(methods[mm]));
|
||||
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
|
||||
otemp_buf.allocForCompression(compress_buf_len);
|
||||
otemp = &otemp_buf;
|
||||
// do not overwrite o_ptr
|
||||
o_tmp_buf.allocForCompression(UPX_MAX(hdr_len, i_len));
|
||||
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);
|
||||
if (r != UPX_E_OK)
|
||||
throwInternalError("header compression failed");
|
||||
if (hdr_c_len >= hdr_u_len)
|
||||
if (hdr_c_len >= hdr_len)
|
||||
throwInternalError("header compression size increase");
|
||||
}
|
||||
int nfilters_success_mm = 0;
|
||||
for (int ff = 0; ff < nfilters; ff++) // for all filters
|
||||
{
|
||||
assert(isValidFilter(filters[ff]));
|
||||
ibuf.checkState();
|
||||
obuf.checkState();
|
||||
// get fresh packheader
|
||||
ph = orig_ph;
|
||||
ph.method = methods[mm];
|
||||
|
@ -1347,8 +1345,8 @@ void Packer::compressWithFilters(Filter *parm_ft,
|
|||
Filter ft = orig_ft;
|
||||
ft.init(ph.filter, orig_ft.addvalue);
|
||||
// filter
|
||||
optimizeFilter(&ft, ibuf + filter_off, filter_len);
|
||||
bool success = ft.filter(ibuf + filter_off, filter_len);
|
||||
optimizeFilter(&ft, f_ptr, f_len);
|
||||
bool success = ft.filter(f_ptr, f_len);
|
||||
if (ft.id != 0 && ft.calls == 0)
|
||||
{
|
||||
// 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",
|
||||
ft.id, ft.buf_len, ft.calls, ft.noncalls, ft.wrongcalls, ft.firstcall, ft.lastcall, ft.cto);
|
||||
#endif
|
||||
if (nfilters_success_total != 0 && otemp == &obuf)
|
||||
if (nfilters_success_total != 0 && o_tmp == o_ptr)
|
||||
{
|
||||
otemp_buf.allocForCompression(compress_buf_len);
|
||||
otemp = &otemp_buf;
|
||||
o_tmp_buf.allocForCompression(i_len);
|
||||
o_tmp = o_tmp_buf;
|
||||
}
|
||||
nfilters_success_total++;
|
||||
nfilters_success_mm++;
|
||||
ph.filter_cto = ft.cto;
|
||||
ph.n_mru = ft.n_mru;
|
||||
// compress
|
||||
if (compress(ibuf + compress_buf_off, *otemp, cconf))
|
||||
if (compress(i_ptr, i_len, o_tmp, cconf))
|
||||
{
|
||||
unsigned lsize = 0;
|
||||
if (ph.c_len + lsize + hdr_c_len <= best_ph.c_len + best_ph_lsize + best_hdr_c_len)
|
||||
{
|
||||
// get results
|
||||
ph.overlap_overhead = findOverlapOverhead(*otemp, overlap_range);
|
||||
ph.overlap_overhead = findOverlapOverhead(o_tmp, overlap_range);
|
||||
buildLoader(&ft);
|
||||
lsize = getLoaderSize();
|
||||
assert(lsize > 0);
|
||||
|
@ -1414,9 +1412,9 @@ void Packer::compressWithFilters(Filter *parm_ft,
|
|||
if (update)
|
||||
{
|
||||
assert((int)ph.overlap_overhead > 0);
|
||||
// update obuf[] with best version
|
||||
if (otemp != &obuf)
|
||||
memcpy(obuf, *otemp, ph.c_len);
|
||||
// update o_ptr[] with best version
|
||||
if (o_tmp != o_ptr)
|
||||
memcpy(o_ptr, o_tmp, ph.c_len);
|
||||
// save compression results
|
||||
best_ph = ph;
|
||||
best_ph_lsize = lsize;
|
||||
|
@ -1424,13 +1422,8 @@ void Packer::compressWithFilters(Filter *parm_ft,
|
|||
best_ft = ft;
|
||||
}
|
||||
}
|
||||
// restore ibuf[] - unfilter with verify
|
||||
ft.unfilter(ibuf + filter_off, filter_len, true);
|
||||
//
|
||||
ibuf.checkState();
|
||||
obuf.checkState();
|
||||
otemp->checkState();
|
||||
//
|
||||
// restore - unfilter with verify
|
||||
ft.unfilter(f_ptr, f_len, true);
|
||||
if (filter_strategy < 0)
|
||||
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
|
||||
*/
|
||||
|
|
29
src/packer.h
29
src/packer.h
|
@ -169,7 +169,7 @@ public:
|
|||
|
||||
protected:
|
||||
// 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);
|
||||
virtual void decompress(const upx_bytep in, upx_bytep out,
|
||||
bool verify_checksum = true, Filter *ft = NULL);
|
||||
|
@ -181,11 +181,24 @@ protected:
|
|||
void compressWithFilters(Filter *ft,
|
||||
const unsigned overlap_range,
|
||||
const upx_compress_config_t *cconf,
|
||||
int filter_strategy = 0,
|
||||
unsigned filter_buf_off = 0,
|
||||
unsigned compress_buf_off = 0,
|
||||
const upx_bytep header_buffer = NULL,
|
||||
unsigned header_length = 0);
|
||||
int filter_strategy = 0);
|
||||
void compressWithFilters(Filter *ft,
|
||||
const unsigned overlap_range,
|
||||
const upx_compress_config_t *cconf,
|
||||
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
|
||||
// non-destructive test
|
||||
|
@ -233,10 +246,6 @@ protected:
|
|||
|
||||
// filter handling [see packer_f.cpp]
|
||||
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 addFilter32(int filter_id);
|
||||
|
|
|
@ -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_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_LZMA(method)) return m_lzma;
|
||||
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_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_LZMA(method)) return m_lzma;
|
||||
if (M_IS_NRV2B(method)) return m_nrv2b;
|
||||
|
|
|
@ -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
|
||||
**************************************************************************/
|
||||
|
|
Loading…
Reference in New Issue
Block a user