Merge branch 'devel' into jreiser
modified: ../.appveyor.yml modified: ../.github/travis_build.sh modified: Makefile modified: linker.cpp modified: p_lx_elf.cpp modified: packmast.cpp
This commit is contained in:
commit
e88d2ff88c
@ -34,7 +34,6 @@ init:
|
||||
# - dir "c:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin"
|
||||
|
||||
install:
|
||||
- set PATH=%PATH%;C:\Program Files\Git\mingw64\bin
|
||||
- cd c:\projects
|
||||
- md build build\%C% deps
|
||||
- cd c:\projects\upx
|
||||
|
||||
3
.github/travis_build.sh
vendored
3
.github/travis_build.sh
vendored
@ -51,11 +51,12 @@ if [[ $BM_X =~ (^|\+)rebuild-stubs($|\+) ]]; then
|
||||
extra_subdirs+=( src/stub/src/arch/amd64 )
|
||||
extra_subdirs+=( src/stub/src/arch/arm/v4a )
|
||||
extra_subdirs+=( src/stub/src/arch/arm/v4t )
|
||||
#extra_subdirs+=( src/stub/src/arch/arm64/v8 ) # FIXME / TODO
|
||||
extra_subdirs+=( src/stub/src/arch/i386 )
|
||||
extra_subdirs+=( src/stub/src/arch/m68k/m68000 )
|
||||
extra_subdirs+=( src/stub/src/arch/m68k/m68020 )
|
||||
extra_subdirs+=( src/stub/src/arch/mips/r3000 )
|
||||
#extra_subdirs+=( src/stub/src/arch/powerpc/32 ) # FIXME / TODO
|
||||
extra_subdirs+=( src/stub/src/arch/powerpc/32 )
|
||||
extra_subdirs+=( src/stub/src/arch/powerpc/64le )
|
||||
make -C src/stub maintainer-clean
|
||||
for d in ${extra_subdirs[@]}; do
|
||||
|
||||
@ -163,7 +163,7 @@ endif
|
||||
|
||||
# automatically format some C++ source code files
|
||||
ifeq ($(shell uname),Linux)
|
||||
CLANG_FORMAT_FILES += linker.cpp linker.h packhead.cpp
|
||||
CLANG_FORMAT_FILES += linker.cpp linker.h packhead.cpp packmast.cpp
|
||||
CLANG_FORMAT_FILES += s_djgpp2.cpp s_object.cpp s_vcsa.cpp s_win32.cpp screen.h
|
||||
CLANG_FORMAT_FILES += snprintf.cpp
|
||||
CLANG_FORMAT_FILES += stdcxx.cpp stdcxx.h
|
||||
|
||||
@ -474,7 +474,8 @@ void ElfLinker::relocate() {
|
||||
upx_byte *location = rel->section->output + rel->offset;
|
||||
// printf("%-28s %-28s %-10s %#16llx %#16llx\n", rel->section->name, rel->value->name,
|
||||
// rel->type, (long long) value, (long long) value - rel->section->offset - rel->offset);
|
||||
// printf(" %llx %d %llx %d %llx : %d\n", (long long) value, (int)rel->value->section->offset,
|
||||
// printf(" %llx %d %llx %d %llx : %d\n", (long long) value,
|
||||
// (int)rel->value->section->offset,
|
||||
// rel->value->offset, rel->offset, (long long) rel->add, *location);
|
||||
relocate1(rel, location, value, rel->type);
|
||||
}
|
||||
@ -611,14 +612,12 @@ void ElfLinkerARM64::relocate1(const Relocation *rel, upx_byte *location, upx_ui
|
||||
set_le32(location, get_le32(location) + value);
|
||||
} else if (!strcmp(type, "ABS64")) {
|
||||
set_le64(location, get_le64(location) + value);
|
||||
}
|
||||
else if (!strcmp(type, "CONDBR19")) {
|
||||
} else if (!strcmp(type, "CONDBR19")) {
|
||||
value -= rel->section->offset + rel->offset;
|
||||
uint32_t const m19 = ~(~0u << 19);
|
||||
uint32_t w = get_le32(location);
|
||||
set_le32(location, (w &~(m19<<5)) | ((((w>>5) + (value>>2)) & m19) << 5) );
|
||||
}
|
||||
else
|
||||
upx_uint32_t const m19 = ~(~0u << 19);
|
||||
upx_uint32_t w = get_le32(location);
|
||||
set_le32(location, (w & ~(m19 << 5)) | ((((w >> 5) + (value >> 2)) & m19) << 5));
|
||||
} else
|
||||
super::relocate1(rel, location, value, type);
|
||||
}
|
||||
|
||||
|
||||
@ -2403,7 +2403,7 @@ PackLinuxElf32::generateElfHdr(
|
||||
set_te32(&h2->phdr[1].p_flags, Elf32_Phdr::PF_R | Elf32_Phdr::PF_W);
|
||||
}
|
||||
if (ph.format==getFormat()) {
|
||||
assert((2+ !!gnu_stack) == phnum_o);
|
||||
assert((2u+ !!gnu_stack) == phnum_o);
|
||||
set_te32(&h2->phdr[0].p_flags, ~Elf32_Phdr::PF_W & get_te32(&h2->phdr[0].p_flags));
|
||||
if (!gnu_stack) {
|
||||
memset(&h2->linfo, 0, sizeof(h2->linfo));
|
||||
@ -2665,7 +2665,7 @@ PackLinuxElf64::generateElfHdr(
|
||||
set_te32(&h2->phdr[1].p_flags, Elf64_Phdr::PF_R | Elf64_Phdr::PF_W);
|
||||
}
|
||||
if (ph.format==getFormat()) {
|
||||
assert((2+ !!gnu_stack) == phnum_o);
|
||||
assert((2u+ !!gnu_stack) == phnum_o);
|
||||
set_te32(&h2->phdr[0].p_flags, ~Elf64_Phdr::PF_W & get_te32(&h2->phdr[0].p_flags));
|
||||
if (!gnu_stack) {
|
||||
memset(&h2->linfo, 0, sizeof(h2->linfo));
|
||||
@ -3573,7 +3573,7 @@ void PackLinuxElf32::pack4(OutputFile *fo, Filter &ft)
|
||||
|
||||
if (0!=xct_off) { // shared library
|
||||
if (opt->o_unix.android_shlib && shdri) { // dlopen() checks Elf32_Shdr vs Elf32_Phdr
|
||||
unsigned load0_hi = ~0;
|
||||
unsigned load0_hi = ~0u;
|
||||
Elf32_Phdr const *phdr = phdri;
|
||||
for (unsigned j = 0; j < e_phnum; ++j, ++phdr) {
|
||||
unsigned load0_lo = get_te32(&phdr->p_vaddr);
|
||||
@ -3704,7 +3704,7 @@ void PackLinuxElf64::pack4(OutputFile *fo, Filter &ft)
|
||||
|
||||
if (0!=xct_off) { // shared library
|
||||
if (opt->o_unix.android_shlib && shdri) { // dlopen() checks Elf64_Shdr vs Elf64_Phdr
|
||||
unsigned load0_hi = ~0;
|
||||
unsigned load0_hi = ~0u;
|
||||
Elf64_Phdr const *phdr = phdri;
|
||||
for (unsigned j = 0; j < e_phnum; ++j, ++phdr) {
|
||||
upx_uint64_t load0_lo = get_te64(&phdr->p_vaddr);
|
||||
|
||||
234
src/packmast.cpp
234
src/packmast.cpp
@ -25,7 +25,6 @@
|
||||
<markus@oberhumer.com> <ezerotven+github@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "file.h"
|
||||
#include "packmast.h"
|
||||
@ -54,56 +53,48 @@
|
||||
#include "p_mach.h"
|
||||
#include "p_armpe.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
PackMaster::PackMaster(InputFile *f, options_t *o) :
|
||||
fi(f), p(NULL)
|
||||
{
|
||||
PackMaster::PackMaster(InputFile *f, options_t *o) : fi(f), p(NULL) {
|
||||
// replace global options with local options
|
||||
saved_opt = o;
|
||||
if (o)
|
||||
{
|
||||
if (o) {
|
||||
memcpy(&this->local_options, o, sizeof(*o)); // struct copy
|
||||
opt = &this->local_options;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PackMaster::~PackMaster()
|
||||
{
|
||||
PackMaster::~PackMaster() {
|
||||
fi = NULL;
|
||||
delete p; p = NULL;
|
||||
delete p;
|
||||
p = NULL;
|
||||
// restore global options
|
||||
if (saved_opt)
|
||||
opt = saved_opt;
|
||||
saved_opt = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static Packer* try_pack(Packer *p, void *user)
|
||||
{
|
||||
static Packer *try_pack(Packer *p, void *user) {
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
InputFile *f = (InputFile *) user;
|
||||
p->assertPacker();
|
||||
try {
|
||||
p->initPackHeader();
|
||||
f->seek(0,SEEK_SET);
|
||||
if (p->canPack())
|
||||
{
|
||||
f->seek(0, SEEK_SET);
|
||||
if (p->canPack()) {
|
||||
if (opt->cmd == CMD_COMPRESS)
|
||||
p->updatePackHeader();
|
||||
f->seek(0,SEEK_SET);
|
||||
f->seek(0, SEEK_SET);
|
||||
return p;
|
||||
}
|
||||
} catch (const IOException&) {
|
||||
} catch (const IOException &) {
|
||||
} catch (...) {
|
||||
delete p;
|
||||
throw;
|
||||
@ -112,28 +103,24 @@ static Packer* try_pack(Packer *p, void *user)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static Packer* try_unpack(Packer *p, void *user)
|
||||
{
|
||||
static Packer *try_unpack(Packer *p, void *user) {
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
InputFile *f = (InputFile *) user;
|
||||
p->assertPacker();
|
||||
try {
|
||||
p->initPackHeader();
|
||||
f->seek(0,SEEK_SET);
|
||||
f->seek(0, SEEK_SET);
|
||||
int r = p->canUnpack();
|
||||
if (r > 0)
|
||||
{
|
||||
f->seek(0,SEEK_SET);
|
||||
if (r > 0) {
|
||||
f->seek(0, SEEK_SET);
|
||||
return p;
|
||||
}
|
||||
if (r < 0)
|
||||
{
|
||||
if (r < 0) {
|
||||
// FIXME - could stop testing all other unpackers at this time
|
||||
// see canUnpack() in packer.h
|
||||
}
|
||||
} catch (const IOException&) {
|
||||
} catch (const IOException &) {
|
||||
} catch (...) {
|
||||
delete p;
|
||||
throw;
|
||||
@ -142,155 +129,110 @@ static Packer* try_unpack(Packer *p, void *user)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
|
||||
#define D(name) if (o->debug.debug_level) fprintf(stderr, "%s\n", #name)
|
||||
|
||||
Packer* PackMaster::visitAllPackers(visit_func_t func, InputFile *f, const options_t *o, void *user)
|
||||
{
|
||||
Packer *PackMaster::visitAllPackers(visit_func_t func, InputFile *f, const options_t *o,
|
||||
void *user) {
|
||||
Packer *p = NULL;
|
||||
|
||||
#define D(klass) \
|
||||
ACC_BLOCK_BEGIN \
|
||||
if (o->debug.debug_level) \
|
||||
fprintf(stderr, "visitAllPackers: %s\n", #klass); \
|
||||
if ((p = func(new klass(f), user)) != NULL) \
|
||||
return p; \
|
||||
ACC_BLOCK_END
|
||||
|
||||
// note: order of tries is important !
|
||||
|
||||
//
|
||||
// .exe
|
||||
//
|
||||
if (!o->dos_exe.force_stub)
|
||||
{
|
||||
D(PackDjgpp2); if ((p = func(new PackDjgpp2(f), user)))
|
||||
return p;
|
||||
D(PackTmt); if ((p = func(new PackTmt(f), user)))
|
||||
return p;
|
||||
D(PackWcle); if ((p = func(new PackWcle(f), user)))
|
||||
return p;
|
||||
D(PackW64Pep); if ((p = func(new PackW64Pep(f), user)))
|
||||
return p;
|
||||
D(PackW32Pe); if ((p = func(new PackW32Pe(f), user)))
|
||||
return p;
|
||||
if (!o->dos_exe.force_stub) {
|
||||
D(PackDjgpp2);
|
||||
D(PackTmt);
|
||||
D(PackWcle);
|
||||
D(PackW64Pep);
|
||||
D(PackW32Pe);
|
||||
}
|
||||
D(PackArmPe); if ((p = func(new PackArmPe(f), user)))
|
||||
return p;
|
||||
D(PackExe); if ((p = func(new PackExe(f), user)))
|
||||
return p;
|
||||
D(PackArmPe);
|
||||
D(PackExe);
|
||||
|
||||
//
|
||||
// atari
|
||||
//
|
||||
D(PackTos); if ((p = func(new PackTos(f), user)))
|
||||
return p;
|
||||
D(PackTos);
|
||||
|
||||
//
|
||||
// linux kernel
|
||||
//
|
||||
D(PackVmlinuxARMEL); if ((p = func(new PackVmlinuxARMEL(f), user)))
|
||||
return p;
|
||||
D(PackVmlinuxARMEB); if ((p = func(new PackVmlinuxARMEB(f), user)))
|
||||
return p;
|
||||
D(PackVmlinuxPPC32); if ((p = func(new PackVmlinuxPPC32(f), user)))
|
||||
return p;
|
||||
D(PackVmlinuxPPC64LE); if ((p = func(new PackVmlinuxPPC64LE(f), user)))
|
||||
return p;
|
||||
D(PackVmlinuxAMD64); if ((p = func(new PackVmlinuxAMD64(f), user)))
|
||||
return p;
|
||||
D(PackVmlinuxI386); if ((p = func(new PackVmlinuxI386(f), user)))
|
||||
return p;
|
||||
D(PackVmlinuzI386); if ((p = func(new PackVmlinuzI386(f), user)))
|
||||
return p;
|
||||
D(PackBvmlinuzI386); if ((p = func(new PackBvmlinuzI386(f), user)))
|
||||
return p;
|
||||
D(PackVmlinuzARMEL); if ((p = func(new PackVmlinuzARMEL(f), user)))
|
||||
return p;
|
||||
D(PackVmlinuxARMEL);
|
||||
D(PackVmlinuxARMEB);
|
||||
D(PackVmlinuxPPC32);
|
||||
D(PackVmlinuxPPC64LE);
|
||||
D(PackVmlinuxAMD64);
|
||||
D(PackVmlinuxI386);
|
||||
D(PackVmlinuzI386);
|
||||
D(PackBvmlinuzI386);
|
||||
D(PackVmlinuzARMEL);
|
||||
|
||||
//
|
||||
// linux
|
||||
//
|
||||
if (!o->o_unix.force_execve)
|
||||
{
|
||||
if (!o->o_unix.force_execve) {
|
||||
if (o->o_unix.use_ptinterp) {
|
||||
D(PackLinuxElf32x86interp); if ((p = func(new PackLinuxElf32x86interp(f), user)))
|
||||
return p;
|
||||
D(PackLinuxElf32x86interp);
|
||||
}
|
||||
D(PackFreeBSDElf32x86); if ((p = func(new PackFreeBSDElf32x86(f), user)))
|
||||
return p;
|
||||
D(PackNetBSDElf32x86); if ((p = func(new PackNetBSDElf32x86(f), user)))
|
||||
return p;
|
||||
D(PackOpenBSDElf32x86); if ((p = func(new PackOpenBSDElf32x86(f), user)))
|
||||
return p;
|
||||
D(PackLinuxElf32x86); if ((p = func(new PackLinuxElf32x86(f), user)))
|
||||
return p;
|
||||
D(PackLinuxElf64amd); if ((p = func(new PackLinuxElf64amd(f), user)))
|
||||
return p;
|
||||
D(PackLinuxElf32armLe); if ((p = func(new PackLinuxElf32armLe(f), user)))
|
||||
return p;
|
||||
D(PackLinuxElf32armBe); if ((p = func(new PackLinuxElf32armBe(f), user)))
|
||||
return p;
|
||||
D(PackLinuxElf64arm); if ((p = func(new PackLinuxElf64arm(f), user)))
|
||||
return p;
|
||||
D(PackLinuxElf32ppc); if ((p = func(new PackLinuxElf32ppc(f), user)))
|
||||
return p;
|
||||
D(PackLinuxElf64ppcle); if ((p = func(new PackLinuxElf64ppcle(f), user)))
|
||||
return p;
|
||||
D(PackLinuxElf32mipsel); if ((p = func(new PackLinuxElf32mipsel(f), user)))
|
||||
return p;
|
||||
D(PackLinuxElf32mipseb); if ((p = func(new PackLinuxElf32mipseb(f), user)))
|
||||
return p;
|
||||
D(PackLinuxI386sh); if ((p = func(new PackLinuxI386sh(f), user)))
|
||||
return p;
|
||||
D(PackFreeBSDElf32x86);
|
||||
D(PackNetBSDElf32x86);
|
||||
D(PackOpenBSDElf32x86);
|
||||
D(PackLinuxElf32x86);
|
||||
D(PackLinuxElf64amd);
|
||||
D(PackLinuxElf32armLe);
|
||||
D(PackLinuxElf32armBe);
|
||||
D(PackLinuxElf64arm);
|
||||
D(PackLinuxElf32ppc);
|
||||
D(PackLinuxElf64ppcle);
|
||||
D(PackLinuxElf32mipsel);
|
||||
D(PackLinuxElf32mipseb);
|
||||
D(PackLinuxI386sh);
|
||||
}
|
||||
D(PackBSDI386); if ((p = func(new PackBSDI386(f), user)))
|
||||
return p;
|
||||
D(PackMachFat); if ((p = func(new PackMachFat(f), user))) // cafebabe conflict
|
||||
return p;
|
||||
D(PackLinuxI386); if ((p = func(new PackLinuxI386(f), user))) // cafebabe conflict
|
||||
return p;
|
||||
D(PackBSDI386);
|
||||
D(PackMachFat); // cafebabe conflict
|
||||
D(PackLinuxI386); // cafebabe conflict
|
||||
|
||||
//
|
||||
// psone
|
||||
//
|
||||
D(PackPs1); if ((p = func(new PackPs1(f), user)))
|
||||
return p;
|
||||
D(PackPs1);
|
||||
|
||||
//
|
||||
// .sys and .com
|
||||
//
|
||||
D(PackSys); if ((p = func(new PackSys(f), user)))
|
||||
return p;
|
||||
D(PackCom); if ((p = func(new PackCom(f), user)))
|
||||
return p;
|
||||
D(PackSys);
|
||||
D(PackCom);
|
||||
|
||||
// Mach (MacOS X PowerPC)
|
||||
D(PackMachPPC32); if ((p = func(new PackMachPPC32(f), user)))
|
||||
return p;
|
||||
D(PackMachPPC64LE); if ((p = func(new PackMachPPC64LE(f), user)))
|
||||
return p;
|
||||
D(PackMachI386); if ((p = func(new PackMachI386(f), user)))
|
||||
return p;
|
||||
D(PackMachAMD64); if ((p = func(new PackMachAMD64(f), user)))
|
||||
return p;
|
||||
D(PackMachARMEL); if ((p = func(new PackMachARMEL(f), user)))
|
||||
return p;
|
||||
D(PackMachPPC32);
|
||||
D(PackMachPPC64LE);
|
||||
D(PackMachI386);
|
||||
D(PackMachAMD64);
|
||||
D(PackMachARMEL);
|
||||
|
||||
// 2010-03-12 omit these because PackMachBase<T>::pack4dylib (p_mach.cpp)
|
||||
// does not understand what the Darwin (Apple Mac OS X) dynamic loader
|
||||
// assumes about .dylib file structure.
|
||||
// D(PackDylibI386); if ((p = func(new PackDylibI386(f), user)))
|
||||
// return p;
|
||||
// D(PackDylibPPC32); if ((p = func(new PackDylibPPC32(f), user)))
|
||||
// return p;
|
||||
// D(PackDylibAMD64); if ((p = func(new PackDylibAMD64(f), user)))
|
||||
// return p;
|
||||
// D(PackDylibI386);
|
||||
// D(PackDylibPPC32);
|
||||
// D(PackDylibAMD64);
|
||||
|
||||
return NULL;
|
||||
#undef D
|
||||
}
|
||||
|
||||
|
||||
Packer *PackMaster::getPacker(InputFile *f)
|
||||
{
|
||||
Packer *PackMaster::getPacker(InputFile *f) {
|
||||
Packer *pp = visitAllPackers(try_pack, f, opt, f);
|
||||
if (!pp)
|
||||
throwUnknownExecutableFormat();
|
||||
@ -298,9 +240,7 @@ Packer *PackMaster::getPacker(InputFile *f)
|
||||
return pp;
|
||||
}
|
||||
|
||||
|
||||
Packer *PackMaster::getUnpacker(InputFile *f)
|
||||
{
|
||||
Packer *PackMaster::getUnpacker(InputFile *f) {
|
||||
Packer *pp = visitAllPackers(try_unpack, f, opt, f);
|
||||
if (!pp)
|
||||
throwNotPacked();
|
||||
@ -308,51 +248,41 @@ Packer *PackMaster::getUnpacker(InputFile *f)
|
||||
return pp;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// delegation
|
||||
**************************************************************************/
|
||||
|
||||
void PackMaster::pack(OutputFile *fo)
|
||||
{
|
||||
void PackMaster::pack(OutputFile *fo) {
|
||||
p = getPacker(fi);
|
||||
fi = NULL;
|
||||
p->doPack(fo);
|
||||
}
|
||||
|
||||
|
||||
void PackMaster::unpack(OutputFile *fo)
|
||||
{
|
||||
void PackMaster::unpack(OutputFile *fo) {
|
||||
p = getUnpacker(fi);
|
||||
p->assertPacker();
|
||||
fi = NULL;
|
||||
p->doUnpack(fo);
|
||||
}
|
||||
|
||||
|
||||
void PackMaster::test()
|
||||
{
|
||||
void PackMaster::test() {
|
||||
p = getUnpacker(fi);
|
||||
fi = NULL;
|
||||
p->doTest();
|
||||
}
|
||||
|
||||
|
||||
void PackMaster::list()
|
||||
{
|
||||
void PackMaster::list() {
|
||||
p = getUnpacker(fi);
|
||||
fi = NULL;
|
||||
p->doList();
|
||||
}
|
||||
|
||||
|
||||
void PackMaster::fileInfo()
|
||||
{
|
||||
void PackMaster::fileInfo() {
|
||||
p = visitAllPackers(try_unpack, fi, opt, fi);
|
||||
if (!p)
|
||||
p = visitAllPackers(try_pack, fi, opt, fi);
|
||||
if (!p)
|
||||
throwUnknownExecutableFormat(NULL, 1); // make a warning here
|
||||
throwUnknownExecutableFormat(NULL, 1); // make a warning here
|
||||
p->assertPacker();
|
||||
fi = NULL;
|
||||
p->doFileInfo();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user