Skip to content

Commit

Permalink
Replaced lzmawrt with lzma_adaptive
Browse files Browse the repository at this point in the history
  • Loading branch information
devttys0 committed Aug 16, 2014
1 parent 4818dae commit 36edc69
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 5 deletions.
30 changes: 30 additions & 0 deletions LZMA/lzmalib/C/7zip/Compress/LZMA_Lib/ZLib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,3 +380,33 @@ extern "C" int lzma7z_uncompress OF((Bytef *dest, uLongf *destLen,

return Z_OK;
}

// CJH: A decompressor used for brute forcing commonly modified LZMA fields
extern "C" int lzmaspec_uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int lc, int lp, int pb, int offset))
{
CInMemoryStream *inStreamSpec = new CInMemoryStream(source+offset, sourceLen-offset);
CMyComPtr<ISequentialInStream> inStream = inStreamSpec;

COutMemoryStream *outStreamSpec = new COutMemoryStream(dest, *destLen);
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;

NCompress::NLZMA::CDecoder *decoderSpec =
new NCompress::NLZMA::CDecoder;
CMyComPtr<ICompressCoder> decoder = decoderSpec;

if (decoderSpec->SetDecoderPropertiesRaw(lc,
lp, pb, (1 << 23)) != S_OK) return Z_DATA_ERROR;

UInt64 fileSize = *destLen;

if (decoder->Code(inStream, outStream, 0, &fileSize, 0) != S_OK)
{
return Z_DATA_ERROR;
}

outStreamSpec->Seek(0, STREAM_SEEK_END, &fileSize);
*destLen = fileSize;

return Z_OK;
}

1 change: 1 addition & 0 deletions LZMA/lzmalib/C/7zip/Compress/LZMA_Lib/lzmalib.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ int lzmalib_uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uL
int lzmawrt_uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen));
int lzma7z_uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen));
int lzmalinksys_uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen));
int lzmaspec_uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int lc, int lp, int pb, int offset));

#endif
87 changes: 82 additions & 5 deletions lzma_wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@
#define LZMA_LIB 4
#define LZMA_LIB_7Z 5
#define LZMA_LIB_LINKSYS 6
#define LZMA_LIB_WRT 7 // CJH: This should always be tried last, it seems very buggy (segfaults, infinite loops)
#define LZMA_VARIANTS_COUNT LZMA_LIB_WRT
#define LZMA_LIB_ADAPTIVE 7
//#define LZMA_LIB_WRT 8 // CJH: This should always be tried last, it seems very buggy (segfaults, infinite loops)
#define LZMA_VARIANTS_COUNT 7

static int lzma_compress(void *strm, void *dest, void *src, int size, int block_size,
int *error)
Expand Down Expand Up @@ -275,6 +276,77 @@ int lzma_lib_linksys_uncompress(void *dest, void *src, int size, int outsize, in
return retval;
}

// CJH: An adaptive LZMA decompressor
struct lzma_props
{
int lc;
int lp;
int pb;
int offset;
};
struct lzma_props properties = { .lc=4, .lp=4, .pb=4, .offset=0 };
static int lzma_adaptive_uncompress(void *dest, void *src, int size, int outsize, int *error)
{
int lc, lp, pb, i;
int offsets[4] = {0, 4, 5, 9};
int retval = -1, expected_outsize = 0;

expected_outsize = outsize;

retval = lzmaspec_uncompress((Bytef *) dest,
(uLongf *) &outsize,
(const Bytef *) src,
(uLong) size,
properties.lc,
properties.lp,
properties.pb,
properties.offset);

if(retval == 0)
{
return outsize;
}

for(lc=0; lc<=4; lc++)
{
for(lp=0; lp<=4; lp++)
{
for(pb=0; pb<=4; pb++)
{
for(i=0; i<4; i++)
{
outsize = expected_outsize;
retval = lzmaspec_uncompress((Bytef *) dest,
(uLongf *) &outsize,
(const Bytef *) src,
(uLong) size,
lc,
lp,
pb,
offsets[i]);

if(retval == 0)
{
properties.lc = lc;
properties.lp = lp;
properties.pb = pb;
properties.offset = offsets[i];

TRACE("Detected LZMA settings [lc: %d, lp: %d, pb: %d, offset: %d]\n", properties.lc,
properties.lp,
properties.pb,
properties.offset);
return outsize;
}
}
}
}
}

*error = retval;
return -1;
}

// CJH: A decompression wrapper for the various LZMA versions
int detected_lzma_variant = -1;
static int lzma_uncompress(void *dest, void *src, int size, int outsize, int *error)
Expand All @@ -288,7 +360,7 @@ static int lzma_uncompress(void *dest, void *src, int size, int outsize, int *er
i++;
}

for(k=LZMA_STANDARD; i<LZMA_VARIANTS_COUNT; i++,k++)
for(k=1; i<LZMA_VARIANTS_COUNT; i++,k++)
{
if(k == detected_lzma_variant)
{
Expand All @@ -312,17 +384,22 @@ static int lzma_uncompress(void *dest, void *src, int size, int outsize, int *er
case LZMA_SQLZMA:
retval = sqlzma_uncompress(dest, src, size, outsize, error);
break;
/*
case LZMA_LIB_WRT:
retval = lzma_wrt_uncompress(dest, src, size, outsize, error);
break;
*/
case LZMA_LIB:
retval = lzma_lib_uncompress(dest, src, size, outsize, error);
break;
case LZMA_LIB_LINKSYS:
retval = lzma_lib_linksys_uncompress(dest, src, size, outsize, error);
break;
case LZMA_LIB_7Z:
retval = lzma_lib_7z_uncompress(dest, src, size, outsize, error);
break;
case LZMA_LIB_LINKSYS:
retval = lzma_lib_linksys_uncompress(dest, src, size, outsize, error);
case LZMA_LIB_ADAPTIVE:
retval = lzma_adaptive_uncompress(dest, src, size, outsize, error);
break;
}

Expand Down

0 comments on commit 36edc69

Please sign in to comment.