Add Dispack file-level filter in the libarchive chain.
Add new file type for Win32-PE executables (Dispack). Reset file type flag after filter processing for better compression. Fix array index handling for file type list.
This commit is contained in:
parent
9a5361f010
commit
1db822d866
11 changed files with 456 additions and 15 deletions
|
@ -156,7 +156,7 @@ PPNMOBJS = $(PPNMSRCS:.cpp=.o)
|
||||||
WAVPKSRCS = archive/wavpack_helper.c
|
WAVPKSRCS = archive/wavpack_helper.c
|
||||||
WAVPKOBJS = $(WAVPKSRCS:.c=.o)
|
WAVPKOBJS = $(WAVPKSRCS:.c=.o)
|
||||||
|
|
||||||
DISPACKSRCS = filters/dispack/dis.cpp
|
DISPACKSRCS = filters/dispack/dis.cpp archive/dispack_helper.cpp
|
||||||
DISPACKHDRS = filters/dispack/dis.hpp filters/dispack/types.hpp
|
DISPACKHDRS = filters/dispack/dis.hpp filters/dispack/types.hpp
|
||||||
DISPACKOBJS = $(DISPACKSRCS:.cpp=.o)
|
DISPACKOBJS = $(DISPACKSRCS:.cpp=.o)
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ BASE_CPPFLAGS = -I. -I./lzma -I./lzfx -I./lz4 -I./rabin -I./bsdiff -DNODEFAULT_P
|
||||||
-I./crypto/scrypt -I./crypto/aes -I./crypto @KEYLEN@ -I./rabin/global \
|
-I./crypto/scrypt -I./crypto/aes -I./crypto @KEYLEN@ -I./rabin/global \
|
||||||
-I./crypto/keccak -I./filters/transpose -I./crypto/blake2 $(EXTRA_CPPFLAGS) \
|
-I./crypto/keccak -I./filters/transpose -I./crypto/blake2 $(EXTRA_CPPFLAGS) \
|
||||||
-I./crypto/xsalsa20 -I./archive -pedantic -Wall -I./filters -fno-strict-aliasing \
|
-I./crypto/xsalsa20 -I./archive -pedantic -Wall -I./filters -fno-strict-aliasing \
|
||||||
-Wno-unused-but-set-variable -Wno-enum-compare -I./filters/analyzer \
|
-Wno-unused-but-set-variable -Wno-enum-compare -I./filters/analyzer -I./filters/dispack \
|
||||||
@COMPAT_CPPFLAGS@ @XSALSA20_DEBUG@ -I@LIBARCHIVE_DIR@/libarchive -I./filters/packjpg \
|
@COMPAT_CPPFLAGS@ @XSALSA20_DEBUG@ -I@LIBARCHIVE_DIR@/libarchive -I./filters/packjpg \
|
||||||
-I./filters/packpnm @ENABLE_WAVPACK@
|
-I./filters/packpnm @ENABLE_WAVPACK@
|
||||||
COMMON_CPPFLAGS = $(BASE_CPPFLAGS) -std=gnu99
|
COMMON_CPPFLAGS = $(BASE_CPPFLAGS) -std=gnu99
|
||||||
|
|
151
archive/dispack_helper.cpp
Normal file
151
archive/dispack_helper.cpp
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of Pcompress, a chunked parallel multi-
|
||||||
|
* algorithm lossless compression and decompression program.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014 Moinak Ghosh. All rights reserved.
|
||||||
|
* Use is subject to license terms.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this program.
|
||||||
|
* If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* moinakg@belenix.org, http://moinakg.wordpress.com/
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
#include "winsupport.h"
|
||||||
|
#include "types.hpp"
|
||||||
|
#include "dis.hpp"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef unsigned char uchar_t;
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
struct FileHeader
|
||||||
|
{
|
||||||
|
sU32 SizeBefore; // number of bytes before start of code section
|
||||||
|
sU32 SizeAfter; // number of bytes after code section
|
||||||
|
sU32 SizeTransformed; // size of transformed code section
|
||||||
|
sU32 SizeOriginal; // size of untransformed code section
|
||||||
|
sU32 Origin; // virtual address of first byte
|
||||||
|
};
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
size_t
|
||||||
|
dispack_filter_encode(uchar_t *inData, size_t len, uchar_t **out_buf)
|
||||||
|
{
|
||||||
|
uchar_t *pos;
|
||||||
|
FileHeader hdr;
|
||||||
|
|
||||||
|
*out_buf = (uchar_t *)malloc(len);
|
||||||
|
if (*out_buf == NULL)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
// assume the input file is a PE executable.
|
||||||
|
IMAGE_DOS_HEADER *doshdr = (IMAGE_DOS_HEADER *) inData;
|
||||||
|
IMAGE_NT_HEADERS *nthdr = (IMAGE_NT_HEADERS *) (inData + doshdr->e_lfanew);
|
||||||
|
|
||||||
|
if (nthdr->FileHeader.Machine != IMAGE_FILE_MACHINE_I386 ||
|
||||||
|
nthdr->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
||||||
|
// Only 32-bit PE files for x86 supported
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
sU32 imageBase = nthdr->OptionalHeader.ImageBase;
|
||||||
|
sU32 codeStart = nthdr->OptionalHeader.BaseOfCode;
|
||||||
|
sU32 codeSize = nthdr->OptionalHeader.SizeOfCode;
|
||||||
|
sU32 fileOffs = 0; // find file offset of first section
|
||||||
|
|
||||||
|
// find section containing code
|
||||||
|
IMAGE_SECTION_HEADER *sec = IMAGE_FIRST_SECTION(nthdr);
|
||||||
|
for (sInt i=0;i<nthdr->FileHeader.NumberOfSections;i++) {
|
||||||
|
if (codeStart >= sec[i].VirtualAddress && codeStart <
|
||||||
|
sec[i].VirtualAddress + sec[i].SizeOfRawData)
|
||||||
|
fileOffs = sec[i].PointerToRawData + (codeStart - sec[i].VirtualAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileOffs == 0) {
|
||||||
|
// Code section not found!
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep space for header
|
||||||
|
pos = *out_buf + sizeof (hdr);
|
||||||
|
|
||||||
|
// transform code
|
||||||
|
sU32 transSize = len - sizeof (hdr);
|
||||||
|
if (DisFilter(inData + fileOffs, codeSize, imageBase + codeStart, pos, transSize) == NULL)
|
||||||
|
return (0);
|
||||||
|
pos += transSize;
|
||||||
|
|
||||||
|
// Now plonk the header
|
||||||
|
hdr.SizeBefore = fileOffs;
|
||||||
|
hdr.SizeAfter = len - (fileOffs + codeSize);
|
||||||
|
hdr.SizeTransformed = transSize;
|
||||||
|
hdr.SizeOriginal = codeSize;
|
||||||
|
hdr.Origin = imageBase + codeStart;
|
||||||
|
memcpy(*out_buf, &hdr, sizeof (hdr));
|
||||||
|
|
||||||
|
// Copy rest of the data
|
||||||
|
memcpy(pos, inData, hdr.SizeBefore);
|
||||||
|
pos += hdr.SizeBefore;
|
||||||
|
memcpy(pos, inData + (fileOffs + codeSize), hdr.SizeAfter);
|
||||||
|
pos += hdr.SizeAfter;
|
||||||
|
|
||||||
|
return (pos - *out_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
dispack_filter_decode(uchar_t *inData, size_t len, uchar_t **out_buf)
|
||||||
|
{
|
||||||
|
uchar_t *decoded;
|
||||||
|
FileHeader *hdr = (FileHeader *)inData;
|
||||||
|
|
||||||
|
sU8 *transformed = inData + sizeof (FileHeader);
|
||||||
|
sU8 *before = transformed + hdr->SizeTransformed;
|
||||||
|
sU8 *after = before + hdr->SizeBefore;
|
||||||
|
|
||||||
|
// alloc buffer for unfiltered code
|
||||||
|
*out_buf = (uchar_t *)malloc(len);
|
||||||
|
if (*out_buf == NULL)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
decoded = *out_buf;
|
||||||
|
memcpy(decoded, before, hdr->SizeBefore);
|
||||||
|
decoded += hdr->SizeBefore;
|
||||||
|
|
||||||
|
if (!DisUnFilter(transformed, hdr->SizeTransformed, decoded,
|
||||||
|
hdr->SizeOriginal, hdr->Origin)) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
decoded += hdr->SizeOriginal;
|
||||||
|
memcpy(decoded, after, hdr->SizeAfter);
|
||||||
|
decoded += hdr->SizeAfter;
|
||||||
|
|
||||||
|
return (decoded - *out_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -61,6 +61,10 @@ extern size_t wavpack_filter_decode(uchar_t *in_buf, size_t len, uchar_t **out_b
|
||||||
ssize_t wavpack_filter(struct filter_info *fi, void *filter_private);
|
ssize_t wavpack_filter(struct filter_info *fi, void *filter_private);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
size_t dispack_filter_encode(uchar_t *inData, size_t len, uchar_t **out_buf);
|
||||||
|
size_t dispack_filter_decode(uchar_t *inData, size_t len, uchar_t **out_buf);
|
||||||
|
ssize_t dispack_filter(struct filter_info *fi, void *filter_private);
|
||||||
|
|
||||||
void
|
void
|
||||||
add_filters_by_type(struct type_data *typetab, struct filter_flags *ff)
|
add_filters_by_type(struct type_data *typetab, struct filter_flags *ff)
|
||||||
{
|
{
|
||||||
|
@ -90,6 +94,18 @@ add_filters_by_type(struct type_data *typetab, struct filter_flags *ff)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (ff->exe_preprocess) {
|
||||||
|
if (!sdat) {
|
||||||
|
sdat = (struct scratch_buffer *)malloc(sizeof (struct scratch_buffer));
|
||||||
|
sdat->in_buff = NULL;
|
||||||
|
sdat->in_bufflen = 0;
|
||||||
|
}
|
||||||
|
slot = TYPE_EXE32_PE >> 3;
|
||||||
|
typetab[slot].filter_private = sdat;
|
||||||
|
typetab[slot].filter_func = dispack_filter;
|
||||||
|
typetab[slot].filter_name = "Dispack";
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _ENABLE_WAVPACK_
|
#ifdef _ENABLE_WAVPACK_
|
||||||
if (ff->enable_wavpack) {
|
if (ff->enable_wavpack) {
|
||||||
if (!sdat) {
|
if (!sdat) {
|
||||||
|
@ -111,7 +127,7 @@ type_tag_from_filter_name(struct type_data *typetab, const char *fname, size_t l
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < NUM_SUB_TYPES; i++)
|
for (i = 0; i <= NUM_SUB_TYPES; i++)
|
||||||
{
|
{
|
||||||
if (typetab[i].filter_name &&
|
if (typetab[i].filter_name &&
|
||||||
strncmp(fname, typetab[i].filter_name, len) == 0)
|
strncmp(fname, typetab[i].filter_name, len) == 0)
|
||||||
|
@ -507,3 +523,103 @@ wavpack_filter(struct filter_info *fi, void *filter_private)
|
||||||
}
|
}
|
||||||
#endif /* _ENABLE_WAVPACK_ */
|
#endif /* _ENABLE_WAVPACK_ */
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
dispack_filter(struct filter_info *fi, void *filter_private)
|
||||||
|
{
|
||||||
|
struct scratch_buffer *sdat = (struct scratch_buffer *)filter_private;
|
||||||
|
uchar_t *mapbuf, *out;
|
||||||
|
uint64_t len, in_size = 0, len1;
|
||||||
|
|
||||||
|
len = archive_entry_size(fi->entry);
|
||||||
|
len1 = len;
|
||||||
|
if (len > WVPK_FILE_SIZE_LIMIT) // Bork on massive files
|
||||||
|
return (FILTER_RETURN_SKIP);
|
||||||
|
|
||||||
|
if (fi->compressing) {
|
||||||
|
mapbuf = mmap(NULL, len, PROT_READ, MAP_SHARED, fi->fd, 0);
|
||||||
|
if (mapbuf == NULL) {
|
||||||
|
log_msg(LOG_ERR, 1, "Mmap failed in Dispack filter.");
|
||||||
|
return (FILTER_RETURN_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No check for supported 32-bit exe here. EXE types are always
|
||||||
|
* detected by file header analysis. So no need to duplicate here.
|
||||||
|
*/
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Allocate input buffer and read archive data stream for the entry
|
||||||
|
* into this buffer.
|
||||||
|
*/
|
||||||
|
ensure_buffer(sdat, len);
|
||||||
|
if (sdat->in_buff == NULL) {
|
||||||
|
log_msg(LOG_ERR, 1, "Out of memory.");
|
||||||
|
return (FILTER_RETURN_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
in_size = copy_archive_data(fi->source_arc, sdat->in_buff);
|
||||||
|
if (in_size != len) {
|
||||||
|
log_msg(LOG_ERR, 0, "Failed to read archive data.");
|
||||||
|
return (FILTER_RETURN_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First 8 bytes in the data is the compressed size of the entry.
|
||||||
|
* LibArchive always zero-pads entries to their original size so
|
||||||
|
* we need to separately store the compressed size.
|
||||||
|
*/
|
||||||
|
in_size = LE64(U64_P(sdat->in_buff));
|
||||||
|
mapbuf = sdat->in_buff + 8;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No check for supported EXE types needed here since supported
|
||||||
|
* and filtered files are tagged in the archive using xattrs during
|
||||||
|
* compression.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compression case.
|
||||||
|
*/
|
||||||
|
if (fi->compressing) {
|
||||||
|
out = NULL;
|
||||||
|
len = dispack_filter_encode(mapbuf, len, &out);
|
||||||
|
if (len == 0 || len >= (len1 - 8)) {
|
||||||
|
munmap(mapbuf, len1);
|
||||||
|
free(out);
|
||||||
|
return (FILTER_RETURN_SKIP);
|
||||||
|
}
|
||||||
|
munmap(mapbuf, len1);
|
||||||
|
|
||||||
|
fi->fout->output_type = FILTER_OUTPUT_MEM;
|
||||||
|
fi->fout->out = out;
|
||||||
|
fi->fout->out_size = len;
|
||||||
|
fi->fout->hdr.in_size = LE64(len1);
|
||||||
|
return (ARCHIVE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decompression case.
|
||||||
|
*/
|
||||||
|
out = NULL;
|
||||||
|
if ((len = dispack_filter_decode(mapbuf, in_size, &out)) == 0) {
|
||||||
|
/*
|
||||||
|
* If filter failed we indicate a soft error to continue the
|
||||||
|
* archive extraction.
|
||||||
|
*/
|
||||||
|
free(out);
|
||||||
|
out = malloc(len);
|
||||||
|
memcpy(out, sdat->in_buff, len);
|
||||||
|
|
||||||
|
fi->fout->output_type = FILTER_OUTPUT_MEM;
|
||||||
|
fi->fout->out = out;
|
||||||
|
fi->fout->out_size = len;
|
||||||
|
return (FILTER_RETURN_SOFT_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
fi->fout->output_type = FILTER_OUTPUT_MEM;
|
||||||
|
fi->fout->out = out;
|
||||||
|
fi->fout->out_size = len;
|
||||||
|
return (ARCHIVE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,7 @@ struct filter_info {
|
||||||
struct filter_flags {
|
struct filter_flags {
|
||||||
int enable_packjpg;
|
int enable_packjpg;
|
||||||
int enable_wavpack;
|
int enable_wavpack;
|
||||||
|
int exe_preprocess;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef ssize_t (*filter_func_ptr)(struct filter_info *fi, void *filter_private);
|
typedef ssize_t (*filter_func_ptr)(struct filter_info *fi, void *filter_private);
|
||||||
|
|
|
@ -63,7 +63,7 @@ static struct ext_hash_entry {
|
||||||
int type;
|
int type;
|
||||||
} *exthtab = NULL;
|
} *exthtab = NULL;
|
||||||
|
|
||||||
static struct type_data typetab[NUM_SUB_TYPES];
|
static struct type_data typetab[NUM_SUB_TYPES+1];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
AE_IFREG Regular file
|
AE_IFREG Regular file
|
||||||
|
@ -1100,6 +1100,7 @@ copy_file_data(pc_ctx_t *pctx, struct archive *arc, struct archive_entry *entry,
|
||||||
&fout, 1, pctx->level);
|
&fout, 1, pctx->level);
|
||||||
if (rv != FILTER_RETURN_SKIP &&
|
if (rv != FILTER_RETURN_SKIP &&
|
||||||
rv != FILTER_RETURN_ERROR) {
|
rv != FILTER_RETURN_ERROR) {
|
||||||
|
pctx->ctype = TYPE_UNKNOWN; // Force analyzer on filter output
|
||||||
if (fout.output_type == FILTER_OUTPUT_MEM) {
|
if (fout.output_type == FILTER_OUTPUT_MEM) {
|
||||||
archive_entry_xattr_add_entry(entry, FILTER_XATTR_ENTRY,
|
archive_entry_xattr_add_entry(entry, FILTER_XATTR_ENTRY,
|
||||||
fname, strlen(fname));
|
fname, strlen(fname));
|
||||||
|
@ -1176,6 +1177,7 @@ do_map:
|
||||||
&fout, 1, pctx->level);
|
&fout, 1, pctx->level);
|
||||||
if (rv != FILTER_RETURN_SKIP &&
|
if (rv != FILTER_RETURN_SKIP &&
|
||||||
rv != FILTER_RETURN_ERROR) {
|
rv != FILTER_RETURN_ERROR) {
|
||||||
|
pctx->ctype = TYPE_UNKNOWN; // Force analyzer on filter output
|
||||||
if (fout.output_type == FILTER_OUTPUT_MEM) {
|
if (fout.output_type == FILTER_OUTPUT_MEM) {
|
||||||
archive_entry_xattr_add_entry(entry,
|
archive_entry_xattr_add_entry(entry,
|
||||||
FILTER_XATTR_ENTRY,
|
FILTER_XATTR_ENTRY,
|
||||||
|
@ -1997,7 +1999,7 @@ detect_type_by_data(uchar_t *buf, size_t len)
|
||||||
if (id == 0x8664)
|
if (id == 0x8664)
|
||||||
return (TYPE_BINARY|TYPE_EXE64);
|
return (TYPE_BINARY|TYPE_EXE64);
|
||||||
else
|
else
|
||||||
return (TYPE_BINARY|TYPE_EXE32);
|
return (TYPE_BINARY|TYPE_EXE32_PE);
|
||||||
} else {
|
} else {
|
||||||
return (TYPE_BINARY);
|
return (TYPE_BINARY);
|
||||||
}
|
}
|
||||||
|
|
|
@ -637,10 +637,10 @@ struct DisFilterCtx
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
static sU8 *
|
sU8 *
|
||||||
DisFilter(DisFilterCtx &ctx, sU8 *src, sU32 size, sU32 origin, sU8 *dst, sU32 &outputSize)
|
DisFilter(sU8 *src, sU32 size, sU32 origin, sU8 *dst, sU32 &outputSize)
|
||||||
{
|
{
|
||||||
// DisFilterCtx ctx(origin,origin+size);
|
DisFilterCtx ctx(origin,origin+size);
|
||||||
|
|
||||||
// main loop: handle everything but the last few bytes
|
// main loop: handle everything but the last few bytes
|
||||||
sU32 pos = 0;
|
sU32 pos = 0;
|
||||||
|
@ -707,7 +707,7 @@ static inline sU32 Copy32(sU8 *&d,sU8 *&s) { sU32 v = Fetch32B(s); Write32(d,
|
||||||
#define Copy16Chk(strm) do { CheckSrcDst(strm,2); Copy16(dest,stream[strm]); } while(0)
|
#define Copy16Chk(strm) do { CheckSrcDst(strm,2); Copy16(dest,stream[strm]); } while(0)
|
||||||
#define Copy32Chk(strm) do { CheckSrcDst(strm,4); Copy32(dest,stream[strm]); } while(0)
|
#define Copy32Chk(strm) do { CheckSrcDst(strm,4); Copy32(dest,stream[strm]); } while(0)
|
||||||
|
|
||||||
static sBool
|
sBool
|
||||||
DisUnFilter(sU8 *source,sU32 sourceSize,sU8 *dest,sU32 destSize,sU32 memStart)
|
DisUnFilter(sU8 *source,sU32 sourceSize,sU8 *dest,sU32 destSize,sU32 memStart)
|
||||||
{
|
{
|
||||||
sU8 *stream[ST_MAX];
|
sU8 *stream[ST_MAX];
|
||||||
|
@ -902,6 +902,10 @@ DisUnFilter(sU8 *source,sU32 sourceSize,sU8 *dest,sU32 destSize,sU32 memStart)
|
||||||
return sTRUE;
|
return sTRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: function unused. Retained for future need.
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
/*
|
/*
|
||||||
* Try to estimate if the given data block contains 32-bit x86 instructions
|
* Try to estimate if the given data block contains 32-bit x86 instructions
|
||||||
* especially of the call and jmp variety.
|
* especially of the call and jmp variety.
|
||||||
|
@ -926,6 +930,7 @@ is_x86_code(uchar_t *buf, int len)
|
||||||
avgFreq = ln>>8;
|
avgFreq = ln>>8;
|
||||||
return (freq[0x8b] > avgFreq && freq[0x00] > avgFreq * 2 && freq[0xE8] > 6);
|
return (freq[0x8b] > avgFreq && freq[0x00] > avgFreq * 2 && freq[0xE8] > 6);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -1007,6 +1012,10 @@ Inverse_E89(uint8_t *src, uint64_t sz)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: function unused. Retained for future need.
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
/*
|
/*
|
||||||
* 32-bit x86 executable packer top-level routines. Detected x86 executable data
|
* 32-bit x86 executable packer top-level routines. Detected x86 executable data
|
||||||
* are passed through these encoding routines. The data chunk is split into 32KB
|
* are passed through these encoding routines. The data chunk is split into 32KB
|
||||||
|
@ -1106,7 +1115,12 @@ dispack_encode(uchar_t *from, uint64_t fromlen, uchar_t *to, uint64_t *dstlen)
|
||||||
#endif
|
#endif
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function retained for ability to decode older archives encoded using raw block
|
||||||
|
* dispack.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
dispack_decode(uchar_t *from, uint64_t fromlen, uchar_t *to, uint64_t *dstlen)
|
dispack_decode(uchar_t *from, uint64_t fromlen, uchar_t *to, uint64_t *dstlen)
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,12 +26,12 @@
|
||||||
#define __DIS_HPP__
|
#define __DIS_HPP__
|
||||||
|
|
||||||
#include <utils.h>
|
#include <utils.h>
|
||||||
|
#include "types.hpp"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int dispack_encode(uchar_t *from, uint64_t fromlen, uchar_t *to, uint64_t *_dstlen);
|
|
||||||
int dispack_decode(uchar_t *from, uint64_t fromlen, uchar_t *to, uint64_t *dstlen);
|
int dispack_decode(uchar_t *from, uint64_t fromlen, uchar_t *to, uint64_t *dstlen);
|
||||||
|
|
||||||
int Forward_E89(uint8_t *src, uint64_t sz);
|
int Forward_E89(uint8_t *src, uint64_t sz);
|
||||||
|
@ -41,4 +41,9 @@ int Inverse_E89(uint8_t *src, uint64_t sz);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
sU8 *DisFilter(sU8 *src, sU32 size, sU32 origin, sU8 *dst, sU32 &outputSize);
|
||||||
|
sBool DisUnFilter(sU8 *source,sU32 sourceSize,sU8 *dest,sU32 destSize,sU32 memStart);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -39,12 +39,14 @@ typedef uint64_t sU64;
|
||||||
typedef int64_t sS64;
|
typedef int64_t sS64;
|
||||||
typedef int sInt;
|
typedef int sInt;
|
||||||
typedef char sChar;
|
typedef char sChar;
|
||||||
typedef bool sBool;
|
|
||||||
typedef float sF32;
|
typedef float sF32;
|
||||||
typedef double sF64;
|
typedef double sF64;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
typedef bool sBool;
|
||||||
#define sTRUE true
|
#define sTRUE true
|
||||||
#define sFALSE false
|
#define sFALSE false
|
||||||
|
#endif
|
||||||
|
|
||||||
#define _byteswap_ushort htons
|
#define _byteswap_ushort htons
|
||||||
#define _byteswap_ulong htonl
|
#define _byteswap_ulong htonl
|
||||||
|
|
10
pcompress.c
10
pcompress.c
|
@ -223,7 +223,6 @@ preproc_compress(pc_ctx_t *pctx, compress_func_ptr cmp_func, void *src, uint64_t
|
||||||
stype = PC_SUBTYPE(btype);
|
stype = PC_SUBTYPE(btype);
|
||||||
dict = 0;
|
dict = 0;
|
||||||
analyzed = 0;
|
analyzed = 0;
|
||||||
|
|
||||||
if (btype == TYPE_UNKNOWN || stype == TYPE_ARCHIVE_TAR || stype == TYPE_PDF || interesting) {
|
if (btype == TYPE_UNKNOWN || stype == TYPE_ARCHIVE_TAR || stype == TYPE_PDF || interesting) {
|
||||||
analyze_buffer(src, srclen, &actx);
|
analyze_buffer(src, srclen, &actx);
|
||||||
analyzed = 1;
|
analyzed = 1;
|
||||||
|
@ -3140,6 +3139,7 @@ init_pc_context(pc_ctx_t *pctx, int argc, char *argv[])
|
||||||
pctx->advanced_opts = 0;
|
pctx->advanced_opts = 0;
|
||||||
ff.enable_packjpg = 0;
|
ff.enable_packjpg = 0;
|
||||||
ff.enable_wavpack = 0;
|
ff.enable_wavpack = 0;
|
||||||
|
ff.exe_preprocess = 0;
|
||||||
|
|
||||||
pthread_mutex_lock(&opt_parse);
|
pthread_mutex_lock(&opt_parse);
|
||||||
while ((opt = getopt(argc, argv, "dc:s:l:pt:MCDGEe:w:LPS:B:Fk:avmKjxiTn")) != -1) {
|
while ((opt = getopt(argc, argv, "dc:s:l:pt:MCDGEe:w:LPS:B:Fk:avmKjxiTn")) != -1) {
|
||||||
|
@ -3315,6 +3315,7 @@ init_pc_context(pc_ctx_t *pctx, int argc, char *argv[])
|
||||||
case 'x':
|
case 'x':
|
||||||
pctx->advanced_opts = 1;
|
pctx->advanced_opts = 1;
|
||||||
pctx->exe_preprocess = 1;
|
pctx->exe_preprocess = 1;
|
||||||
|
ff.exe_preprocess = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'T':
|
case 'T':
|
||||||
|
@ -3625,10 +3626,13 @@ init_pc_context(pc_ctx_t *pctx, int argc, char *argv[])
|
||||||
ff.enable_packjpg = 1;
|
ff.enable_packjpg = 1;
|
||||||
ff.enable_wavpack = 1;
|
ff.enable_wavpack = 1;
|
||||||
}
|
}
|
||||||
|
if (pctx->level > 8) {
|
||||||
|
pctx->exe_preprocess = 1;
|
||||||
|
ff.exe_preprocess = 1;
|
||||||
|
}
|
||||||
init_filters(&ff);
|
init_filters(&ff);
|
||||||
pctx->enable_packjpg = ff.enable_packjpg;
|
pctx->enable_packjpg = ff.enable_packjpg;
|
||||||
pctx->enable_wavpack = ff.enable_wavpack;
|
pctx->enable_wavpack = ff.enable_wavpack;
|
||||||
if (pctx->level > 8) pctx->exe_preprocess = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3658,8 +3662,10 @@ init_pc_context(pc_ctx_t *pctx, int argc, char *argv[])
|
||||||
*/
|
*/
|
||||||
ff.enable_packjpg = 1;
|
ff.enable_packjpg = 1;
|
||||||
ff.enable_wavpack = 1;
|
ff.enable_wavpack = 1;
|
||||||
|
ff.exe_preprocess = 1;
|
||||||
pctx->enable_packjpg = 1;
|
pctx->enable_packjpg = 1;
|
||||||
pctx->enable_wavpack = 1;
|
pctx->enable_wavpack = 1;
|
||||||
|
pctx->exe_preprocess = 1;
|
||||||
init_filters(&ff);
|
init_filters(&ff);
|
||||||
}
|
}
|
||||||
pctx->inited = 1;
|
pctx->inited = 1;
|
||||||
|
|
|
@ -278,7 +278,7 @@ typedef enum {
|
||||||
/*
|
/*
|
||||||
* Sub-types.
|
* Sub-types.
|
||||||
*/
|
*/
|
||||||
#define NUM_SUB_TYPES 34
|
#define NUM_SUB_TYPES 35
|
||||||
TYPE_EXE32 = 8,
|
TYPE_EXE32 = 8,
|
||||||
TYPE_JPEG = 16,
|
TYPE_JPEG = 16,
|
||||||
TYPE_MARKUP = 24,
|
TYPE_MARKUP = 24,
|
||||||
|
@ -312,7 +312,8 @@ typedef enum {
|
||||||
TYPE_PACKPNM = 248,
|
TYPE_PACKPNM = 248,
|
||||||
TYPE_WAV = 256,
|
TYPE_WAV = 256,
|
||||||
TYPE_ENGLISH = 264,
|
TYPE_ENGLISH = 264,
|
||||||
TYPE_MEDIA_BSC = 272
|
TYPE_MEDIA_BSC = 272,
|
||||||
|
TYPE_EXE32_PE = 280
|
||||||
} data_type_t;
|
} data_type_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
143
utils/winsupport.h
Normal file
143
utils/winsupport.h
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
/*
|
||||||
|
* This file is a part of Pcompress, a chunked parallel multi-
|
||||||
|
* algorithm lossless compression and decompression program.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014 Moinak Ghosh. All rights reserved.
|
||||||
|
* Use is subject to license terms.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this program.
|
||||||
|
* If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* moinakg@belenix.org, http://moinakg.wordpress.com/
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __WINSUPPORT_H__
|
||||||
|
#define __WINSUPPORT_H__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Windows data types.
|
||||||
|
*/
|
||||||
|
typedef unsigned char BYTE;
|
||||||
|
typedef unsigned short WORD;
|
||||||
|
typedef unsigned int DWORD;
|
||||||
|
typedef long LONG;
|
||||||
|
typedef int INT;
|
||||||
|
|
||||||
|
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
|
||||||
|
#define IMAGE_SIZEOF_SHORT_NAME 8
|
||||||
|
#define IMAGE_FILE_MACHINE_I386 0x014c
|
||||||
|
#define IMAGE_FILE_MACHINE_AMD64 0x8664
|
||||||
|
#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
|
||||||
|
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
|
||||||
|
|
||||||
|
typedef struct _IMAGE_DOS_HEADER
|
||||||
|
{
|
||||||
|
WORD e_magic;
|
||||||
|
WORD e_cblp;
|
||||||
|
WORD e_cp;
|
||||||
|
WORD e_crlc;
|
||||||
|
WORD e_cparhdr;
|
||||||
|
WORD e_minalloc;
|
||||||
|
WORD e_maxalloc;
|
||||||
|
WORD e_ss;
|
||||||
|
WORD e_sp;
|
||||||
|
WORD e_csum;
|
||||||
|
WORD e_ip;
|
||||||
|
WORD e_cs;
|
||||||
|
WORD e_lfarlc;
|
||||||
|
WORD e_ovno;
|
||||||
|
WORD e_res[4];
|
||||||
|
WORD e_oemid;
|
||||||
|
WORD e_oeminfo;
|
||||||
|
WORD e_res2[10];
|
||||||
|
INT e_lfanew;
|
||||||
|
} IMAGE_DOS_HEADER;
|
||||||
|
|
||||||
|
typedef struct _IMAGE_DATA_DIRECTORY {
|
||||||
|
DWORD VirtualAddress;
|
||||||
|
DWORD Size;
|
||||||
|
} IMAGE_DATA_DIRECTORY;
|
||||||
|
|
||||||
|
typedef struct _IMAGE_SECTION_HEADER {
|
||||||
|
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
|
||||||
|
union {
|
||||||
|
DWORD PhysicalAddress;
|
||||||
|
DWORD VirtualSize;
|
||||||
|
} Misc;
|
||||||
|
DWORD VirtualAddress;
|
||||||
|
DWORD SizeOfRawData;
|
||||||
|
DWORD PointerToRawData;
|
||||||
|
DWORD PointerToRelocations;
|
||||||
|
DWORD PointerToLinenumbers;
|
||||||
|
WORD NumberOfRelocations;
|
||||||
|
WORD NumberOfLinenumbers;
|
||||||
|
DWORD Characteristics;
|
||||||
|
} IMAGE_SECTION_HEADER;
|
||||||
|
|
||||||
|
typedef struct _IMAGE_FILE_HEADER {
|
||||||
|
WORD Machine;
|
||||||
|
WORD NumberOfSections;
|
||||||
|
DWORD TimeDateStamp;
|
||||||
|
DWORD PointerToSymbolTable;
|
||||||
|
DWORD NumberOfSymbols;
|
||||||
|
WORD SizeOfOptionalHeader;
|
||||||
|
WORD Characteristics;
|
||||||
|
} IMAGE_FILE_HEADER;
|
||||||
|
|
||||||
|
typedef struct _IMAGE_OPTIONAL_HEADER {
|
||||||
|
WORD Magic;
|
||||||
|
BYTE MajorLinkerVersion;
|
||||||
|
BYTE MinorLinkerVersion;
|
||||||
|
DWORD SizeOfCode;
|
||||||
|
DWORD SizeOfInitializedData;
|
||||||
|
DWORD SizeOfUninitializedData;
|
||||||
|
DWORD AddressOfEntryPoint;
|
||||||
|
DWORD BaseOfCode;
|
||||||
|
DWORD BaseOfData;
|
||||||
|
DWORD ImageBase;
|
||||||
|
DWORD SectionAlignment;
|
||||||
|
DWORD FileAlignment;
|
||||||
|
WORD MajorOperatingSystemVersion;
|
||||||
|
WORD MinorOperatingSystemVersion;
|
||||||
|
WORD MajorImageVersion;
|
||||||
|
WORD MinorImageVersion;
|
||||||
|
WORD MajorSubsystemVersion;
|
||||||
|
WORD MinorSubsystemVersion;
|
||||||
|
DWORD Win32VersionValue;
|
||||||
|
DWORD SizeOfImage;
|
||||||
|
DWORD SizeOfHeaders;
|
||||||
|
DWORD CheckSum;
|
||||||
|
WORD Subsystem;
|
||||||
|
WORD DllCharacteristics;
|
||||||
|
DWORD SizeOfStackReserve;
|
||||||
|
DWORD SizeOfStackCommit;
|
||||||
|
DWORD SizeOfHeapReserve;
|
||||||
|
DWORD SizeOfHeapCommit;
|
||||||
|
DWORD LoaderFlags;
|
||||||
|
DWORD NumberOfRvaAndSizes;
|
||||||
|
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
|
||||||
|
} IMAGE_OPTIONAL_HEADER;
|
||||||
|
|
||||||
|
typedef struct _IMAGE_NT_HEADERS {
|
||||||
|
DWORD Signature;
|
||||||
|
IMAGE_FILE_HEADER FileHeader;
|
||||||
|
IMAGE_OPTIONAL_HEADER OptionalHeader;
|
||||||
|
} IMAGE_NT_HEADERS;
|
||||||
|
|
||||||
|
#define IMAGE_FIRST_SECTION(ntheader) \
|
||||||
|
((IMAGE_SECTION_HEADER *)((unsigned char *)&((IMAGE_NT_HEADERS *)(ntheader))->OptionalHeader + \
|
||||||
|
((IMAGE_NT_HEADERS *)(ntheader))->FileHeader.SizeOfOptionalHeader))
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue