mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
More lzma stuff.
This commit is contained in:
parent
54340ab4bf
commit
f1ba0c0aa7
|
@ -87,6 +87,7 @@ int upx_compress ( const upx_bytep src, upx_uint src_len,
|
||||||
result[5] = src_len; // max_run_found
|
result[5] = src_len; // max_run_found
|
||||||
result[6] = 1; // first_offset_found
|
result[6] = 1; // first_offset_found
|
||||||
//result[7] = 999999; // same_match_offsets_found - NOT USED
|
//result[7] = 999999; // same_match_offsets_found - NOT USED
|
||||||
|
result[8] = 0;
|
||||||
|
|
||||||
#if defined(WITH_LZMA)
|
#if defined(WITH_LZMA)
|
||||||
if (M_IS_LZMA(method))
|
if (M_IS_LZMA(method))
|
||||||
|
@ -147,6 +148,10 @@ int upx_test_overlap ( const upx_bytep buf, upx_uint src_off,
|
||||||
{
|
{
|
||||||
int r = UPX_E_ERROR;
|
int r = UPX_E_ERROR;
|
||||||
|
|
||||||
|
assert(src_len < *dst_len); // must be compressed
|
||||||
|
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
||||||
|
assert((int)overlap_overhead > 0);
|
||||||
|
|
||||||
#if defined(WITH_LZMA)
|
#if defined(WITH_LZMA)
|
||||||
if (M_IS_LZMA(method))
|
if (M_IS_LZMA(method))
|
||||||
return upx_lzma_test_overlap(buf, src_off, src_len, dst_len, method);
|
return upx_lzma_test_overlap(buf, src_off, src_len, dst_len, method);
|
||||||
|
|
|
@ -42,14 +42,14 @@ int compress_lzma_dummy = 0;
|
||||||
#undef OS2
|
#undef OS2
|
||||||
#undef _WIN32
|
#undef _WIN32
|
||||||
#undef _WIN32_WCE
|
#undef _WIN32_WCE
|
||||||
#include "lzma/MyInitGuid.h"
|
#undef COMPRESS_MF_MT
|
||||||
//#include "lzma/LZMADecoder.h"
|
#include "C/Common/MyInitGuid.h"
|
||||||
#include "lzma/LZMAEncoder.h"
|
#include "C/7zip/Compress/LZMA/LZMADecoder.h"
|
||||||
#undef RC_NORMALIZE
|
#include "C/7zip/Compress/LZMA/LZMAEncoder.h"
|
||||||
|
|
||||||
namespace MyLzma {
|
namespace MyLzma {
|
||||||
|
|
||||||
struct CInStreamRam: public ISequentialInStream, public CMyUnknownImp
|
struct InStreamRam: public ISequentialInStream, public CMyUnknownImp
|
||||||
{
|
{
|
||||||
MY_UNKNOWN_IMP
|
MY_UNKNOWN_IMP
|
||||||
const Byte *Data; size_t Size; size_t Pos;
|
const Byte *Data; size_t Size; size_t Pos;
|
||||||
|
@ -59,7 +59,7 @@ struct CInStreamRam: public ISequentialInStream, public CMyUnknownImp
|
||||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||||
};
|
};
|
||||||
|
|
||||||
STDMETHODIMP CInStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize)
|
STDMETHODIMP InStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||||
{
|
{
|
||||||
UInt32 remain = Size - Pos;
|
UInt32 remain = Size - Pos;
|
||||||
if (size > remain) size = remain;
|
if (size > remain) size = remain;
|
||||||
|
@ -69,7 +69,7 @@ STDMETHODIMP CInStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct COutStreamRam : public ISequentialOutStream, public CMyUnknownImp
|
struct OutStreamRam : public ISequentialOutStream, public CMyUnknownImp
|
||||||
{
|
{
|
||||||
MY_UNKNOWN_IMP
|
MY_UNKNOWN_IMP
|
||||||
Byte *Data; size_t Size; size_t Pos; bool Overflow;
|
Byte *Data; size_t Size; size_t Pos; bool Overflow;
|
||||||
|
@ -84,7 +84,7 @@ struct COutStreamRam : public ISequentialOutStream, public CMyUnknownImp
|
||||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||||
};
|
};
|
||||||
|
|
||||||
STDMETHODIMP COutStreamRam::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
STDMETHODIMP OutStreamRam::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
for (i = 0; i < size && Pos < Size; i++)
|
for (i = 0; i < size && Pos < Size; i++)
|
||||||
|
@ -94,6 +94,21 @@ STDMETHODIMP COutStreamRam::Write(const void *data, UInt32 size, UInt32 *process
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct ProgressInfo : public ICompressProgressInfo, public CMyUnknownImp
|
||||||
|
{
|
||||||
|
MY_UNKNOWN_IMP
|
||||||
|
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
|
||||||
|
upx_callback_p cb;
|
||||||
|
};
|
||||||
|
|
||||||
|
STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
|
||||||
|
{
|
||||||
|
if (cb && cb->nprogress)
|
||||||
|
cb->nprogress(cb, (upx_uint) *inSize, (upx_uint) *outSize, 3);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
@ -101,7 +116,7 @@ int upx_lzma_compress ( const upx_bytep src, upx_uint src_len,
|
||||||
upx_bytep dst, upx_uintp dst_len,
|
upx_bytep dst, upx_uintp dst_len,
|
||||||
upx_callback_p cb,
|
upx_callback_p cb,
|
||||||
int method, int level,
|
int method, int level,
|
||||||
const struct upx_compress_config_t *conf,
|
const struct upx_compress_config_t *conf_parm,
|
||||||
upx_uintp result )
|
upx_uintp result )
|
||||||
{
|
{
|
||||||
assert(method == M_LZMA);
|
assert(method == M_LZMA);
|
||||||
|
@ -111,41 +126,59 @@ int upx_lzma_compress ( const upx_bytep src, upx_uint src_len,
|
||||||
int r = UPX_E_ERROR;
|
int r = UPX_E_ERROR;
|
||||||
HRESULT rh;
|
HRESULT rh;
|
||||||
|
|
||||||
MyLzma::CInStreamRam* isp = new MyLzma::CInStreamRam;
|
MyLzma::InStreamRam is; is.AddRef();
|
||||||
MyLzma::CInStreamRam& is = *isp;
|
MyLzma::OutStreamRam os; os.AddRef();
|
||||||
MyLzma::COutStreamRam* osp = new MyLzma::COutStreamRam;
|
|
||||||
MyLzma::COutStreamRam& os = *osp;
|
|
||||||
is.Init(src, src_len);
|
is.Init(src, src_len);
|
||||||
// os.Init(dst, *dst_len);
|
// os.Init(dst, *dst_len);
|
||||||
os.Init(dst, src_len);
|
os.Init(dst, src_len);
|
||||||
|
|
||||||
|
MyLzma::ProgressInfo progress; progress.AddRef();
|
||||||
|
progress.cb = cb;
|
||||||
|
|
||||||
#ifndef _NO_EXCEPTIONS
|
#ifndef _NO_EXCEPTIONS
|
||||||
try {
|
try {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NCompress::NLZMA::CEncoder enc;
|
NCompress::NLZMA::CEncoder enc;
|
||||||
PROPID propIDs[3] = {
|
const PROPID propIDs[7] = {
|
||||||
NCoderPropID::kAlgorithm,
|
NCoderPropID::kPosStateBits, // 0 pb _posStateBits(2)
|
||||||
NCoderPropID::kDictionarySize,
|
NCoderPropID::kLitPosBits, // 1 lp _numLiteralPosStateBits(0)
|
||||||
NCoderPropID::kNumFastBytes
|
NCoderPropID::kLitContextBits, // 2 lc _numLiteralContextBits(3)
|
||||||
|
NCoderPropID::kDictionarySize, // 3
|
||||||
|
NCoderPropID::kAlgorithm, // 4 _fastmode
|
||||||
|
NCoderPropID::kNumFastBytes, // 5
|
||||||
|
NCoderPropID::kMatchFinderCycles // 6
|
||||||
};
|
};
|
||||||
PROPVARIANT properties[3];
|
PROPVARIANT pr[7];
|
||||||
properties[0].vt = VT_UI4;
|
pr[0].vt = pr[1].vt = pr[2].vt = VT_UI4;
|
||||||
properties[1].vt = VT_UI4;
|
pr[3].vt = pr[4].vt = pr[5].vt = VT_UI4;
|
||||||
properties[2].vt = VT_UI4;
|
pr[6].vt = VT_UI4;
|
||||||
properties[0].ulVal = (UInt32) 2;
|
|
||||||
// properties[1].ulVal = (UInt32) dictionarySize;
|
|
||||||
properties[1].ulVal = (UInt32) 1024 * 1024; // FIXME
|
|
||||||
properties[2].ulVal = (UInt32) 64;
|
|
||||||
|
|
||||||
if (enc.SetCoderProperties(propIDs, properties, 3) != S_OK)
|
// setup defaults
|
||||||
|
pr[0].uintVal = 2;
|
||||||
|
pr[1].uintVal = 0;
|
||||||
|
pr[2].uintVal = 3;
|
||||||
|
pr[3].uintVal = src_len;
|
||||||
|
pr[4].uintVal = 2;
|
||||||
|
pr[5].uintVal = 64;
|
||||||
|
pr[6].uintVal = 0;
|
||||||
|
|
||||||
|
// FIXME: tune these according to level
|
||||||
|
if (pr[3].uintVal > src_len)
|
||||||
|
pr[3].uintVal = src_len;
|
||||||
|
|
||||||
|
if (enc.SetCoderProperties(propIDs, pr, 3) != S_OK)
|
||||||
goto error;
|
goto error;
|
||||||
if (enc.WriteCoderProperties(&os) != S_OK)
|
if (enc.WriteCoderProperties(&os) != S_OK)
|
||||||
goto error;
|
goto error;
|
||||||
if (os.Pos != 5)
|
if (os.Overflow || os.Pos != 5)
|
||||||
goto error;
|
goto error;
|
||||||
|
#if 0 // defined(_LZMA_OUT_READ)
|
||||||
|
#else
|
||||||
|
os.Pos -= 4; // do not encode dict_size
|
||||||
|
#endif
|
||||||
|
|
||||||
rh = enc.Code(&is, &os, 0, 0, 0);
|
rh = enc.Code(&is, &os, NULL, NULL, &progress);
|
||||||
if (rh == E_OUTOFMEMORY)
|
if (rh == E_OUTOFMEMORY)
|
||||||
r = UPX_E_OUT_OF_MEMORY;
|
r = UPX_E_OUT_OF_MEMORY;
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -156,7 +189,8 @@ int upx_lzma_compress ( const upx_bytep src, upx_uint src_len,
|
||||||
r = UPX_E_OK;
|
r = UPX_E_OK;
|
||||||
|
|
||||||
//result[8] = LzmaGetNumProbs(&s.Properties));
|
//result[8] = LzmaGetNumProbs(&s.Properties));
|
||||||
result[8] = 0; // FIXME
|
//result[8] = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
|
||||||
|
result[8] = 1846 + (768 << (pr[2].uintVal + pr[1].uintVal));
|
||||||
|
|
||||||
error:
|
error:
|
||||||
*dst_len = os.Pos;
|
*dst_len = os.Pos;
|
||||||
|
@ -168,14 +202,17 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#include "lzma/Alloc.cpp"
|
#include "C/Common/Alloc.cpp"
|
||||||
#include "lzma/CRC.cpp"
|
#include "C/Common/CRC.cpp"
|
||||||
//#include "lzma/LZMADecoder.cpp"
|
//#include "C/7zip/Common/InBuffer.cpp"
|
||||||
#include "lzma/LZMAEncoder.cpp"
|
#include "C/7zip/Common/OutBuffer.cpp"
|
||||||
#include "lzma/LZInWindow.cpp"
|
#include "C/7zip/Common/StreamUtils.cpp"
|
||||||
#include "lzma/OutBuffer.cpp"
|
#include "C/7zip/Compress/LZ/LZInWindow.cpp"
|
||||||
#include "lzma/RangeCoderBit.cpp"
|
//#include "C/7zip/Compress/LZ/LZOutWindow.cpp"
|
||||||
#include "lzma/StreamUtils.cpp"
|
//#include "C/7zip/Compress/LZMA/LZMADecoder.cpp"
|
||||||
|
#include "C/7zip/Compress/LZMA/LZMAEncoder.cpp"
|
||||||
|
#include "C/7zip/Compress/RangeCoder/RangeCoderBit.cpp"
|
||||||
|
#undef RC_NORMALIZE
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
@ -186,7 +223,7 @@ error:
|
||||||
#undef _LZMA_OUT_READ
|
#undef _LZMA_OUT_READ
|
||||||
#undef _LZMA_PROB32
|
#undef _LZMA_PROB32
|
||||||
#undef _LZMA_LOC_OPT
|
#undef _LZMA_LOC_OPT
|
||||||
#include "lzma/LzmaDecode.cpp"
|
#include "C/7zip/Compress/LZMA_C/LzmaDecode.c"
|
||||||
|
|
||||||
int upx_lzma_decompress ( const upx_bytep src, upx_uint src_len,
|
int upx_lzma_decompress ( const upx_bytep src, upx_uint src_len,
|
||||||
upx_bytep dst, upx_uintp dst_len,
|
upx_bytep dst, upx_uintp dst_len,
|
||||||
|
@ -205,7 +242,11 @@ int upx_lzma_decompress ( const upx_bytep src, upx_uint src_len,
|
||||||
r = LzmaDecodeProperties(&s.Properties, src, src_len);
|
r = LzmaDecodeProperties(&s.Properties, src, src_len);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
#if 0 // defined(_LZMA_OUT_READ)
|
||||||
src += LZMA_PROPERTIES_SIZE; src_len -= LZMA_PROPERTIES_SIZE;
|
src += LZMA_PROPERTIES_SIZE; src_len -= LZMA_PROPERTIES_SIZE;
|
||||||
|
#else
|
||||||
|
src += 1; src_len -= 1;
|
||||||
|
#endif
|
||||||
s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties));
|
s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties));
|
||||||
if (!s.Probs)
|
if (!s.Probs)
|
||||||
r = UPX_E_OUT_OF_MEMORY;
|
r = UPX_E_OUT_OF_MEMORY;
|
||||||
|
@ -218,6 +259,28 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_lzma_test_overlap ( const upx_bytep buf, upx_uint src_off,
|
||||||
|
upx_uint src_len, upx_uintp dst_len,
|
||||||
|
int method )
|
||||||
|
{
|
||||||
|
assert(method == M_LZMA);
|
||||||
|
|
||||||
|
/* FIXME */
|
||||||
|
UNUSED(buf);
|
||||||
|
|
||||||
|
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
||||||
|
//printf("upx_lzma_test_overlap: %d\n", overlap_overhead);
|
||||||
|
if ((int)overlap_overhead >= 256)
|
||||||
|
return UPX_E_OK;
|
||||||
|
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* WITH_LZMA */
|
#endif /* WITH_LZMA */
|
||||||
/*
|
/*
|
||||||
vi:ts=4:et:nowrap
|
vi:ts=4:et:nowrap
|
||||||
|
|
18
src/conf.h
18
src/conf.h
|
@ -144,6 +144,9 @@
|
||||||
# undef __unix
|
# undef __unix
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 1 && !defined(WITH_LZMA)
|
||||||
|
# define WITH_LZMA 1
|
||||||
|
#endif
|
||||||
#if !defined(WITH_UCL)
|
#if !defined(WITH_UCL)
|
||||||
# define WITH_UCL 1
|
# define WITH_UCL 1
|
||||||
#endif
|
#endif
|
||||||
|
@ -181,7 +184,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct upx_callback_t;
|
struct upx_callback_t;
|
||||||
typedef struct upx_callback_t upx_callback_t;
|
|
||||||
#define upx_callback_p upx_callback_t *
|
#define upx_callback_p upx_callback_t *
|
||||||
typedef upx_voidp (__UPX_CDECL *upx_alloc_func_t)
|
typedef upx_voidp (__UPX_CDECL *upx_alloc_func_t)
|
||||||
(upx_callback_p self, upx_uint items, upx_uint size);
|
(upx_callback_p self, upx_uint items, upx_uint size);
|
||||||
|
@ -200,10 +202,20 @@ struct upx_callback_t
|
||||||
upx_uint user3;
|
upx_uint user3;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct lzma_compress_config_t
|
||||||
|
{
|
||||||
|
unsigned pos_bits;
|
||||||
|
unsigned lit_pos_bits;
|
||||||
|
unsigned lit_context_bits;
|
||||||
|
unsigned dict_size;
|
||||||
|
unsigned mf_passes;
|
||||||
|
};
|
||||||
|
|
||||||
#define upx_compress_config_p upx_compress_config_t *
|
#define upx_compress_config_p upx_compress_config_t *
|
||||||
struct upx_compress_config_t
|
struct upx_compress_config_t
|
||||||
{
|
{
|
||||||
ucl_compress_config_t conf_ucl;
|
lzma_compress_config_t conf_lzma;
|
||||||
|
ucl_compress_config_t conf_ucl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -441,6 +453,8 @@ inline void operator delete[](void *p)
|
||||||
|
|
||||||
|
|
||||||
// compression methods - DO NOT CHANGE
|
// compression methods - DO NOT CHANGE
|
||||||
|
#define M_SKIP (-2)
|
||||||
|
#define M_END (-1)
|
||||||
#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
|
||||||
|
|
|
@ -512,6 +512,7 @@ static int do_option(int optc, const char *arg)
|
||||||
e_method(M_NRV2E_LE32, opt->level);
|
e_method(M_NRV2E_LE32, opt->level);
|
||||||
break;
|
break;
|
||||||
case 721:
|
case 721:
|
||||||
|
opt->all_methods_use_lzma = true;
|
||||||
if (!set_method(M_LZMA, -1))
|
if (!set_method(M_LZMA, -1))
|
||||||
e_method(M_LZMA, opt->level);
|
e_method(M_LZMA, opt->level);
|
||||||
break;
|
break;
|
||||||
|
@ -532,6 +533,7 @@ static int do_option(int optc, const char *arg)
|
||||||
|
|
||||||
case 901: // --brute
|
case 901: // --brute
|
||||||
opt->all_methods = true;
|
opt->all_methods = true;
|
||||||
|
opt->all_methods_use_lzma = true;
|
||||||
opt->method = -1;
|
opt->method = -1;
|
||||||
opt->all_filters = true;
|
opt->all_filters = true;
|
||||||
opt->filter = -1;
|
opt->filter = -1;
|
||||||
|
|
|
@ -47,11 +47,12 @@ struct options_t {
|
||||||
|
|
||||||
// compression options
|
// compression options
|
||||||
int method;
|
int method;
|
||||||
int level; // compression level 1..10
|
int level; // compression level 1..10
|
||||||
int filter; // preferred filter from Packer::getFilters()
|
int filter; // preferred filter from Packer::getFilters()
|
||||||
bool all_methods; // try all available compression methods ?
|
bool all_methods; // try all available compression methods ?
|
||||||
bool all_filters; // try all available filters ?
|
bool all_methods_use_lzma;
|
||||||
bool no_filter; // force no filter
|
bool all_filters; // try all available filters ?
|
||||||
|
bool no_filter; // force no filter
|
||||||
|
|
||||||
// other options
|
// other options
|
||||||
int backup;
|
int backup;
|
||||||
|
|
|
@ -195,8 +195,8 @@ int const *
|
||||||
PackLinuxElf64amd::getCompressionMethods(int method, int level) const
|
PackLinuxElf64amd::getCompressionMethods(int method, int level) const
|
||||||
{
|
{
|
||||||
// No real dependency on LE32.
|
// No real dependency on LE32.
|
||||||
static const int m_nrv2b[] = { M_NRV2B_LE32, M_NRV2E_LE32, -1 };
|
static const int m_nrv2b[] = { M_NRV2B_LE32, M_NRV2E_LE32, M_LZMA, -1 };
|
||||||
static const int m_nrv2e[] = { M_NRV2E_LE32, M_NRV2B_LE32, -1 };
|
static const int m_nrv2e[] = { M_NRV2E_LE32, M_NRV2B_LE32, M_LZMA, -1 };
|
||||||
static const int m_lzma[] = { M_LZMA,-1 };
|
static const int m_lzma[] = { M_LZMA,-1 };
|
||||||
|
|
||||||
if (M_IS_NRV2B(method))
|
if (M_IS_NRV2B(method))
|
||||||
|
@ -1534,11 +1534,12 @@ void PackLinuxElf64::unpack(OutputFile *fo)
|
||||||
throwChecksumError();
|
throwChecksumError();
|
||||||
#undef MAX_ELF_HDR
|
#undef MAX_ELF_HDR
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
PackLinuxElf32x86::PackLinuxElf32x86(InputFile *f) : super(f)
|
PackLinuxElf32x86::PackLinuxElf32x86(InputFile *f) : super(f)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,6 +138,21 @@ bool Packer::testUnpackFormat(int format) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Packer::skipVerify(int method, int level) const
|
||||||
|
{
|
||||||
|
if (method == M_LZMA)
|
||||||
|
return false;
|
||||||
|
if (level > 1)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Packer::skipVerify() const
|
||||||
|
{
|
||||||
|
return skipVerify(ph.method, ph.level);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// compress
|
// compress
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
@ -228,7 +243,7 @@ bool Packer::compress(upx_bytep in, upx_bytep out,
|
||||||
// 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(out, 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.level > 1)
|
if (!skipVerify())
|
||||||
{
|
{
|
||||||
// decompress
|
// decompress
|
||||||
unsigned new_len = ph.u_len;
|
unsigned new_len = ph.u_len;
|
||||||
|
@ -332,12 +347,16 @@ bool Packer::testOverlappingDecompression(const upx_bytep buf,
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
assert((int)overlap_overhead >= 0);
|
assert((int)overlap_overhead >= 0);
|
||||||
|
|
||||||
// Because upx_test_overlap() does not use the asm_fast decompressor
|
// Because upx_test_overlap() does not use the asm_fast decompressor
|
||||||
// we must account for extra 3 bytes that asm_fast does use,
|
// we must account for extra 3 bytes that asm_fast does use,
|
||||||
// or else we may fail at runtime decompression.
|
// or else we may fail at runtime decompression.
|
||||||
if (overlap_overhead <= 4 + 3) // don't waste time here
|
unsigned extra = 0;
|
||||||
|
if (M_IS_NRV2B(ph.method) || M_IS_NRV2D(ph.method) || M_IS_NRV2E(ph.method))
|
||||||
|
extra = 3;
|
||||||
|
if (overlap_overhead <= 4 + extra) // don't waste time here
|
||||||
return false;
|
return false;
|
||||||
overlap_overhead -= 3;
|
overlap_overhead -= extra;
|
||||||
|
|
||||||
unsigned src_off = ph.u_len + overlap_overhead - ph.c_len;
|
unsigned src_off = ph.u_len + overlap_overhead - ph.c_len;
|
||||||
unsigned new_len = ph.u_len;
|
unsigned new_len = ph.u_len;
|
||||||
|
@ -366,7 +385,7 @@ void Packer::verifyOverlappingDecompression(Filter *ft)
|
||||||
// See also:
|
// See also:
|
||||||
// Filter::verifyUnfilter()
|
// Filter::verifyUnfilter()
|
||||||
|
|
||||||
if (ph.level == 1)
|
if (skipVerify())
|
||||||
return;
|
return;
|
||||||
unsigned offset = (ph.u_len + ph.overlap_overhead) - ph.c_len;
|
unsigned offset = (ph.u_len + ph.overlap_overhead) - ph.c_len;
|
||||||
if (offset + ph.c_len > obuf.getSize())
|
if (offset + ph.c_len > obuf.getSize())
|
||||||
|
@ -407,7 +426,9 @@ unsigned Packer::findOverlapOverhead(const upx_bytep buf,
|
||||||
assert(m >= low); assert(m <= high);
|
assert(m >= low); assert(m <= high);
|
||||||
assert(m < overhead || overhead == 0);
|
assert(m < overhead || overhead == 0);
|
||||||
nr++;
|
nr++;
|
||||||
if (testOverlappingDecompression(buf, m))
|
bool success = testOverlappingDecompression(buf, m);
|
||||||
|
//printf("testOverlapOverhead: %d %d -> %d\n", nr, m, (int)success);
|
||||||
|
if (success)
|
||||||
{
|
{
|
||||||
overhead = m;
|
overhead = m;
|
||||||
// Succeed early if m lies in [low .. low+range-1], i.e. if
|
// Succeed early if m lies in [low .. low+range-1], i.e. if
|
||||||
|
@ -920,17 +941,22 @@ unsigned Packer::unoptimizeReloc32(upx_byte **in, upx_byte *image,
|
||||||
|
|
||||||
bool Packer::isValidCompressionMethod(int method)
|
bool Packer::isValidCompressionMethod(int method)
|
||||||
{
|
{
|
||||||
|
#if !defined(WITH_LZMA)
|
||||||
|
if (method == M_LZMA) {
|
||||||
|
assert(0 && "Internal error - LZMA not compiled in");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return (method >= M_NRV2B_LE32 && method <= M_LZMA);
|
return (method >= M_NRV2B_LE32 && method <= M_LZMA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const int *Packer::getDefaultCompressionMethods_8(int method, int level, int small) const
|
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, -1 };
|
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, -1 };
|
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, -1 };
|
static const int m_nrv2e[] = { M_NRV2E_8, M_NRV2B_8, M_NRV2D_8, M_LZMA, M_END };
|
||||||
static const int m_cl1b[] = { M_CL1B_8, -1 };
|
static const int m_cl1b[] = { M_CL1B_8, M_END };
|
||||||
static const int m_lzma[] = { M_LZMA, -1 };
|
static const int m_lzma[] = { M_LZMA, M_END };
|
||||||
|
|
||||||
if (small < 0)
|
if (small < 0)
|
||||||
small = file_size <= 512*1024;
|
small = file_size <= 512*1024;
|
||||||
|
@ -944,6 +970,7 @@ const int *Packer::getDefaultCompressionMethods_8(int method, int level, int sma
|
||||||
return m_cl1b;
|
return m_cl1b;
|
||||||
if (M_IS_LZMA(method))
|
if (M_IS_LZMA(method))
|
||||||
return m_lzma;
|
return m_lzma;
|
||||||
|
assert(method == -1); // --all-methods
|
||||||
if (level == 1 || small)
|
if (level == 1 || small)
|
||||||
return m_nrv2b;
|
return m_nrv2b;
|
||||||
return m_nrv2e;
|
return m_nrv2e;
|
||||||
|
@ -952,11 +979,11 @@ const int *Packer::getDefaultCompressionMethods_8(int method, int level, int sma
|
||||||
|
|
||||||
const int *Packer::getDefaultCompressionMethods_le32(int method, int level, int small) const
|
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, -1 };
|
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, -1 };
|
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, -1 };
|
static const int m_nrv2e[] = { M_NRV2E_LE32, M_NRV2B_LE32, M_NRV2D_LE32, M_LZMA, M_END };
|
||||||
static const int m_cl1b[] = { M_CL1B_LE32, -1 };
|
static const int m_cl1b[] = { M_CL1B_LE32, M_END };
|
||||||
static const int m_lzma[] = { M_LZMA, -1 };
|
static const int m_lzma[] = { M_LZMA, M_END };
|
||||||
|
|
||||||
if (small < 0)
|
if (small < 0)
|
||||||
small = file_size <= 512*1024;
|
small = file_size <= 512*1024;
|
||||||
|
@ -970,6 +997,7 @@ const int *Packer::getDefaultCompressionMethods_le32(int method, int level, int
|
||||||
return m_cl1b;
|
return m_cl1b;
|
||||||
if (M_IS_LZMA(method))
|
if (M_IS_LZMA(method))
|
||||||
return m_lzma;
|
return m_lzma;
|
||||||
|
assert(method == -1); // --all-methods
|
||||||
if (level == 1 || small)
|
if (level == 1 || small)
|
||||||
return m_nrv2b;
|
return m_nrv2b;
|
||||||
return m_nrv2e;
|
return m_nrv2e;
|
||||||
|
@ -1363,16 +1391,20 @@ void Packer::compressWithFilters(Filter *parm_ft,
|
||||||
filters[nfilters] = -1;
|
filters[nfilters] = -1;
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
int tmp_methods[] = { ph.method, -1 };
|
int tmp_methods[] = { ph.method, M_END };
|
||||||
const int *methods = NULL;
|
const int *methods = NULL;
|
||||||
if (opt->all_methods)
|
if (opt->all_methods)
|
||||||
methods = getCompressionMethods(-1, ph.level);
|
methods = getCompressionMethods(-1, ph.level);
|
||||||
if (methods == NULL)
|
if (methods == NULL)
|
||||||
methods = tmp_methods;
|
methods = tmp_methods;
|
||||||
int nmethods = 0;
|
int nmethods = 0;
|
||||||
while (methods[nmethods] >= 0)
|
for (int mm = 0; methods[mm] != M_END; ++mm)
|
||||||
{
|
{
|
||||||
assert(isValidCompressionMethod(methods[nmethods]));
|
if (methods[mm] == M_SKIP)
|
||||||
|
continue;
|
||||||
|
if (opt->all_methods && !opt->all_methods_use_lzma && methods[mm] == M_LZMA)
|
||||||
|
continue;
|
||||||
|
assert(isValidCompressionMethod(methods[mm]));
|
||||||
nmethods++;
|
nmethods++;
|
||||||
}
|
}
|
||||||
assert(nmethods > 0);
|
assert(nmethods > 0);
|
||||||
|
@ -1389,17 +1421,23 @@ void Packer::compressWithFilters(Filter *parm_ft,
|
||||||
|
|
||||||
// compress
|
// compress
|
||||||
int nfilters_success = 0;
|
int nfilters_success = 0;
|
||||||
for (int m = 0; m < nmethods; m++) // for all methods
|
for (int mm = 0; methods[mm] != M_END; ++mm) // for all methods
|
||||||
{
|
{
|
||||||
|
if (methods[mm] == M_SKIP)
|
||||||
|
continue;
|
||||||
|
if (opt->all_methods && !opt->all_methods_use_lzma && methods[mm] == M_LZMA)
|
||||||
|
continue;
|
||||||
unsigned hdr_c_len = 0;
|
unsigned hdr_c_len = 0;
|
||||||
if (hdr_buf && hdr_u_len)
|
if (hdr_buf && hdr_u_len)
|
||||||
{
|
{
|
||||||
if (0 < m && otemp == &obuf) { // do not overwrite obuf
|
if (nfilters_success != 0 && otemp == &obuf)
|
||||||
|
{
|
||||||
|
// do not overwrite obuf
|
||||||
otemp_buf.allocForCompression(compress_buf_len);
|
otemp_buf.allocForCompression(compress_buf_len);
|
||||||
otemp = &otemp_buf;
|
otemp = &otemp_buf;
|
||||||
}
|
}
|
||||||
int r = upx_compress(hdr_buf, hdr_u_len, *otemp, &hdr_c_len,
|
int r = upx_compress(hdr_buf, hdr_u_len, *otemp, &hdr_c_len,
|
||||||
NULL, methods[m], 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_u_len)
|
||||||
|
@ -1411,7 +1449,7 @@ void Packer::compressWithFilters(Filter *parm_ft,
|
||||||
obuf.checkState();
|
obuf.checkState();
|
||||||
// get fresh packheader
|
// get fresh packheader
|
||||||
ph = orig_ph;
|
ph = orig_ph;
|
||||||
ph.method = methods[m];
|
ph.method = methods[mm];
|
||||||
ph.filter = filters[i];
|
ph.filter = filters[i];
|
||||||
ph.overlap_overhead = 0;
|
ph.overlap_overhead = 0;
|
||||||
// get fresh filter
|
// get fresh filter
|
||||||
|
@ -1442,7 +1480,7 @@ 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 > 0 && otemp == &obuf)
|
if (nfilters_success != 0 && otemp == &obuf)
|
||||||
{
|
{
|
||||||
otemp_buf.allocForCompression(compress_buf_len);
|
otemp_buf.allocForCompression(compress_buf_len);
|
||||||
otemp = &otemp_buf;
|
otemp = &otemp_buf;
|
||||||
|
|
|
@ -137,6 +137,9 @@ protected:
|
||||||
// unpacker tests - these may throw exceptions
|
// unpacker tests - these may throw exceptions
|
||||||
virtual bool testUnpackVersion(int version) const;
|
virtual bool testUnpackVersion(int version) const;
|
||||||
virtual bool testUnpackFormat(int format) const;
|
virtual bool testUnpackFormat(int format) const;
|
||||||
|
//
|
||||||
|
virtual bool skipVerify(int method, int level) const;
|
||||||
|
virtual bool skipVerify() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// implementation
|
// implementation
|
||||||
|
|
Loading…
Reference in New Issue
Block a user