mirror of
https://github.com/upx/upx.git
synced 2025-08-11 22:52:30 +08:00
Decompress pre-compressed stubs in Linker::init().
This commit is contained in:
@ -106,7 +106,7 @@ int upx_compress ( const upx_bytep src, unsigned src_len,
|
||||
cresult->c_len = 0;
|
||||
#endif
|
||||
|
||||
if (method < 0) {
|
||||
if (0) {
|
||||
}
|
||||
#if defined(WITH_LZMA)
|
||||
else if (M_IS_LZMA(method))
|
||||
@ -152,7 +152,7 @@ int upx_decompress ( const upx_bytep src, unsigned src_len,
|
||||
if (cresult && cresult->method == 0)
|
||||
cresult = NULL;
|
||||
|
||||
if (method < 0) {
|
||||
if (0) {
|
||||
}
|
||||
#if defined(WITH_LZMA)
|
||||
else if (M_IS_LZMA(method))
|
||||
@ -165,6 +165,10 @@ int upx_decompress ( const upx_bytep src, unsigned src_len,
|
||||
#if defined(WITH_UCL)
|
||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||
r = upx_ucl_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||
#endif
|
||||
#if defined(WITH_ZLIB)
|
||||
else if (M_IS_DEFLATE(method))
|
||||
r = upx_zlib_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||
#endif
|
||||
else {
|
||||
throwInternalError("unknown decompression method");
|
||||
@ -193,7 +197,7 @@ int upx_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
||||
assert((int)overlap_overhead > 0);
|
||||
|
||||
if (method < 0) {
|
||||
if (0) {
|
||||
}
|
||||
#if defined(WITH_LZMA)
|
||||
else if (M_IS_LZMA(method))
|
||||
|
@ -130,18 +130,52 @@ ElfLinker::~ElfLinker()
|
||||
free(relocations);
|
||||
}
|
||||
|
||||
void ElfLinker::init(const void *pdata, int plen)
|
||||
void ElfLinker::init(const void *pdata_v, int plen)
|
||||
{
|
||||
upx_byte *i = new upx_byte[plen + 1];
|
||||
memcpy(i, pdata, plen);
|
||||
input = i;
|
||||
inputlen = plen;
|
||||
input[plen] = 0;
|
||||
const upx_byte *pdata = (const upx_byte *) pdata_v;
|
||||
// decompress
|
||||
if (plen >= 16 && memcmp(pdata, "UPX#", 4) == 0)
|
||||
{
|
||||
int method = -1;
|
||||
unsigned u_len, c_len;
|
||||
if (pdata[4] == M_DEFLATE)
|
||||
{
|
||||
method = M_DEFLATE;
|
||||
u_len = get_le16(pdata + 5);
|
||||
c_len = get_le16(pdata + 7);
|
||||
pdata += 9;
|
||||
assert(9 + c_len == (unsigned) plen);
|
||||
}
|
||||
else if (pdata[4] == 0 && pdata[5] == M_DEFLATE)
|
||||
{
|
||||
method = M_DEFLATE;
|
||||
u_len = get_le32(pdata + 6);
|
||||
c_len = get_le32(pdata + 10);
|
||||
pdata += 14;
|
||||
assert(14 + c_len == (unsigned) plen);
|
||||
}
|
||||
else
|
||||
throwBadLoader();
|
||||
assert((unsigned) plen < u_len);
|
||||
inputlen = u_len;
|
||||
input = new upx_byte[inputlen + 1];
|
||||
unsigned new_len = u_len;
|
||||
int r = upx_decompress(pdata, c_len, input, &new_len, method, NULL);
|
||||
if (r != 0 || new_len != u_len)
|
||||
throwBadLoader();
|
||||
}
|
||||
else
|
||||
{
|
||||
inputlen = plen;
|
||||
input = new upx_byte[inputlen + 1];
|
||||
memcpy(input, pdata, inputlen);
|
||||
}
|
||||
input[inputlen] = 0; // NUL terminate
|
||||
|
||||
output = new upx_byte[plen];
|
||||
output = new upx_byte[inputlen];
|
||||
outputlen = 0;
|
||||
|
||||
int pos = find(input, plen, "Sections:", 9);
|
||||
int pos = find(input, inputlen, "Sections:", 9);
|
||||
assert(pos != -1);
|
||||
char *psections = (char *) input + pos;
|
||||
|
||||
|
Reference in New Issue
Block a user