src: add a xspan check to p_tmt.cpp and clang-format

This commit is contained in:
Markus F.X.J. Oberhumer
2022-11-24 09:11:25 +01:00
parent 779b648c5f
commit 93c6496ba8
3 changed files with 108 additions and 162 deletions
+1 -1
View File
@@ -79,7 +79,7 @@ CLANG_FORMAT_FILES += except.cpp except.h
CLANG_FORMAT_FILES += file.cpp file.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 += 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 += ui.cpp ui.h work.cpp
CLANG_FORMAT_FILES += $(wildcard util/[a-ln-z]*.[ch]* util/mem*.[ch]*)
+42 -93
View File
@@ -25,7 +25,6 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com>
*/
#include "conf.h"
#include "file.h"
#include "filter.h"
@@ -33,92 +32,63 @@
#include "p_tmt.h"
#include "linker.h"
static const
static const CLANG_FORMAT_DUMMY_STATEMENT
#include "stub/i386-dos32.tmt.h"
#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;
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);
}
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 };
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};
return filters;
}
unsigned PackTmt::findOverlapOverhead(const upx_bytep buf,
const upx_bytep tbuf,
unsigned range,
unsigned upper_limit) const
{
unsigned PackTmt::findOverlapOverhead(const upx_bytep buf, const upx_bytep tbuf, unsigned range,
unsigned upper_limit) const {
// make sure the decompressor will be paragraph aligned
unsigned o = super::findOverlapOverhead(buf, tbuf, range, upper_limit);
o = ((o + 0x20) & ~0xf) - (ph.u_len & 0xf);
return o;
}
Linker *PackTmt::newLinker() const { return new ElfLinkerX86; }
Linker* PackTmt::newLinker() const
{
return new ElfLinkerX86;
}
void PackTmt::buildLoader(const Filter *ft)
{
void PackTmt::buildLoader(const Filter *ft) {
// prepare loader
initLoader(stub_i386_dos32_tmt, sizeof(stub_i386_dos32_tmt));
addLoader("IDENTSTR,TMTMAIN1",
ph.first_offset_found == 1 ? "TMTMAIN1A" : "",
"TMTMAIN1B",
ft->id ? "TMTCALT1" : "",
"TMTMAIN2,UPX1HEAD,TMTCUTPO",
nullptr);
addLoader("IDENTSTR,TMTMAIN1", ph.first_offset_found == 1 ? "TMTMAIN1A" : "", "TMTMAIN1B",
ft->id ? "TMTCALT1" : "", "TMTMAIN2,UPX1HEAD,TMTCUTPO", nullptr);
// fake alignment for the start of the decompressor
linker->defineSymbol("TMTCUTPO", 0x1000);
addLoader(getDecompressorSections(), "TMTMAIN5", nullptr);
if (ft->id)
{
if (ft->id) {
assert(ft->calls > 0);
addLoader("TMTCALT2", nullptr);
addFilter32(ft->id);
}
addLoader("TMTRELOC,RELOC320",
big_relocs ? "REL32BIG" : "",
"RELOC32J,TMTJUMP1",
nullptr
);
addLoader("TMTRELOC,RELOC320", big_relocs ? "REL32BIG" : "", "RELOC32J,TMTJUMP1", nullptr);
}
/*************************************************************************
//
**************************************************************************/
int PackTmt::readFileHeader()
{
int PackTmt::readFileHeader() {
#define H(x) get_le16(h + 2 * (x))
#define H4(x) get_le32(h + (x))
unsigned char h[0x40];
@@ -126,8 +96,7 @@ int PackTmt::readFileHeader()
unsigned exe_offset = 0;
adam_offset = 0;
for (ic = 0; ic < 20; ic++)
{
for (ic = 0; ic < 20; ic++) {
fi->seek(adam_offset, SEEK_SET);
fi->readx(h, sizeof(h));
@@ -139,30 +108,24 @@ int PackTmt::readFileHeader()
adam_offset -= 512;
if (H(0x18 / 2) == 0x40 && 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);
else if (memcmp(h,"PMW1",4) == 0)
{
else if (memcmp(h, "PMW1", 4) == 0) {
fi->seek(adam_offset + H4(0x18), SEEK_SET);
adam_offset += H4(0x24);
int objs = H4(0x1c);
while (objs--)
{
while (objs--) {
fi->readx(h, 0x18);
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
unsigned offs = exe_offset + (H4(0x14) - 1) * H4(0x28) + H4(0x2c);
fi->seek(adam_offset + 0x80, SEEK_SET);
fi->readx(h, 4);
// + data_pages_offset
adam_offset = offs + H4(0);
}
else if (memcmp(h,"Adam",4) == 0)
} else if (memcmp(h, "Adam", 4) == 0)
break;
else
return 0;
@@ -173,15 +136,12 @@ int PackTmt::readFileHeader()
fi->seek(adam_offset, SEEK_SET);
fi->readx(&ih, sizeof(ih));
// FIXME: should add more checks for the values in 'ih'
unsigned const imagesize = get_le32(&ih.imagesize);
unsigned const entry = get_le32(&ih.entry);
unsigned const relocsize = get_le32(&ih.relocsize);
if (!imagesize
|| file_size <= imagesize
|| file_size <= entry
|| file_size <= relocsize) {
printWarn(getName(), "bad header; imagesize=%#x entry=%#x relocsize=%#x",
imagesize, entry, relocsize);
unsigned const imagesize = ih.imagesize;
unsigned const entry = ih.entry;
unsigned const relocsize = ih.relocsize;
if (!imagesize || file_size <= imagesize || file_size <= entry || file_size <= relocsize) {
printWarn(getName(), "bad header; imagesize=%#x entry=%#x relocsize=%#x", imagesize,
entry, relocsize);
return 0;
}
@@ -190,21 +150,17 @@ int PackTmt::readFileHeader()
#undef H
}
bool PackTmt::canPack()
{
bool PackTmt::canPack() {
if (!readFileHeader())
return false;
return true;
}
/*************************************************************************
//
**************************************************************************/
void PackTmt::pack(OutputFile *fo)
{
void PackTmt::pack(OutputFile *fo) {
big_relocs = 0;
Packer::handleStub(fi, fo, adam_offset);
@@ -215,8 +171,9 @@ void PackTmt::pack(OutputFile *fo)
ibuf.alloc(usize + rsize + 128);
obuf.allocForCompression(usize + rsize + 128);
MemBuffer wrkmem;
wrkmem.alloc(rsize+EXTRA_INFO); // relocations
MemBuffer mb_wrkmem;
mb_wrkmem.alloc(rsize + EXTRA_INFO); // relocations
SPAN_S_VAR(upx_byte, wrkmem, mb_wrkmem);
fi->seek(adam_offset + sizeof(ih), SEEK_SET);
fi->readx(ibuf, usize);
@@ -235,7 +192,8 @@ void PackTmt::pack(OutputFile *fo)
{
for (unsigned ic = 4; ic <= rsize; 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;
@@ -251,7 +209,8 @@ void PackTmt::pack(OutputFile *fo)
Filter ft(ph.level);
ft.buf_len = usize;
// compress
upx_compress_config_t cconf; cconf.reset();
upx_compress_config_t cconf;
cconf.reset();
// limit stack size needed for runtime decompression
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
compressWithFilters(&ft, 512, &cconf);
@@ -270,9 +229,6 @@ void PackTmt::pack(OutputFile *fo)
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_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);
relocateLoader();
@@ -305,18 +261,14 @@ void PackTmt::pack(OutputFile *fo)
throwNotCompressible();
}
int PackTmt::canUnpack()
{
int PackTmt::canUnpack() {
if (!readFileHeader())
return false;
fi->seek(adam_offset, SEEK_SET);
return readPackHeader(512) ? 1 : -1;
}
void PackTmt::unpack(OutputFile *fo)
{
void PackTmt::unpack(OutputFile *fo) {
Packer::handleStub(fi, fo, adam_offset);
ibuf.alloc(ph.c_len);
@@ -334,8 +286,7 @@ void PackTmt::unpack(OutputFile *fo)
const unsigned origstart = get_le32(obuf + ph.u_len - 8);
// unfilter
if (ph.filter)
{
if (ph.filter) {
Filter ft(ph.level);
ft.init(ph.filter, 0);
ft.cto = (unsigned char) ph.filter_cto;
@@ -346,7 +297,7 @@ void PackTmt::unpack(OutputFile *fo)
// decode relocations
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);
for (unsigned ic = 0; ic < relocn; ic++)
set_le32(wrkmem + ic * 4, get_le32(wrkmem + ic * 4) + 4);
@@ -356,13 +307,11 @@ void PackTmt::unpack(OutputFile *fo)
oh.entry = origstart;
oh.relocsize = relocn * 4;
const unsigned overlay = file_size - adam_offset - ih.imagesize
- ih.relocsize - sizeof(ih);
const unsigned overlay = file_size - adam_offset - ih.imagesize - ih.relocsize - sizeof(ih);
checkOverlay(overlay);
// write decompressed file
if (fo)
{
if (fo) {
fo->write(&oh, sizeof(oh));
fo->write(obuf, osize);
fo->write(raw_bytes(wrkmem, relocn * 4), relocn * 4);
+7 -10
View File
@@ -25,24 +25,24 @@
<markus@oberhumer.com> <ezerotven+github@gmail.com>
*/
#ifndef __UPX_P_TMT_H
#define __UPX_P_TMT_H 1
/*************************************************************************
// tmt/adam
**************************************************************************/
class PackTmt final : public Packer
{
class PackTmt final : public Packer {
typedef Packer super;
public:
PackTmt(InputFile *f);
virtual int getVersion() const override { return 13; }
virtual int getFormat() const override { return UPX_F_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 *getFilters() const override;
@@ -55,8 +55,7 @@ public:
protected:
int readFileHeader();
virtual unsigned findOverlapOverhead(const upx_bytep buf,
const upx_bytep tbuf,
virtual unsigned findOverlapOverhead(const upx_bytep buf, const upx_bytep tbuf,
unsigned range = 0,
unsigned upper_limit = ~0u) const override;
virtual void buildLoader(const Filter *ft) override;
@@ -65,8 +64,7 @@ protected:
unsigned adam_offset;
int big_relocs;
struct tmt_header_t
{
struct tmt_header_t {
char _[16]; // signature,linkerversion,minversion,exesize,imagestart
LE32 imagesize;
char __[4]; // initial memory
@@ -76,7 +74,6 @@ protected:
} ih, oh;
};
#endif /* already included */
/* vim:set ts=4 sw=4 et: */