src: add a xspan check to p_tmt.cpp and clang-format
This commit is contained in:
+1
-1
@@ -79,7 +79,7 @@ CLANG_FORMAT_FILES += except.cpp except.h
|
|||||||
CLANG_FORMAT_FILES += file.cpp file.h
|
CLANG_FORMAT_FILES += file.cpp file.h
|
||||||
CLANG_FORMAT_FILES += linker.cpp linker.h packhead.cpp packmast.cpp packmast.h
|
CLANG_FORMAT_FILES += linker.cpp linker.h packhead.cpp packmast.cpp packmast.h
|
||||||
CLANG_FORMAT_FILES += main.cpp options.cpp options.h packer.cpp packer.h
|
CLANG_FORMAT_FILES += main.cpp options.cpp options.h packer.cpp packer.h
|
||||||
CLANG_FORMAT_FILES += p_tos.cpp p_tos.h
|
CLANG_FORMAT_FILES += p_tmt.cpp p_tmt.h p_tos.cpp p_tos.h
|
||||||
CLANG_FORMAT_FILES += s_djgpp2.cpp s_object.cpp s_vcsa.cpp s_win32.cpp screen.h
|
CLANG_FORMAT_FILES += s_djgpp2.cpp s_object.cpp s_vcsa.cpp s_win32.cpp screen.h
|
||||||
CLANG_FORMAT_FILES += ui.cpp ui.h work.cpp
|
CLANG_FORMAT_FILES += ui.cpp ui.h work.cpp
|
||||||
CLANG_FORMAT_FILES += $(wildcard util/[a-ln-z]*.[ch]* util/mem*.[ch]*)
|
CLANG_FORMAT_FILES += $(wildcard util/[a-ln-z]*.[ch]* util/mem*.[ch]*)
|
||||||
|
|||||||
+96
-147
@@ -25,7 +25,6 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
@@ -33,136 +32,100 @@
|
|||||||
#include "p_tmt.h"
|
#include "p_tmt.h"
|
||||||
#include "linker.h"
|
#include "linker.h"
|
||||||
|
|
||||||
static const
|
static const CLANG_FORMAT_DUMMY_STATEMENT
|
||||||
#include "stub/i386-dos32.tmt.h"
|
#include "stub/i386-dos32.tmt.h"
|
||||||
|
|
||||||
#define EXTRA_INFO 4 // original entry point
|
#define EXTRA_INFO 4 // original entry point
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
PackTmt::PackTmt(InputFile *f) : super(f)
|
PackTmt::PackTmt(InputFile *f) : super(f) {
|
||||||
{
|
|
||||||
bele = &N_BELE_RTP::le_policy;
|
bele = &N_BELE_RTP::le_policy;
|
||||||
COMPILE_TIME_ASSERT(sizeof(tmt_header_t) == 44)
|
COMPILE_TIME_ASSERT(sizeof(tmt_header_t) == 44)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int *PackTmt::getCompressionMethods(int method, int level) const {
|
||||||
const int *PackTmt::getCompressionMethods(int method, int level) const
|
|
||||||
{
|
|
||||||
return Packer::getDefaultCompressionMethods_le32(method, level);
|
return Packer::getDefaultCompressionMethods_le32(method, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int *PackTmt::getFilters() const {
|
||||||
const int *PackTmt::getFilters() const
|
static const int filters[] = {0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14,
|
||||||
{
|
0x11, FT_ULTRA_BRUTE, 0x25, 0x15, 0x12, FT_END};
|
||||||
static const int filters[] = {
|
|
||||||
0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14, 0x11,
|
|
||||||
FT_ULTRA_BRUTE, 0x25, 0x15, 0x12,
|
|
||||||
FT_END };
|
|
||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned PackTmt::findOverlapOverhead(const upx_bytep buf, const upx_bytep tbuf, unsigned range,
|
||||||
unsigned PackTmt::findOverlapOverhead(const upx_bytep buf,
|
unsigned upper_limit) const {
|
||||||
const upx_bytep tbuf,
|
|
||||||
unsigned range,
|
|
||||||
unsigned upper_limit) const
|
|
||||||
{
|
|
||||||
// make sure the decompressor will be paragraph aligned
|
// make sure the decompressor will be paragraph aligned
|
||||||
unsigned o = super::findOverlapOverhead(buf, tbuf, range, upper_limit);
|
unsigned o = super::findOverlapOverhead(buf, tbuf, range, upper_limit);
|
||||||
o = ((o + 0x20) &~ 0xf) - (ph.u_len & 0xf);
|
o = ((o + 0x20) & ~0xf) - (ph.u_len & 0xf);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Linker *PackTmt::newLinker() const { return new ElfLinkerX86; }
|
||||||
|
|
||||||
Linker* PackTmt::newLinker() const
|
void PackTmt::buildLoader(const Filter *ft) {
|
||||||
{
|
|
||||||
return new ElfLinkerX86;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PackTmt::buildLoader(const Filter *ft)
|
|
||||||
{
|
|
||||||
// prepare loader
|
// prepare loader
|
||||||
initLoader(stub_i386_dos32_tmt, sizeof(stub_i386_dos32_tmt));
|
initLoader(stub_i386_dos32_tmt, sizeof(stub_i386_dos32_tmt));
|
||||||
addLoader("IDENTSTR,TMTMAIN1",
|
addLoader("IDENTSTR,TMTMAIN1", ph.first_offset_found == 1 ? "TMTMAIN1A" : "", "TMTMAIN1B",
|
||||||
ph.first_offset_found == 1 ? "TMTMAIN1A" : "",
|
ft->id ? "TMTCALT1" : "", "TMTMAIN2,UPX1HEAD,TMTCUTPO", nullptr);
|
||||||
"TMTMAIN1B",
|
|
||||||
ft->id ? "TMTCALT1" : "",
|
|
||||||
"TMTMAIN2,UPX1HEAD,TMTCUTPO",
|
|
||||||
nullptr);
|
|
||||||
|
|
||||||
// fake alignment for the start of the decompressor
|
// fake alignment for the start of the decompressor
|
||||||
linker->defineSymbol("TMTCUTPO", 0x1000);
|
linker->defineSymbol("TMTCUTPO", 0x1000);
|
||||||
|
|
||||||
addLoader(getDecompressorSections(), "TMTMAIN5", nullptr);
|
addLoader(getDecompressorSections(), "TMTMAIN5", nullptr);
|
||||||
if (ft->id)
|
if (ft->id) {
|
||||||
{
|
|
||||||
assert(ft->calls > 0);
|
assert(ft->calls > 0);
|
||||||
addLoader("TMTCALT2",nullptr);
|
addLoader("TMTCALT2", nullptr);
|
||||||
addFilter32(ft->id);
|
addFilter32(ft->id);
|
||||||
}
|
}
|
||||||
addLoader("TMTRELOC,RELOC320",
|
addLoader("TMTRELOC,RELOC320", big_relocs ? "REL32BIG" : "", "RELOC32J,TMTJUMP1", nullptr);
|
||||||
big_relocs ? "REL32BIG" : "",
|
|
||||||
"RELOC32J,TMTJUMP1",
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int PackTmt::readFileHeader()
|
int PackTmt::readFileHeader() {
|
||||||
{
|
#define H(x) get_le16(h + 2 * (x))
|
||||||
#define H(x) get_le16(h+2*(x))
|
#define H4(x) get_le32(h + (x))
|
||||||
#define H4(x) get_le32(h+(x))
|
|
||||||
unsigned char h[0x40];
|
unsigned char h[0x40];
|
||||||
int ic;
|
int ic;
|
||||||
unsigned exe_offset = 0;
|
unsigned exe_offset = 0;
|
||||||
adam_offset = 0;
|
adam_offset = 0;
|
||||||
|
|
||||||
for (ic = 0; ic < 20; ic++)
|
for (ic = 0; ic < 20; ic++) {
|
||||||
{
|
fi->seek(adam_offset, SEEK_SET);
|
||||||
fi->seek(adam_offset,SEEK_SET);
|
fi->readx(h, sizeof(h));
|
||||||
fi->readx(h,sizeof(h));
|
|
||||||
|
|
||||||
if (memcmp(h,"MZ",2) == 0) // dos exe
|
if (memcmp(h, "MZ", 2) == 0) // dos exe
|
||||||
{
|
{
|
||||||
exe_offset = adam_offset;
|
exe_offset = adam_offset;
|
||||||
adam_offset += H(2)*512+H(1);
|
adam_offset += H(2) * 512 + H(1);
|
||||||
if (H(1))
|
if (H(1))
|
||||||
adam_offset -= 512;
|
adam_offset -= 512;
|
||||||
if (H(0x18/2) == 0x40 && H4(0x3c))
|
if (H(0x18 / 2) == 0x40 && H4(0x3c))
|
||||||
adam_offset = H4(0x3c);
|
adam_offset = H4(0x3c);
|
||||||
}
|
} else if (memcmp(h, "BW", 2) == 0)
|
||||||
else if (memcmp(h,"BW",2) == 0)
|
adam_offset += H(2) * 512 + H(1);
|
||||||
adam_offset += H(2)*512+H(1);
|
else if (memcmp(h, "PMW1", 4) == 0) {
|
||||||
else if (memcmp(h,"PMW1",4) == 0)
|
fi->seek(adam_offset + H4(0x18), SEEK_SET);
|
||||||
{
|
|
||||||
fi->seek(adam_offset + H4(0x18),SEEK_SET);
|
|
||||||
adam_offset += H4(0x24);
|
adam_offset += H4(0x24);
|
||||||
int objs = H4(0x1c);
|
int objs = H4(0x1c);
|
||||||
while (objs--)
|
while (objs--) {
|
||||||
{
|
fi->readx(h, 0x18);
|
||||||
fi->readx(h,0x18);
|
|
||||||
adam_offset += H4(4);
|
adam_offset += H4(4);
|
||||||
}
|
}
|
||||||
}
|
} else if (memcmp(h, "LE", 2) == 0) {
|
||||||
else if (memcmp(h,"LE",2) == 0)
|
|
||||||
{
|
|
||||||
// + (memory_pages-1)*memory_page_size+bytes_on_last_page
|
// + (memory_pages-1)*memory_page_size+bytes_on_last_page
|
||||||
unsigned offs = exe_offset + (H4(0x14) - 1) * H4(0x28) + H4(0x2c);
|
unsigned offs = exe_offset + (H4(0x14) - 1) * H4(0x28) + H4(0x2c);
|
||||||
fi->seek(adam_offset+0x80,SEEK_SET);
|
fi->seek(adam_offset + 0x80, SEEK_SET);
|
||||||
fi->readx(h,4);
|
fi->readx(h, 4);
|
||||||
// + data_pages_offset
|
// + data_pages_offset
|
||||||
adam_offset = offs + H4(0);
|
adam_offset = offs + H4(0);
|
||||||
}
|
} else if (memcmp(h, "Adam", 4) == 0)
|
||||||
else if (memcmp(h,"Adam",4) == 0)
|
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
@@ -170,18 +133,15 @@ int PackTmt::readFileHeader()
|
|||||||
if (ic == 20)
|
if (ic == 20)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fi->seek(adam_offset,SEEK_SET);
|
fi->seek(adam_offset, SEEK_SET);
|
||||||
fi->readx(&ih,sizeof(ih));
|
fi->readx(&ih, sizeof(ih));
|
||||||
// FIXME: should add more checks for the values in 'ih'
|
// FIXME: should add more checks for the values in 'ih'
|
||||||
unsigned const imagesize = get_le32(&ih.imagesize);
|
unsigned const imagesize = ih.imagesize;
|
||||||
unsigned const entry = get_le32(&ih.entry);
|
unsigned const entry = ih.entry;
|
||||||
unsigned const relocsize = get_le32(&ih.relocsize);
|
unsigned const relocsize = ih.relocsize;
|
||||||
if (!imagesize
|
if (!imagesize || file_size <= imagesize || file_size <= entry || file_size <= relocsize) {
|
||||||
|| file_size <= imagesize
|
printWarn(getName(), "bad header; imagesize=%#x entry=%#x relocsize=%#x", imagesize,
|
||||||
|| file_size <= entry
|
entry, relocsize);
|
||||||
|| file_size <= relocsize) {
|
|
||||||
printWarn(getName(), "bad header; imagesize=%#x entry=%#x relocsize=%#x",
|
|
||||||
imagesize, entry, relocsize);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,40 +150,37 @@ int PackTmt::readFileHeader()
|
|||||||
#undef H
|
#undef H
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PackTmt::canPack() {
|
||||||
bool PackTmt::canPack()
|
|
||||||
{
|
|
||||||
if (!readFileHeader())
|
if (!readFileHeader())
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
void PackTmt::pack(OutputFile *fo)
|
void PackTmt::pack(OutputFile *fo) {
|
||||||
{
|
|
||||||
big_relocs = 0;
|
big_relocs = 0;
|
||||||
|
|
||||||
Packer::handleStub(fi,fo,adam_offset);
|
Packer::handleStub(fi, fo, adam_offset);
|
||||||
|
|
||||||
const unsigned usize = ih.imagesize;
|
const unsigned usize = ih.imagesize;
|
||||||
const unsigned rsize = ih.relocsize;
|
const unsigned rsize = ih.relocsize;
|
||||||
|
|
||||||
ibuf.alloc(usize+rsize+128);
|
ibuf.alloc(usize + rsize + 128);
|
||||||
obuf.allocForCompression(usize+rsize+128);
|
obuf.allocForCompression(usize + rsize + 128);
|
||||||
|
|
||||||
MemBuffer wrkmem;
|
MemBuffer mb_wrkmem;
|
||||||
wrkmem.alloc(rsize+EXTRA_INFO); // relocations
|
mb_wrkmem.alloc(rsize + EXTRA_INFO); // relocations
|
||||||
|
SPAN_S_VAR(upx_byte, wrkmem, mb_wrkmem);
|
||||||
|
|
||||||
fi->seek(adam_offset+sizeof(ih),SEEK_SET);
|
fi->seek(adam_offset + sizeof(ih), SEEK_SET);
|
||||||
fi->readx(ibuf,usize);
|
fi->readx(ibuf, usize);
|
||||||
fi->readx(wrkmem+4,rsize);
|
fi->readx(wrkmem + 4, rsize);
|
||||||
const unsigned overlay = file_size - fi->tell();
|
const unsigned overlay = file_size - fi->tell();
|
||||||
|
|
||||||
if (find_le32(ibuf,128,get_le32("UPX ")) >= 0)
|
if (find_le32(ibuf, 128, get_le32("UPX ")) >= 0)
|
||||||
throwAlreadyPacked();
|
throwAlreadyPacked();
|
||||||
if (rsize == 0)
|
if (rsize == 0)
|
||||||
throwCantPack("file is already compressed with another packer");
|
throwCantPack("file is already compressed with another packer");
|
||||||
@@ -231,19 +188,20 @@ void PackTmt::pack(OutputFile *fo)
|
|||||||
checkOverlay(overlay);
|
checkOverlay(overlay);
|
||||||
|
|
||||||
unsigned relocsize = 0;
|
unsigned relocsize = 0;
|
||||||
//if (rsize)
|
// if (rsize)
|
||||||
{
|
{
|
||||||
for (unsigned ic=4; ic<=rsize; ic+=4)
|
for (unsigned ic = 4; ic <= rsize; ic += 4)
|
||||||
set_le32(wrkmem+ic,get_le32(wrkmem+ic)-4);
|
set_le32(wrkmem + ic, get_le32(wrkmem + ic) - 4);
|
||||||
relocsize = optimizeReloc32(wrkmem+4,rsize/4,wrkmem,ibuf,file_size,1,&big_relocs);
|
relocsize =
|
||||||
|
optimizeReloc32(wrkmem + 4, rsize / 4, wrkmem, ibuf, file_size, true, &big_relocs);
|
||||||
}
|
}
|
||||||
|
|
||||||
wrkmem[relocsize++] = 0;
|
wrkmem[relocsize++] = 0;
|
||||||
set_le32(wrkmem+relocsize,ih.entry); // save original entry point
|
set_le32(wrkmem + relocsize, ih.entry); // save original entry point
|
||||||
relocsize += 4;
|
relocsize += 4;
|
||||||
set_le32(wrkmem+relocsize,relocsize+4);
|
set_le32(wrkmem + relocsize, relocsize + 4);
|
||||||
relocsize += 4;
|
relocsize += 4;
|
||||||
memcpy(ibuf+usize,wrkmem,relocsize);
|
memcpy(ibuf + usize, wrkmem, relocsize);
|
||||||
|
|
||||||
// prepare packheader
|
// prepare packheader
|
||||||
ph.u_len = usize + relocsize;
|
ph.u_len = usize + relocsize;
|
||||||
@@ -251,7 +209,8 @@ void PackTmt::pack(OutputFile *fo)
|
|||||||
Filter ft(ph.level);
|
Filter ft(ph.level);
|
||||||
ft.buf_len = usize;
|
ft.buf_len = usize;
|
||||||
// compress
|
// compress
|
||||||
upx_compress_config_t cconf; cconf.reset();
|
upx_compress_config_t cconf;
|
||||||
|
cconf.reset();
|
||||||
// limit stack size needed for runtime decompression
|
// limit stack size needed for runtime decompression
|
||||||
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
|
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
|
||||||
compressWithFilters(&ft, 512, &cconf);
|
compressWithFilters(&ft, 512, &cconf);
|
||||||
@@ -260,7 +219,7 @@ void PackTmt::pack(OutputFile *fo)
|
|||||||
const unsigned s_point = getLoaderSection("TMTMAIN1");
|
const unsigned s_point = getLoaderSection("TMTMAIN1");
|
||||||
int e_len = getLoaderSectionStart("TMTCUTPO");
|
int e_len = getLoaderSectionStart("TMTCUTPO");
|
||||||
const unsigned d_len = lsize - e_len;
|
const unsigned d_len = lsize - e_len;
|
||||||
assert(e_len > 0 && s_point > 0);
|
assert(e_len > 0 && s_point > 0);
|
||||||
|
|
||||||
// patch loader
|
// patch loader
|
||||||
linker->defineSymbol("original_entry", ih.entry);
|
linker->defineSymbol("original_entry", ih.entry);
|
||||||
@@ -270,29 +229,26 @@ void PackTmt::pack(OutputFile *fo)
|
|||||||
linker->defineSymbol("bytes_to_copy", ph.c_len + d_len);
|
linker->defineSymbol("bytes_to_copy", ph.c_len + d_len);
|
||||||
linker->defineSymbol("copy_dest", 0u - (ph.u_len + ph.overlap_overhead + d_len - 1));
|
linker->defineSymbol("copy_dest", 0u - (ph.u_len + ph.overlap_overhead + d_len - 1));
|
||||||
linker->defineSymbol("copy_source", ph.c_len + lsize - 1);
|
linker->defineSymbol("copy_source", ph.c_len + lsize - 1);
|
||||||
//fprintf(stderr,"\nelen=%x dlen=%x copy_len=%x copy_to=%x oo=%x jmp_pos=%x ulen=%x c_len=%x \n\n",
|
|
||||||
// e_len,d_len,copy_len,copy_to,ph.overlap_overhead,jmp_pos,ph.u_len,ph.c_len);
|
|
||||||
|
|
||||||
linker->defineSymbol("TMTCUTPO", ph.u_len + ph.overlap_overhead);
|
linker->defineSymbol("TMTCUTPO", ph.u_len + ph.overlap_overhead);
|
||||||
relocateLoader();
|
relocateLoader();
|
||||||
|
|
||||||
MemBuffer loader(lsize);
|
MemBuffer loader(lsize);
|
||||||
memcpy(loader,getLoader(),lsize);
|
memcpy(loader, getLoader(), lsize);
|
||||||
patchPackHeader(loader,e_len);
|
patchPackHeader(loader, e_len);
|
||||||
|
|
||||||
memcpy(&oh,&ih,sizeof(oh));
|
memcpy(&oh, &ih, sizeof(oh));
|
||||||
oh.imagesize = ph.c_len + lsize; // new size
|
oh.imagesize = ph.c_len + lsize; // new size
|
||||||
oh.entry = s_point; // new entry point
|
oh.entry = s_point; // new entry point
|
||||||
oh.relocsize = 4;
|
oh.relocsize = 4;
|
||||||
|
|
||||||
// write loader + compressed file
|
// write loader + compressed file
|
||||||
fo->write(&oh,sizeof(oh));
|
fo->write(&oh, sizeof(oh));
|
||||||
fo->write(loader,e_len);
|
fo->write(loader, e_len);
|
||||||
fo->write(obuf,ph.c_len);
|
fo->write(obuf, ph.c_len);
|
||||||
fo->write(loader+lsize-d_len,d_len); // decompressor
|
fo->write(loader + lsize - d_len, d_len); // decompressor
|
||||||
char rel_entry[4];
|
char rel_entry[4];
|
||||||
set_le32(rel_entry,5 + s_point);
|
set_le32(rel_entry, 5 + s_point);
|
||||||
fo->write(rel_entry,sizeof (rel_entry));
|
fo->write(rel_entry, sizeof(rel_entry));
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
verifyOverlappingDecompression();
|
verifyOverlappingDecompression();
|
||||||
@@ -305,67 +261,60 @@ void PackTmt::pack(OutputFile *fo)
|
|||||||
throwNotCompressible();
|
throwNotCompressible();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PackTmt::canUnpack() {
|
||||||
int PackTmt::canUnpack()
|
|
||||||
{
|
|
||||||
if (!readFileHeader())
|
if (!readFileHeader())
|
||||||
return false;
|
return false;
|
||||||
fi->seek(adam_offset, SEEK_SET);
|
fi->seek(adam_offset, SEEK_SET);
|
||||||
return readPackHeader(512) ? 1 : -1;
|
return readPackHeader(512) ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PackTmt::unpack(OutputFile *fo) {
|
||||||
void PackTmt::unpack(OutputFile *fo)
|
Packer::handleStub(fi, fo, adam_offset);
|
||||||
{
|
|
||||||
Packer::handleStub(fi,fo,adam_offset);
|
|
||||||
|
|
||||||
ibuf.alloc(ph.c_len);
|
ibuf.alloc(ph.c_len);
|
||||||
obuf.allocForDecompression(ph.u_len);
|
obuf.allocForDecompression(ph.u_len);
|
||||||
|
|
||||||
fi->seek(adam_offset + ph.buf_offset + ph.getPackHeaderSize(),SEEK_SET);
|
fi->seek(adam_offset + ph.buf_offset + ph.getPackHeaderSize(), SEEK_SET);
|
||||||
fi->readx(ibuf,ph.c_len);
|
fi->readx(ibuf, ph.c_len);
|
||||||
|
|
||||||
// decompress
|
// decompress
|
||||||
decompress(ibuf,obuf);
|
decompress(ibuf, obuf);
|
||||||
|
|
||||||
// decode relocations
|
// decode relocations
|
||||||
const unsigned osize = ph.u_len - get_le32(obuf+ph.u_len-4);
|
const unsigned osize = ph.u_len - get_le32(obuf + ph.u_len - 4);
|
||||||
SPAN_P_VAR(upx_byte, relocs, obuf + osize);
|
SPAN_P_VAR(upx_byte, relocs, obuf + osize);
|
||||||
const unsigned origstart = get_le32(obuf+ph.u_len-8);
|
const unsigned origstart = get_le32(obuf + ph.u_len - 8);
|
||||||
|
|
||||||
// unfilter
|
// unfilter
|
||||||
if (ph.filter)
|
if (ph.filter) {
|
||||||
{
|
|
||||||
Filter ft(ph.level);
|
Filter ft(ph.level);
|
||||||
ft.init(ph.filter, 0);
|
ft.init(ph.filter, 0);
|
||||||
ft.cto = (unsigned char) ph.filter_cto;
|
ft.cto = (unsigned char) ph.filter_cto;
|
||||||
if (ph.version < 11)
|
if (ph.version < 11)
|
||||||
ft.cto = (unsigned char) (get_le32(obuf+ph.u_len-12) >> 24);
|
ft.cto = (unsigned char) (get_le32(obuf + ph.u_len - 12) >> 24);
|
||||||
ft.unfilter(obuf, ptr_udiff_bytes(relocs, obuf));
|
ft.unfilter(obuf, ptr_udiff_bytes(relocs, obuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode relocations
|
// decode relocations
|
||||||
MemBuffer mb_wrkmem;
|
MemBuffer mb_wrkmem;
|
||||||
unsigned relocn = unoptimizeReloc32(relocs, obuf, mb_wrkmem, true);
|
const unsigned relocn = unoptimizeReloc32(relocs, obuf, mb_wrkmem, true);
|
||||||
SPAN_S_VAR(upx_byte, wrkmem, mb_wrkmem);
|
SPAN_S_VAR(upx_byte, wrkmem, mb_wrkmem);
|
||||||
for (unsigned ic = 0; ic < relocn; ic++)
|
for (unsigned ic = 0; ic < relocn; ic++)
|
||||||
set_le32(wrkmem+ic*4,get_le32(wrkmem+ic*4)+4);
|
set_le32(wrkmem + ic * 4, get_le32(wrkmem + ic * 4) + 4);
|
||||||
|
|
||||||
memcpy(&oh,&ih,sizeof(oh));
|
memcpy(&oh, &ih, sizeof(oh));
|
||||||
oh.imagesize = osize;
|
oh.imagesize = osize;
|
||||||
oh.entry = origstart;
|
oh.entry = origstart;
|
||||||
oh.relocsize = relocn*4;
|
oh.relocsize = relocn * 4;
|
||||||
|
|
||||||
const unsigned overlay = file_size - adam_offset - ih.imagesize
|
const unsigned overlay = file_size - adam_offset - ih.imagesize - ih.relocsize - sizeof(ih);
|
||||||
- ih.relocsize - sizeof(ih);
|
|
||||||
checkOverlay(overlay);
|
checkOverlay(overlay);
|
||||||
|
|
||||||
// write decompressed file
|
// write decompressed file
|
||||||
if (fo)
|
if (fo) {
|
||||||
{
|
fo->write(&oh, sizeof(oh));
|
||||||
fo->write(&oh,sizeof(oh));
|
fo->write(obuf, osize);
|
||||||
fo->write(obuf,osize);
|
fo->write(raw_bytes(wrkmem, relocn * 4), relocn * 4);
|
||||||
fo->write(raw_bytes(wrkmem,relocn*4), relocn*4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy the overlay
|
// copy the overlay
|
||||||
|
|||||||
+11
-14
@@ -25,24 +25,24 @@
|
|||||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UPX_P_TMT_H
|
#ifndef __UPX_P_TMT_H
|
||||||
#define __UPX_P_TMT_H 1
|
#define __UPX_P_TMT_H 1
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// tmt/adam
|
// tmt/adam
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
class PackTmt final : public Packer
|
class PackTmt final : public Packer {
|
||||||
{
|
|
||||||
typedef Packer super;
|
typedef Packer super;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PackTmt(InputFile *f);
|
PackTmt(InputFile *f);
|
||||||
virtual int getVersion() const override { return 13; }
|
virtual int getVersion() const override { return 13; }
|
||||||
virtual int getFormat() const override { return UPX_F_TMT_ADAM; }
|
virtual int getFormat() const override { return UPX_F_TMT_ADAM; }
|
||||||
virtual const char *getName() const override { return "tmt/adam"; }
|
virtual const char *getName() const override { return "tmt/adam"; }
|
||||||
virtual const char *getFullName(const options_t *) const override { return "i386-dos32.tmt.adam"; }
|
virtual const char *getFullName(const options_t *) const override {
|
||||||
|
return "i386-dos32.tmt.adam";
|
||||||
|
}
|
||||||
virtual const int *getCompressionMethods(int method, int level) const override;
|
virtual const int *getCompressionMethods(int method, int level) const override;
|
||||||
virtual const int *getFilters() const override;
|
virtual const int *getFilters() const override;
|
||||||
|
|
||||||
@@ -55,28 +55,25 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
int readFileHeader();
|
int readFileHeader();
|
||||||
|
|
||||||
virtual unsigned findOverlapOverhead(const upx_bytep buf,
|
virtual unsigned findOverlapOverhead(const upx_bytep buf, const upx_bytep tbuf,
|
||||||
const upx_bytep tbuf,
|
|
||||||
unsigned range = 0,
|
unsigned range = 0,
|
||||||
unsigned upper_limit = ~0u) const override;
|
unsigned upper_limit = ~0u) const override;
|
||||||
virtual void buildLoader(const Filter *ft) override;
|
virtual void buildLoader(const Filter *ft) override;
|
||||||
virtual Linker* newLinker() const override;
|
virtual Linker *newLinker() const override;
|
||||||
|
|
||||||
unsigned adam_offset;
|
unsigned adam_offset;
|
||||||
int big_relocs;
|
int big_relocs;
|
||||||
|
|
||||||
struct tmt_header_t
|
struct tmt_header_t {
|
||||||
{
|
char _[16]; // signature,linkerversion,minversion,exesize,imagestart
|
||||||
char _[16]; // signature,linkerversion,minversion,exesize,imagestart
|
|
||||||
LE32 imagesize;
|
LE32 imagesize;
|
||||||
char __[4]; // initial memory
|
char __[4]; // initial memory
|
||||||
LE32 entry;
|
LE32 entry;
|
||||||
char ___[12]; // esp,numfixups,flags
|
char ___[12]; // esp,numfixups,flags
|
||||||
LE32 relocsize;
|
LE32 relocsize;
|
||||||
} ih, oh;
|
} ih, oh;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* already included */
|
#endif /* already included */
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
Reference in New Issue
Block a user