Added new option '--ultra-brute'.

This commit is contained in:
Markus F.X.J. Oberhumer
2006-12-01 02:47:46 +01:00
parent 83052eafae
commit 1d0d538d0c
13 changed files with 76 additions and 75 deletions
+10 -3
View File
@@ -189,7 +189,7 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
const upx_compress_config_t *cconf_parm,
upx_compress_result_t *cresult )
{
assert(method == M_LZMA);
assert(M_IS_LZMA(method));
assert(level > 0); assert(cresult != NULL);
int r = UPX_E_ERROR;
@@ -241,6 +241,12 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
pr[3].uintVal = lzma_compress_config_t::dict_size_t::default_value_c;
pr[5].uintVal = lzma_compress_config_t::num_fast_bytes_t::default_value_c;
#endif
// method overrides
if (method >= 0x100) {
pr[0].uintVal = (method >> 16) & 15;
pr[1].uintVal = (method >> 12) & 15;
pr[2].uintVal = (method >> 8) & 15;
}
#if 0
// DEBUG - set sizes so that we use a maxmimum amount of stack.
// These settings cause res->num_probs == 3147574, i.e. we will
@@ -382,6 +388,7 @@ int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
error:
*dst_len = os.Pos;
//printf("\nlzma_compress: %d: %u %u %u %u %u, %u - > %u\n", r, res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs, src_len, *dst_len);
return r;
}
@@ -402,7 +409,7 @@ int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
int method,
const upx_compress_result_t *cresult )
{
assert(method == M_LZMA);
assert(M_IS_LZMA(method));
// see res->num_probs above
COMPILE_TIME_ASSERT(sizeof(CProb) == 2)
COMPILE_TIME_ASSERT(LZMA_BASE_SIZE == 1846)
@@ -479,7 +486,7 @@ int upx_lzma_test_overlap ( const upx_bytep buf, unsigned src_off,
int method,
const upx_compress_result_t *cresult )
{
assert(method == M_LZMA);
assert(M_IS_LZMA(method));
// FIXME - implement this
// Note that Packer::verifyOverlappingDecompression() will
+2 -1
View File
@@ -415,6 +415,7 @@ private:
// compression methods - DO NOT CHANGE
#define M_SKIP (-2)
#define M_END (-1)
#define M_ULTRA_BRUTE (-3)
#define M_NRV2B_LE32 2
#define M_NRV2B_8 3
#define M_NRV2B_LE16 4
@@ -434,7 +435,7 @@ private:
#define M_IS_NRV2D(x) ((x) >= M_NRV2D_LE32 && (x) <= M_NRV2D_LE16)
#define M_IS_NRV2E(x) ((x) >= M_NRV2E_LE32 && (x) <= M_NRV2E_LE16)
#define M_IS_CL1B(x) ((x) >= M_CL1B_LE32 && (x) <= M_CL1B_LE16)
#define M_IS_LZMA(x) ((x) == M_LZMA)
#define M_IS_LZMA(x) (((x) & 255) == M_LZMA)
#define M_IS_DEFLATE(x) ((x) == M_DEFLATE)
+10 -4
View File
@@ -499,7 +499,7 @@ static int do_option(int optc, const char *arg)
case 'f':
opt->force++;
break;
case 902:
case 909:
set_cmd(CMD_FILEINFO);
break;
case 'h':
@@ -568,7 +568,7 @@ static int do_option(int optc, const char *arg)
break;
case 722:
opt->all_methods_use_lzma = false;
if (opt->method == M_LZMA)
if (M_IS_LZMA(opt->method))
opt->method = -1;
break;
@@ -586,6 +586,9 @@ static int do_option(int optc, const char *arg)
e_method(opt->method, optc);
break;
case 902: // --ultra-brute
opt->ultra_brute = true;
/* fallthrough */
case 901: // --brute
opt->all_methods = true;
opt->all_methods_use_lzma = true;
@@ -656,6 +659,7 @@ static int do_option(int optc, const char *arg)
break;
case 524: // --all-methods
opt->all_methods = true;
opt->all_methods_use_lzma = true;
opt->method = -1;
break;
case 525: // --exact
@@ -871,10 +875,11 @@ static const struct mfx_option longopts[] =
// commands
{"best", 0x10, 0, 900}, // compress best
{"brute", 0x10, 0, 901}, // compress best, brute force
{"ultra-brute", 0x10, 0, 902}, // compress best, brute force
{"decompress", 0, 0, 'd'}, // decompress
{"fast", 0x10, 0, '1'}, // compress faster
{"fileinfo", 0x10, 0, 902}, // display info about file
{"file-info", 0x10, 0, 902}, // display info about file
{"fileinfo", 0x10, 0, 909}, // display info about file
{"file-info", 0x10, 0, 909}, // display info about file
{"help", 0, 0, 'h'+256}, // give help
{"license", 0, 0, 'L'}, // display software license
{"list", 0, 0, 'l'}, // list compressed exe
@@ -1039,6 +1044,7 @@ static const struct mfx_option longopts[] =
// commands
{"best", 0x10, 0, 900}, // compress best
{"brute", 0x10, 0, 901}, // compress best, brute force
{"ultra-brute", 0x10, 0, 902}, // compress best, brute force
{"fast", 0x10, 0, '1'}, // compress faster
// options
+1
View File
@@ -49,6 +49,7 @@ struct options_t {
int method;
int level; // compression level 1..10
int filter; // preferred filter from Packer::getFilters()
bool ultra_brute;
bool all_methods; // try all available compression methods ?
bool all_methods_use_lzma;
bool all_filters; // try all available filters ?
+2 -2
View File
@@ -97,9 +97,9 @@ void PackDjgpp2::buildLoader(const Filter *ft)
addLoader("IDENTSTR,DJ2MAIN1",
ft->id ? "DJCALLT1" : "",
"DJ2MAIN2",
ph.method == M_LZMA ? "LZMA_INIT_STACK" : "",
M_IS_LZMA(ph.method) ? "LZMA_INIT_STACK" : "",
getDecompressorSections(),
ph.method == M_LZMA ? "LZMA_DONE_STACK" : "",
M_IS_LZMA(ph.method) ? "LZMA_DONE_STACK" : "",
"DJ2BSS00",
NULL
);
+1 -1
View File
@@ -464,7 +464,7 @@ PackLinuxElf32::buildLinuxLoader(
if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc)
throwInternalError("loader compression failed");
#if 0 //{ debugging only
if (M_LZMA==ph.method) {
if (M_IS_LZMA(ph.method)) {
ucl_uint tmp_len = h.sz_unc; // LZMA uses this as EOF
unsigned char *tmp = new unsigned char[tmp_len];
memset(tmp, 0, tmp_len);
+1 -1
View File
@@ -373,7 +373,7 @@ PackLinuxI386::buildLinuxLoader(
addLoader("IDENTSTR", NULL);
addLoader("LEXEC020", NULL);
addLoader("FOLDEXEC", NULL);
if (ph.method == M_LZMA) {
if (M_IS_LZMA(ph.method)) {
const lzma_compress_result_t *res = &ph.compress_result.result_lzma;
acc_uint32e_t properties = // lc, lp, pb, dummy
(res->lit_context_bits << 0) |
+17 -17
View File
@@ -300,7 +300,7 @@ void PackPs1::buildLoader(const Filter *)
else if (ph.method == M_NRV2E_LE32)
method = isCon ? "nrv2e.small,32bit.sub,nrv.done" :
"nrv2e.32bit,nrv.done";
else if (ph.method == M_LZMA)
else if (M_IS_LZMA(ph.method))
method = "nrv2b.small,8bit.sub,nrv.done,lzma.prep";
else
throwInternalError("unknown compression method");
@@ -319,7 +319,7 @@ void PackPs1::buildLoader(const Filter *)
foundBss = findBssSection();
if (ph.method == M_LZMA && !buildPart2)
if (M_IS_LZMA(ph.method) && !buildPart2)
{
initLoader(stub_mipsel_r3000_ps1, sizeof(stub_mipsel_r3000_ps1));
addLoader("decompressor.start",
@@ -329,7 +329,7 @@ void PackPs1::buildLoader(const Filter *)
}
else
{
if (ph.method == M_LZMA && buildPart2)
if (M_IS_LZMA(ph.method) && buildPart2)
{
sz_lcpr = MemBuffer::getSizeForCompression(sz_lunc);
unsigned char *cprLoader = new unsigned char[sz_lcpr];
@@ -338,7 +338,7 @@ void PackPs1::buildLoader(const Filter *)
if (r != UPX_E_OK || sz_lcpr >= sz_lunc)
throwInternalError("loader compression failed");
initLoader(stub_mipsel_r3000_ps1, sizeof(stub_mipsel_r3000_ps1),
(ph.method != M_LZMA || isCon) ? 0 : 1);
isCon || !M_IS_LZMA(ph.method) ? 0 : 1);
linker->addSection("lzma.exec", cprLoader, sz_lcpr, 0);
delete [] cprLoader;
}
@@ -352,7 +352,7 @@ void PackPs1::buildLoader(const Filter *)
if (isCon)
{
if (ph.method == M_LZMA)
if (M_IS_LZMA(ph.method))
addLoader(!foundBss ? "con.start" : "bss.con.start",
method,
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
@@ -368,7 +368,7 @@ void PackPs1::buildLoader(const Filter *)
}
else
{
if (ph.method == M_LZMA)
if (M_IS_LZMA(ph.method))
addLoader("cdb.start.lzma", "pad.code", "cdb.entry.lzma", method, "cdb.lzma.cpr",
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
"lzma.exec", NULL);
@@ -441,10 +441,10 @@ bool PackPs1::findBssSection()
if (0 < ALIGN_DOWN(bss_end - bss_start, 4) )
{
unsigned wkmem_sz = (ph.method == M_LZMA) ? 32768 : 800;
unsigned wkmem_sz = M_IS_LZMA(ph.method) ? 32768 : 800;
unsigned end_offs = ih.tx_ptr + fdata_size + overlap;
if (bss_end > (end_offs + wkmem_sz))
return (isCon || (!isCon && (ph.method == M_LZMA)));
return isCon || (!isCon && M_IS_LZMA(ph.method));
else
return false;
}
@@ -507,7 +507,7 @@ void PackPs1::pack(OutputFile *fo)
unsigned lzma_init = 0;
if (ph.method == M_LZMA)
if (M_IS_LZMA(ph.method))
{
sz_lunc = getLoaderSize();
@@ -553,7 +553,7 @@ void PackPs1::pack(OutputFile *fo)
}
else
{
d_len = (lsize - h_len) - getLoaderSectionStart((ph.method == M_LZMA) ? "cdb.entry.lzma" : "cdb.entry");
d_len = (lsize - h_len) - getLoaderSectionStart(M_IS_LZMA(ph.method) ? "cdb.entry.lzma" : "cdb.entry");
e_len = (lsize - d_len) - h_len;
}
@@ -561,10 +561,10 @@ void PackPs1::pack(OutputFile *fo)
linker->defineSymbol("SC", MIPS_LO(sa_cnt > (0x10000 << 2) ?
sa_cnt >> 5 : sa_cnt >> 2));
linker->defineSymbol("DECO", decomp_data_start);
linker->defineSymbol("ldr_sz", (ph.method == M_LZMA ? sz_lunc + 16 : (d_len-pad_code)));
linker->defineSymbol("ldr_sz", M_IS_LZMA(ph.method) ? sz_lunc + 16 : (d_len-pad_code));
if (foundBss)
if (ph.method == M_LZMA)
if (M_IS_LZMA(ph.method))
linker->defineSymbol("wrkmem", bss_end - 160 - getDecompressorWrkmemSize()
- (sz_lunc + 16));
else
@@ -588,7 +588,7 @@ void PackPs1::pack(OutputFile *fo)
ibuf.clear(0,fdata_size);
upx_bytep paddata = ibuf;
if (ph.method == M_LZMA)
if (M_IS_LZMA(ph.method))
{
linker->defineSymbol("lzma_init_off", lzma_init);
linker->defineSymbol("gb_e", linker->getSymbolOffset("gb8_e"));
@@ -600,7 +600,7 @@ void PackPs1::pack(OutputFile *fo)
if (isCon)
{
linker->defineSymbol("PAD", pad_code);
if (ph.method == M_LZMA)
if (M_IS_LZMA(ph.method))
linker->defineSymbol("DCRT", (entry + getLoaderSectionStart("lzma.exec")));
else
linker->defineSymbol("DCRT", (entry + (e_len - d_len)));
@@ -609,7 +609,7 @@ void PackPs1::pack(OutputFile *fo)
{
linker->defineSymbol("PSVR", FIX_PSVR);
linker->defineSymbol("CPDO", comp_data_start);
if (ph.method == M_LZMA)
if (M_IS_LZMA(ph.method))
linker->defineSymbol("lzma_cpr", getLoaderSectionStart("lzma.exec")
- getLoaderSectionStart("cdb.entry.lzma"));
}
@@ -621,7 +621,7 @@ void PackPs1::pack(OutputFile *fo)
memcpy(loader, getLoader(), lsize);
patchPackHeader(loader, lsize);
if (!isCon && ph.method == M_LZMA && (HD_CODE_OFS + d_len + h_len) > CD_SEC)
if (!isCon && M_IS_LZMA(ph.method) && (HD_CODE_OFS + d_len + h_len) > CD_SEC)
throwInternalError("lzma --boot-only loader > 2048");
// ps1_exe_t structure
@@ -655,7 +655,7 @@ void PackPs1::pack(OutputFile *fo)
printf("%-13s: eof in mem OF : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr + oh.tx_len);
unsigned char i = 0;
if (isCon) { if (foundBss) i = 1; }
else { i = 2; if (ph.method == M_LZMA) { if (!foundBss) i = 3; else i = 4; } }
else { i = 2; if (M_IS_LZMA(ph.method)) { if (!foundBss) i = 3; else i = 4; } }
const char *loader_method[] = { "con/stack", "con/bss", "cdb", "cdb/stack", "cdb/bss" };
char method_name[32+1]; set_method_name(method_name, sizeof(method_name), ph.method, ph.level);
printf("%-13s: methods : %s, %s\n", getName(), method_name, loader_method[i]);
+1 -1
View File
@@ -410,7 +410,7 @@ void PackBvmlinuzI386::pack(OutputFile *fo)
const unsigned lsize = getLoaderSize();
if (ph.method == M_LZMA) {
if (M_IS_LZMA(ph.method)) {
const lzma_compress_result_t *res = &ph.compress_result.result_lzma;
acc_uint32e_t properties = // lc, lp, pb, dummy
(res->lit_context_bits << 0) |
+11 -5
View File
@@ -163,7 +163,9 @@ bool Packer::testUnpackFormat(int format) const
bool ph_skipVerify(const PackHeader &ph)
{
if (ph.method == M_LZMA)
if (M_IS_DEFLATE(ph.method))
return false;
if (M_IS_LZMA(ph.method))
return false;
if (ph.level > 1)
return false;
@@ -1267,9 +1269,11 @@ void Packer::compressWithFilters(Filter *parm_ft,
int nmethods = 0;
for (int mm = 0; methods[mm] != M_END; ++mm)
{
if (methods[mm] == M_SKIP)
if (methods[mm] == M_ULTRA_BRUTE && !opt->ultra_brute)
break;
if (methods[mm] == M_SKIP || methods[mm] == M_ULTRA_BRUTE)
continue;
if (opt->all_methods && !opt->all_methods_use_lzma && methods[mm] == M_LZMA)
if (opt->all_methods && !opt->all_methods_use_lzma && M_IS_LZMA(methods[mm]))
continue;
assert(isValidCompressionMethod(methods[mm]));
nmethods++;
@@ -1290,9 +1294,11 @@ void Packer::compressWithFilters(Filter *parm_ft,
int nfilters_success = 0;
for (int mm = 0; methods[mm] != M_END; ++mm) // for all methods
{
if (methods[mm] == M_SKIP)
if (methods[mm] == M_ULTRA_BRUTE && !opt->ultra_brute)
break;
if (methods[mm] == M_SKIP || methods[mm] == M_ULTRA_BRUTE)
continue;
if (opt->all_methods && !opt->all_methods_use_lzma && methods[mm] == M_LZMA)
if (opt->all_methods && !opt->all_methods_use_lzma && M_IS_LZMA(methods[mm]))
continue;
unsigned hdr_c_len = 0;
if (hdr_buf && hdr_u_len)
+16 -12
View File
@@ -38,20 +38,24 @@
bool Packer::isValidCompressionMethod(int method)
{
#if 1 && !defined(WITH_LZMA)
if (method == M_LZMA) {
if (M_IS_LZMA(method)) {
#if !defined(WITH_LZMA)
assert(0 && "Internal error - LZMA not compiled in");
}
#else
return true;
#endif
}
return (method >= M_NRV2B_LE32 && method <= M_LZMA);
}
const int *Packer::getDefaultCompressionMethods_8(int method, int level, int small) const
{
static const int m_nrv2b[] = { M_NRV2B_8, M_NRV2D_8, M_NRV2E_8, M_LZMA, M_END };
static const int m_nrv2d[] = { M_NRV2D_8, M_NRV2B_8, M_NRV2E_8, M_LZMA, M_END };
static const int m_nrv2e[] = { M_NRV2E_8, M_NRV2B_8, M_NRV2D_8, M_LZMA, M_END };
#define M_LZMA_003 (M_LZMA | 0x00300)
#define M_LZMA_407 (M_LZMA | 0x40700)
static const int m_nrv2b[] = { M_NRV2B_8, M_NRV2D_8, M_NRV2E_8, M_LZMA, M_ULTRA_BRUTE, M_LZMA_003, M_LZMA_407, M_END };
static const int m_nrv2d[] = { M_NRV2D_8, M_NRV2B_8, M_NRV2E_8, M_LZMA, M_ULTRA_BRUTE, M_LZMA_003, M_LZMA_407, M_END };
static const int m_nrv2e[] = { M_NRV2E_8, M_NRV2B_8, M_NRV2D_8, M_LZMA, M_ULTRA_BRUTE, M_LZMA_003, M_LZMA_407, M_END };
static const int m_cl1b[] = { M_CL1B_8, M_END };
static const int m_lzma[] = { M_LZMA, M_END };
@@ -76,9 +80,9 @@ const int *Packer::getDefaultCompressionMethods_8(int method, int level, int sma
const int *Packer::getDefaultCompressionMethods_le32(int method, int level, int small) const
{
static const int m_nrv2b[] = { M_NRV2B_LE32, M_NRV2D_LE32, M_NRV2E_LE32, M_LZMA, M_END };
static const int m_nrv2d[] = { M_NRV2D_LE32, M_NRV2B_LE32, M_NRV2E_LE32, M_LZMA, M_END };
static const int m_nrv2e[] = { M_NRV2E_LE32, M_NRV2B_LE32, M_NRV2D_LE32, M_LZMA, M_END };
static const int m_nrv2b[] = { M_NRV2B_LE32, M_NRV2D_LE32, M_NRV2E_LE32, M_LZMA, M_ULTRA_BRUTE, M_LZMA_003, M_LZMA_407, M_END };
static const int m_nrv2d[] = { M_NRV2D_LE32, M_NRV2B_LE32, M_NRV2E_LE32, M_LZMA, M_ULTRA_BRUTE, M_LZMA_003, M_LZMA_407, M_END };
static const int m_nrv2e[] = { M_NRV2E_LE32, M_NRV2B_LE32, M_NRV2D_LE32, M_LZMA, M_ULTRA_BRUTE, M_LZMA_003, M_LZMA_407, M_END };
static const int m_cl1b[] = { M_CL1B_LE32, M_END };
static const int m_lzma[] = { M_LZMA, M_END };
@@ -206,7 +210,7 @@ const char *Packer::getDecompressorSections() const
return opt->small ? nrv2e_le32_small : nrv2e_le32_fast;
if (ph.method == M_CL1B_LE32)
return opt->small ? cl1b_le32_small : cl1b_le32_fast;
if (ph.method == M_LZMA) {
if (M_IS_LZMA(ph.method)) {
if (UPX_F_LINUX_ELF_i386 ==ph.format
|| UPX_F_LINUX_ELFI_i386 ==ph.format
|| UPX_F_LINUX_ELF64_AMD ==ph.format
@@ -225,7 +229,7 @@ const char *Packer::getDecompressorSections() const
unsigned Packer::getDecompressorWrkmemSize() const
{
unsigned size = 0;
if (ph.method == M_LZMA)
if (M_IS_LZMA(ph.method))
{
const lzma_compress_result_t *res = &ph.compress_result.result_lzma;
// FIXME - this is for i386 only
@@ -249,7 +253,7 @@ void Packer::defineDecompressorSymbols()
// ELF calls the decompressor many times; the parameters change!
return;
}
if (ph.method == M_LZMA)
if (M_IS_LZMA(ph.method))
{
const lzma_compress_result_t *res = &ph.compress_result.result_lzma;
// FIXME - this is for i386 only