From 6bd9805bcc36c0ae54f67e45636dd0c00983cc77 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Sun, 9 Jul 2006 08:14:04 -0700 Subject: [PATCH] start converting PackLinuxElf64amd to ElfLinker --- src/linker.cpp | 28 +++ src/linker.h | 10 + src/p_lx_elf.cpp | 12 +- src/p_lx_elf.h | 2 + src/stub/Makefile | 10 +- src/stub/amd64-linux.elf-entry.h | 246 +++++++++++++++++----- src/stub/src/amd64-linux.elf-entry.asm | 273 +++++++++++++++++++++++++ 7 files changed, 527 insertions(+), 54 deletions(-) create mode 100644 src/stub/src/amd64-linux.elf-entry.asm diff --git a/src/linker.cpp b/src/linker.cpp index 9d62bdae..0b377caf 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -675,6 +675,11 @@ void ElfLinkerX86::align(unsigned len) alignWithByte(len, 0x90); } +void ElfLinkerAMD64::align(unsigned len) +{ + alignWithByte(len, 0x90); +} + void ElfLinkerX86::relocate1(Relocation *rel, upx_byte *location, unsigned value, const char *type) { @@ -698,6 +703,29 @@ void ElfLinkerX86::relocate1(Relocation *rel, upx_byte *location, super::relocate1(rel, location, value, type); } +void ElfLinkerAMD64::relocate1(Relocation *rel, upx_byte *location, + unsigned value, const char *type) +{ + if (strncmp(type, "R_X86_64_", 9)) + return super::relocate1(rel, location, value, type); + type += 9; + + if (strncmp(type, "PC", 2) == 0) + { + value -= rel->section->offset + rel->offset; + type += 2; + } + + if (strcmp(type, "8") == 0) + *location += value; + else if (strcmp(type, "16") == 0) + set_le16(location, get_le16(location) + value); + else if (strcmp(type, "32") == 0) + set_le32(location, get_le32(location) + value); + else + super::relocate1(rel, location, value, type); +} + void ElfLinkerArmLE::relocate1(Relocation *rel, upx_byte *location, unsigned value, const char *type) { diff --git a/src/linker.h b/src/linker.h index d1c9e975..111e92ca 100644 --- a/src/linker.h +++ b/src/linker.h @@ -258,6 +258,16 @@ protected: unsigned value, const char *type); }; +class ElfLinkerAMD64 : public ElfLinker +{ + typedef ElfLinker super; + +protected: + virtual void align(unsigned len); + virtual void relocate1(Relocation *, upx_byte *location, + unsigned value, const char *type); +}; + class ElfLinkerArmLE : public ElfLinker { typedef ElfLinker super; diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index e5c23543..b151442c 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -148,11 +148,21 @@ PackLinuxElf::PackLinuxElf(InputFile *f) sz_phdrs(0), sz_elf_hdrs(0), e_machine(0), ei_class(0), ei_data(0), ei_osabi(0) { - delete[] file_image; +} + +Linker *PackLinuxElf::newLinker() const +{ + return new ElfLinker; } PackLinuxElf::~PackLinuxElf() { + delete[] file_image; +} + +Linker* PackLinuxElf64amd::newLinker() const +{ + return new ElfLinkerAMD64; } PackLinuxElf32::PackLinuxElf32(InputFile *f) diff --git a/src/p_lx_elf.h b/src/p_lx_elf.h index 8bd333b6..bbb6e034 100644 --- a/src/p_lx_elf.h +++ b/src/p_lx_elf.h @@ -41,6 +41,7 @@ public: PackLinuxElf(InputFile *f); virtual ~PackLinuxElf(); /*virtual int buildLoader(const Filter *);*/ + virtual Linker* newLinker() const; virtual bool canUnpackVersion(int version) const { return (version >= 11); } protected: @@ -285,6 +286,7 @@ protected: virtual void pack3(OutputFile *, Filter &); // append loader virtual const int *getCompressionMethods(int method, int level) const; virtual int buildLoader(const Filter *); + virtual Linker* newLinker() const; }; /************************************************************************* diff --git a/src/stub/Makefile b/src/stub/Makefile index 61fbdfa0..99f0c550 100644 --- a/src/stub/Makefile +++ b/src/stub/Makefile @@ -186,10 +186,12 @@ tc.amd64-linux.elf.objcopy = $(call tc,m-objcopy) tc.amd64-linux.elf.objdump = $(call tc,m-objdump) tc.amd64-linux.elf.objstrip = $(call tc,objcopy) -R .comment -R .note -amd64-linux.elf-entry.h : $(srcdir)/src/$$T.S - $(call tc,gcc) -c $< -o tmp/$T.o - $(call tc,objstrip) tmp/$T.o - $(call tc,ld) --oformat binary tmp/$T.o -o tmp/$T.bin +amd64-linux.elf-entry.h: $(srcdir)/src/$$T.asm + $(call tc,gcc) -c -x assembler-with-cpp $< -o tmp/$T.bin + $(call tc,m-objcopy) --strip-unneeded tmp/$T.bin + $(call tc,m-objcopy) -R .text -R .data -R .bss tmp/$T.bin + $(call tc,m-objcopy) -R .note -R .comment tmp/$T.bin + $(call tc,m-objdump) -trwh tmp/$T.bin >> tmp/$T.bin $(call tc,bin2h) --ident=linux_elf64amd_loader tmp/$T.bin $@ amd64-linux.elf-fold.h : tmp/$$T.o tmp/amd64-linux.elf-main.o $(srcdir)/src/$$T.lds diff --git a/src/stub/amd64-linux.elf-entry.h b/src/stub/amd64-linux.elf-entry.h index 921c66f6..02f88d18 100644 --- a/src/stub/amd64-linux.elf-entry.h +++ b/src/stub/amd64-linux.elf-entry.h @@ -1,4 +1,4 @@ -/* amd64-linux.elf-entry.h -- created from amd64-linux.elf-entry.bin, 701 (0x2bd) bytes +/* amd64-linux.elf-entry.h -- created from amd64-linux.elf-entry.bin, 3066 (0xbfa) bytes This file is part of the UPX executable compressor. @@ -27,53 +27,201 @@ */ -#define LINUX_ELF64AMD_LOADER_SIZE 701 -#define LINUX_ELF64AMD_LOADER_ADLER32 0xf7af3eba -#define LINUX_ELF64AMD_LOADER_CRC32 0x8ec9e668 +#define LINUX_ELF64AMD_LOADER_SIZE 3066 +#define LINUX_ELF64AMD_LOADER_ADLER32 0x7a3e6996 +#define LINUX_ELF64AMD_LOADER_CRC32 0x5bbfae22 -unsigned char linux_elf64amd_loader[701] = { -232,178, 2, 0, 0, 85, 83, 81, 82, 72, 1,254, 86, 72,137,254, /* 0x 0 */ - 72,137,215, 49,219, 49,201, 72,131,205,255,232,129, 1, 0, 0, /* 0x 10 */ - 1,219,116, 2,243,195,139, 30, 72,131,238,252, 17,219,138, 22, /* 0x 20 */ -243,195, 72,141, 4, 47,131,249, 5,138, 16,118, 33, 72,131,253, /* 0x 30 */ -252,119, 27,131,233, 4,139, 16, 72,131,192, 4,131,233, 4,137, /* 0x 40 */ - 23, 72,141,127, 4,115,239,131,193, 4,138, 16,116, 16, 72,255, /* 0x 50 */ -192,136, 23,131,233, 1,138, 16, 72,141,127, 1,117,240,243,195, /* 0x 60 */ - 72,255,198,136, 23, 72,255,199,138, 22, 1,219,117, 10,139, 30, /* 0x 70 */ - 72,131,238,252, 17,219,138, 22,114,230,141, 65, 1,235, 7,255, /* 0x 80 */ -200, 65,255,211, 17,192, 65,255,211, 17,192, 1,219,117, 10,139, /* 0x 90 */ - 30, 72,131,238,252, 17,219,138, 22,115,228,131,232, 3,114, 29, /* 0x a0 */ -193,224, 8, 15,182,210, 9,208, 72,255,198,131,240,255, 15,132, /* 0x b0 */ -244, 0, 0, 0,209,248, 72, 99,232,114, 56,235, 14, 1,219,117, /* 0x c0 */ - 8,139, 30, 72,131,238,252, 17,219,114, 40,255,193, 1,219,117, /* 0x d0 */ - 8,139, 30, 72,131,238,252, 17,219,114, 24, 65,255,211, 17,201, /* 0x e0 */ - 1,219,117, 8,139, 30, 72,131,238,252, 17,219,115,237,131,193, /* 0x f0 */ - 2,235, 5, 65,255,211, 17,201, 72,129,253, 0,251,255,255,131, /* 0x 100 */ -209, 2,232, 27,255,255,255,233, 92,255,255,255,102,102,102,144, /* 0x 110 */ - 72,255,198,136, 23, 72,255,199,138, 22, 1,219,117, 10,139, 30, /* 0x 120 */ - 72,131,238,252, 17,219,138, 22,114,230,141, 65, 1, 65,255,211, /* 0x 130 */ - 17,192, 1,219,117, 10,139, 30, 72,131,238,252, 17,219,138, 22, /* 0x 140 */ -115,235,131,232, 3,114, 19,193,224, 8, 15,182,210, 9,208, 72, /* 0x 150 */ -255,198,131,240,255,116, 81, 72, 99,232,141, 65, 1, 65,255,211, /* 0x 160 */ - 17,201, 65,255,211, 17,201,117, 24,137,193,131,192, 2, 65,255, /* 0x 170 */ -211, 17,201, 1,219,117, 8,139, 30, 72,131,238,252, 17,219,115, /* 0x 180 */ -237, 72,129,253, 0,243,255,255, 17,193,232,147,254,255,255,235, /* 0x 190 */ -135,252, 65, 91, 65,131,248, 8, 15,132,202,254,255,255, 65,131, /* 0x 1a0 */ -248, 2, 15,132,112,255,255,255, 89, 72,137,240, 72, 41,200, 90, /* 0x 1b0 */ - 72, 41,215, 89,137, 57, 91, 93,195, 10, 36, 73,100, 58, 32, 85, /* 0x 1c0 */ - 80, 88, 32, 40, 67, 41, 32, 49, 57, 57, 54, 45, 50, 48, 48, 54, /* 0x 1d0 */ - 32,116,104,101, 32, 85, 80, 88, 32, 84,101, 97,109, 46, 32, 65, /* 0x 1e0 */ -108,108, 32, 82,105,103,104,116,115, 32, 82,101,115,101,114,118, /* 0x 1f0 */ -101,100, 46, 32,104,116,116,112, 58, 47, 47,117,112,120, 46,115, /* 0x 200 */ -102, 46,110,101,116, 32, 36, 10, 0,104, 30, 0, 0, 0, 90,232, /* 0x 210 */ - 30, 0, 0, 0, 80, 82, 79, 84, 95, 69, 88, 69, 67,124, 80, 82, /* 0x 220 */ - 79, 84, 95, 87, 82, 73, 84, 69, 32,102, 97,105,108,101,100, 46, /* 0x 230 */ - 10, 0, 94,106, 2, 95,106, 1, 88, 15, 5,106,127, 95,106, 60, /* 0x 240 */ - 88, 15, 5, 91,191, 65, 68, 82, 77,106, 7, 90,190, 76, 69, 78, /* 0x 250 */ - 77,106, 50, 65, 90, 69, 41,192,106, 9, 88, 15, 5, 57,199,117, /* 0x 260 */ -168,104, 74, 77, 80, 85,104, 65, 68, 82, 85,190, 65, 68, 82, 67, /* 0x 270 */ -104, 76, 69, 78, 85,185, 67, 78, 84, 67,104, 65, 68, 82, 88,104, /* 0x 280 */ - 76, 69, 78, 88,137,250, 41,242, 1,213, 1,211,252,243, 72,165, /* 0x 290 */ -151,137,222, 80,146,173, 80, 72,137,225,173,151,173, 68, 15,182, /* 0x 2a0 */ -192,135,254,255,213, 89,195, 93,232,150,255,255,255 /* 0x 2b0 */ +unsigned char linux_elf64amd_loader[3066] = { +127, 69, 76, 70, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 0 */ + 1, 0, 62, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 10 */ + 0, 0, 0, 0, 0, 0, 0, 0, 40, 3, 0, 0, 0, 0, 0, 0, /* 0x 20 */ + 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 64, 0, 6, 0, 3, 0, /* 0x 30 */ +232,178, 2, 0, 0, 85, 83, 81, 82, 72, 1,254, 86, 72,137,254, /* 0x 40 */ + 72,137,215, 49,219, 49,201, 72,131,205,255,232,129, 1, 0, 0, /* 0x 50 */ + 1,219,116, 2,243,195,139, 30, 72,131,238,252, 17,219,138, 22, /* 0x 60 */ +243,195, 72,141, 4, 47,131,249, 5,138, 16,118, 33, 72,131,253, /* 0x 70 */ +252,119, 27,131,233, 4,139, 16, 72,131,192, 4,131,233, 4,137, /* 0x 80 */ + 23, 72,141,127, 4,115,239,131,193, 4,138, 16,116, 16, 72,255, /* 0x 90 */ +192,136, 23,131,233, 1,138, 16, 72,141,127, 1,117,240,243,195, /* 0x a0 */ + 72,255,198,136, 23, 72,255,199,138, 22, 1,219,117, 10,139, 30, /* 0x b0 */ + 72,131,238,252, 17,219,138, 22,114,230,141, 65, 1,235, 7,255, /* 0x c0 */ +200, 65,255,211, 17,192, 65,255,211, 17,192, 1,219,117, 10,139, /* 0x d0 */ + 30, 72,131,238,252, 17,219,138, 22,115,228,131,232, 3,114, 29, /* 0x e0 */ +193,224, 8, 15,182,210, 9,208, 72,255,198,131,240,255, 15,132, /* 0x f0 */ +244, 0, 0, 0,209,248, 72, 99,232,114, 56,235, 14, 1,219,117, /* 0x 100 */ + 8,139, 30, 72,131,238,252, 17,219,114, 40,255,193, 1,219,117, /* 0x 110 */ + 8,139, 30, 72,131,238,252, 17,219,114, 24, 65,255,211, 17,201, /* 0x 120 */ + 1,219,117, 8,139, 30, 72,131,238,252, 17,219,115,237,131,193, /* 0x 130 */ + 2,235, 5, 65,255,211, 17,201, 72,129,253, 0,251,255,255,131, /* 0x 140 */ +209, 2,232, 27,255,255,255,233, 92,255,255,255, 0, 0, 0, 0, /* 0x 150 */ + 72,255,198,136, 23, 72,255,199,138, 22, 1,219,117, 10,139, 30, /* 0x 160 */ + 72,131,238,252, 17,219,138, 22,114,230,141, 65, 1, 65,255,211, /* 0x 170 */ + 17,192, 1,219,117, 10,139, 30, 72,131,238,252, 17,219,138, 22, /* 0x 180 */ +115,235,131,232, 3,114, 19,193,224, 8, 15,182,210, 9,208, 72, /* 0x 190 */ +255,198,131,240,255,116, 81, 72, 99,232,141, 65, 1, 65,255,211, /* 0x 1a0 */ + 17,201, 65,255,211, 17,201,117, 24,137,193,131,192, 2, 65,255, /* 0x 1b0 */ +211, 17,201, 1,219,117, 8,139, 30, 72,131,238,252, 17,219,115, /* 0x 1c0 */ +237, 72,129,253, 0,243,255,255, 17,193,232,147,254,255,255,235, /* 0x 1d0 */ +135,252, 65, 91, 65,131,248, 8, 15,132,202,254,255,255, 65,131, /* 0x 1e0 */ +248, 2, 15,132,112,255,255,255, 89, 72,137,240, 72, 41,200, 90, /* 0x 1f0 */ + 72, 41,215, 89,137, 57, 91, 93,195, 10, 36, 73,100, 58, 32, 85, /* 0x 200 */ + 80, 88, 32, 40, 67, 41, 32, 49, 57, 57, 54, 45, 50, 48, 48, 54, /* 0x 210 */ + 32,116,104,101, 32, 85, 80, 88, 32, 84,101, 97,109, 46, 32, 65, /* 0x 220 */ +108,108, 32, 82,105,103,104,116,115, 32, 82,101,115,101,114,118, /* 0x 230 */ +101,100, 46, 32,104,116,116,112, 58, 47, 47,117,112,120, 46,115, /* 0x 240 */ +102, 46,110,101,116, 32, 36, 10, 0,104, 30, 0, 0, 0, 90,232, /* 0x 250 */ + 30, 0, 0, 0, 80, 82, 79, 84, 95, 69, 88, 69, 67,124, 80, 82, /* 0x 260 */ + 79, 84, 95, 87, 82, 73, 84, 69, 32,102, 97,105,108,101,100, 46, /* 0x 270 */ + 10, 0, 94,106, 2, 95,106, 1, 88, 15, 5,106,127, 95,106, 60, /* 0x 280 */ + 88, 15, 5, 91,191, 0, 0, 0, 0,106, 7, 90,190, 0, 0, 0, /* 0x 290 */ + 0,106, 50, 65, 90, 69, 41,192,106, 9, 88, 15, 5, 57,199,117, /* 0x 2a0 */ +168,104, 0, 0, 0, 0,104, 0, 0, 0, 0,190, 0, 0, 0, 0, /* 0x 2b0 */ +104, 0, 0, 0, 0,185, 0, 0, 0, 0,104, 0, 0, 0, 0,104, /* 0x 2c0 */ + 0, 0, 0, 0,137,250, 41,242, 1,213, 1,211,252,243, 72,165, /* 0x 2d0 */ +151,137,222, 80,146,173, 80, 72,137,225,173,151,173, 68, 15,182, /* 0x 2e0 */ +192,135,254,255,213, 89,195, 93,232,150,255,255,255, 0, 46,115, /* 0x 2f0 */ +121,109,116, 97, 98, 0, 46,115,116,114,116, 97, 98, 0, 46,115, /* 0x 300 */ +104,115,116,114,116, 97, 98, 0, 46,114,101,108, 97, 76, 69, 88, /* 0x 310 */ + 69, 67, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 320 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 330 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 340 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 350 */ + 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, /* 0x 360 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 370 */ + 64, 0, 0, 0, 0, 0, 0, 0,189, 2, 0, 0, 0, 0, 0, 0, /* 0x 380 */ + 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, /* 0x 390 */ + 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 4, 0, 0, 0, /* 0x 3a0 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 3b0 */ + 0, 6, 0, 0, 0, 0, 0, 0,216, 0, 0, 0, 0, 0, 0, 0, /* 0x 3c0 */ + 4, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, /* 0x 3d0 */ + 24, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 3, 0, 0, 0, /* 0x 3e0 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 3f0 */ +253, 2, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, /* 0x 400 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, /* 0x 410 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, /* 0x 420 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 430 */ +168, 4, 0, 0, 0, 0, 0, 0, 32, 1, 0, 0, 0, 0, 0, 0, /* 0x 440 */ + 5, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, /* 0x 450 */ + 24, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, /* 0x 460 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 470 */ +200, 5, 0, 0, 0, 0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, /* 0x 480 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, /* 0x 490 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 4a0 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 4b0 */ + 0, 0, 0, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 4c0 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 16, 0, 1, 0, /* 0x 4d0 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 4e0 */ + 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 4f0 */ + 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 16, 0, 0, 0, /* 0x 500 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 510 */ + 18, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 520 */ + 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 16, 0, 0, 0, /* 0x 530 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 540 */ + 28, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 550 */ + 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 16, 0, 0, 0, /* 0x 560 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 570 */ + 38, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 580 */ + 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 16, 0, 0, 0, /* 0x 590 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 5a0 */ + 48, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 5b0 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 95,115,116, 97,114,116, 0, /* 0x 5c0 */ + 65, 68, 82, 77, 0, 76, 69, 78, 77, 0, 74, 77, 80, 85, 0, 65, /* 0x 5d0 */ + 68, 82, 85, 0, 65, 68, 82, 67, 0, 76, 69, 78, 85, 0, 67, 78, /* 0x 5e0 */ + 84, 67, 0, 65, 68, 82, 88, 0, 76, 69, 78, 88, 0, 0, 0, 0, /* 0x 5f0 */ + 85, 2, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 3, 0, 0, 0, /* 0x 600 */ + 0, 0, 0, 0, 0, 0, 0, 0, 93, 2, 0, 0, 0, 0, 0, 0, /* 0x 610 */ + 10, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 620 */ +114, 2, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, /* 0x 630 */ + 0, 0, 0, 0, 0, 0, 0, 0,119, 2, 0, 0, 0, 0, 0, 0, /* 0x 640 */ + 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 650 */ +124, 2, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 7, 0, 0, 0, /* 0x 660 */ + 0, 0, 0, 0, 0, 0, 0, 0,129, 2, 0, 0, 0, 0, 0, 0, /* 0x 670 */ + 10, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 680 */ +134, 2, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, /* 0x 690 */ + 0, 0, 0, 0, 0, 0, 0, 0,139, 2, 0, 0, 0, 0, 0, 0, /* 0x 6a0 */ + 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x 6b0 */ +144, 2, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, /* 0x 6c0 */ + 0, 0, 0, 0, 0, 0, 0, 0, 10,116,109,112, 47, 97,109,100, /* 0x 6d0 */ + 54, 52, 45,108,105,110,117,120, 46,101,108,102, 45,101,110,116, /* 0x 6e0 */ +114,121, 46, 98,105,110, 58, 32, 32, 32, 32, 32,102,105,108,101, /* 0x 6f0 */ + 32,102,111,114,109, 97,116, 32,101,108,102, 54, 52, 45,120, 56, /* 0x 700 */ + 54, 45, 54, 52, 10, 10, 83,101, 99,116,105,111,110,115, 58, 10, /* 0x 710 */ + 73,100,120, 32, 78, 97,109,101, 32, 32, 32, 32, 32, 32, 32, 32, /* 0x 720 */ + 32, 32, 83,105,122,101, 32, 32, 32, 32, 32, 32, 86, 77, 65, 32, /* 0x 730 */ + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 76, 77, /* 0x 740 */ + 65, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, /* 0x 750 */ + 70,105,108,101, 32,111,102,102, 32, 32, 65,108,103,110, 32, 32, /* 0x 760 */ + 70,108, 97,103,115, 10, 32, 32, 48, 32, 76, 69, 88, 69, 67, 48, /* 0x 770 */ + 48, 48, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48, 48, 50, 98,100, /* 0x 780 */ + 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, /* 0x 790 */ + 48, 48, 32, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, /* 0x 7a0 */ + 48, 48, 48, 48, 32, 32, 48, 48, 48, 48, 48, 48, 52, 48, 32, 32, /* 0x 7b0 */ + 50, 42, 42, 51, 32, 32, 67, 79, 78, 84, 69, 78, 84, 83, 44, 32, /* 0x 7c0 */ + 82, 69, 76, 79, 67, 44, 32, 82, 69, 65, 68, 79, 78, 76, 89, 10, /* 0x 7d0 */ + 83, 89, 77, 66, 79, 76, 32, 84, 65, 66, 76, 69, 58, 10, 48, 48, /* 0x 7e0 */ + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32,108, /* 0x 7f0 */ + 32, 32, 32, 32,100, 32, 32, 76, 69, 88, 69, 67, 48, 48, 48, 9, /* 0x 800 */ + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, /* 0x 810 */ + 32, 76, 69, 88, 69, 67, 48, 48, 48, 10, 48, 48, 48, 48, 48, 48, /* 0x 820 */ + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32,103, 32, 32, 32, 32, /* 0x 830 */ + 32, 32, 32, 76, 69, 88, 69, 67, 48, 48, 48, 9, 48, 48, 48, 48, /* 0x 840 */ + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 95,115,116, /* 0x 850 */ + 97,114,116, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, /* 0x 860 */ + 48, 48, 48, 48, 32, 32, 32, 32, 32, 32, 32, 32, 32, 42, 85, 78, /* 0x 870 */ + 68, 42, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, /* 0x 880 */ + 48, 48, 48, 32, 65, 68, 82, 77, 10, 48, 48, 48, 48, 48, 48, 48, /* 0x 890 */ + 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 32, 32, 32, 32, 32, /* 0x 8a0 */ + 32, 32, 42, 85, 78, 68, 42, 9, 48, 48, 48, 48, 48, 48, 48, 48, /* 0x 8b0 */ + 48, 48, 48, 48, 48, 48, 48, 48, 32, 76, 69, 78, 77, 10, 48, 48, /* 0x 8c0 */ + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, /* 0x 8d0 */ + 32, 32, 32, 32, 32, 32, 32, 42, 85, 78, 68, 42, 9, 48, 48, 48, /* 0x 8e0 */ + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 74, 77, /* 0x 8f0 */ + 80, 85, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, /* 0x 900 */ + 48, 48, 48, 32, 32, 32, 32, 32, 32, 32, 32, 32, 42, 85, 78, 68, /* 0x 910 */ + 42, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, /* 0x 920 */ + 48, 48, 32, 65, 68, 82, 85, 10, 48, 48, 48, 48, 48, 48, 48, 48, /* 0x 930 */ + 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 32, 32, 32, 32, 32, 32, /* 0x 940 */ + 32, 42, 85, 78, 68, 42, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, /* 0x 950 */ + 48, 48, 48, 48, 48, 48, 48, 32, 65, 68, 82, 67, 10, 48, 48, 48, /* 0x 960 */ + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 32, /* 0x 970 */ + 32, 32, 32, 32, 32, 32, 42, 85, 78, 68, 42, 9, 48, 48, 48, 48, /* 0x 980 */ + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 76, 69, 78, /* 0x 990 */ + 85, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, /* 0x 9a0 */ + 48, 48, 32, 32, 32, 32, 32, 32, 32, 32, 32, 42, 85, 78, 68, 42, /* 0x 9b0 */ + 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, /* 0x 9c0 */ + 48, 32, 67, 78, 84, 67, 10, 48, 48, 48, 48, 48, 48, 48, 48, 48, /* 0x 9d0 */ + 48, 48, 48, 48, 48, 48, 48, 32, 32, 32, 32, 32, 32, 32, 32, 32, /* 0x 9e0 */ + 42, 85, 78, 68, 42, 9, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, /* 0x 9f0 */ + 48, 48, 48, 48, 48, 48, 32, 65, 68, 82, 88, 10, 48, 48, 48, 48, /* 0x a00 */ + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 32, 32, 32, /* 0x a10 */ + 32, 32, 32, 32, 32, 42, 85, 78, 68, 42, 9, 48, 48, 48, 48, 48, /* 0x a20 */ + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 32, 76, 69, 78, 88, /* 0x a30 */ + 10, 10, 10, 82, 69, 76, 79, 67, 65, 84, 73, 79, 78, 32, 82, 69, /* 0x a40 */ + 67, 79, 82, 68, 83, 32, 70, 79, 82, 32, 91, 76, 69, 88, 69, 67, /* 0x a50 */ + 48, 48, 48, 93, 58, 10, 79, 70, 70, 83, 69, 84, 32, 32, 32, 32, /* 0x a60 */ + 32, 32, 32, 32, 32, 32, 32, 84, 89, 80, 69, 32, 32, 32, 32, 32, /* 0x a70 */ + 32, 32, 32, 32, 32, 32, 32, 32, 32, 86, 65, 76, 85, 69, 32, 10, /* 0x a80 */ + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 50, 53, 53, /* 0x a90 */ + 32, 82, 95, 88, 56, 54, 95, 54, 52, 95, 51, 50, 32, 32, 32, 32, /* 0x aa0 */ + 32, 32, 32, 65, 68, 82, 77, 10, 48, 48, 48, 48, 48, 48, 48, 48, /* 0x ab0 */ + 48, 48, 48, 48, 48, 50, 53,100, 32, 82, 95, 88, 56, 54, 95, 54, /* 0x ac0 */ + 52, 95, 51, 50, 32, 32, 32, 32, 32, 32, 32, 76, 69, 78, 77, 10, /* 0x ad0 */ + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 50, 55, 50, /* 0x ae0 */ + 32, 82, 95, 88, 56, 54, 95, 54, 52, 95, 51, 50, 32, 32, 32, 32, /* 0x af0 */ + 32, 32, 32, 74, 77, 80, 85, 10, 48, 48, 48, 48, 48, 48, 48, 48, /* 0x b00 */ + 48, 48, 48, 48, 48, 50, 55, 55, 32, 82, 95, 88, 56, 54, 95, 54, /* 0x b10 */ + 52, 95, 51, 50, 32, 32, 32, 32, 32, 32, 32, 65, 68, 82, 85, 10, /* 0x b20 */ + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 50, 55, 99, /* 0x b30 */ + 32, 82, 95, 88, 56, 54, 95, 54, 52, 95, 51, 50, 32, 32, 32, 32, /* 0x b40 */ + 32, 32, 32, 65, 68, 82, 67, 10, 48, 48, 48, 48, 48, 48, 48, 48, /* 0x b50 */ + 48, 48, 48, 48, 48, 50, 56, 49, 32, 82, 95, 88, 56, 54, 95, 54, /* 0x b60 */ + 52, 95, 51, 50, 32, 32, 32, 32, 32, 32, 32, 76, 69, 78, 85, 10, /* 0x b70 */ + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 50, 56, 54, /* 0x b80 */ + 32, 82, 95, 88, 56, 54, 95, 54, 52, 95, 51, 50, 32, 32, 32, 32, /* 0x b90 */ + 32, 32, 32, 67, 78, 84, 67, 10, 48, 48, 48, 48, 48, 48, 48, 48, /* 0x ba0 */ + 48, 48, 48, 48, 48, 50, 56, 98, 32, 82, 95, 88, 56, 54, 95, 54, /* 0x bb0 */ + 52, 95, 51, 50, 32, 32, 32, 32, 32, 32, 32, 65, 68, 82, 88, 10, /* 0x bc0 */ + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 50, 57, 48, /* 0x bd0 */ + 32, 82, 95, 88, 56, 54, 95, 54, 52, 95, 51, 50, 32, 32, 32, 32, /* 0x be0 */ + 32, 32, 32, 76, 69, 78, 88, 10, 10, 10 /* 0x bf0 */ }; diff --git a/src/stub/src/amd64-linux.elf-entry.asm b/src/stub/src/amd64-linux.elf-entry.asm new file mode 100644 index 00000000..010a7187 --- /dev/null +++ b/src/stub/src/amd64-linux.elf-entry.asm @@ -0,0 +1,273 @@ +/* l_lx_elf64amd.asm -- Linux program entry point & decompressor (Elf binary) +* +* This file is part of the UPX executable compressor. +* +* Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer +* Copyright (C) 1996-2006 Laszlo Molnar +* Copyright (C) 2000-2006 John F. Reiser +* All Rights Reserved. +* +* UPX and the UCL library are free software; you can redistribute them +* and/or modify them under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 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 General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; see the file COPYING. +* If not, write to the Free Software Foundation, Inc., +* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* Markus F.X.J. Oberhumer Laszlo Molnar +* +* +* John F. Reiser +* +*/ + +//#include "arch/i386/macros2.ash" + +#include "arch/amd64/regs.h" + +sz_l_info= 12 + l_lsize= 8 + +sz_p_info= 12 + +sz_b_info= 12 + sz_unc= 0 + sz_cpr= 4 + b_method= 8 + +PROT_READ= 1 +PROT_WRITE= 2 +PROT_EXEC= 4 + +MAP_PRIVATE= 2 +MAP_FIXED= 0x10 +MAP_ANONYMOUS= 0x20 + +SYS_mmap= 9 // 64-bit mode only! + +PAGE_SHIFT= 12 +PAGE_MASK= (~0<likely, n==>unlikely} */ +/* Prediction omitted for now. */ +/* On refill: prefetch next byte, for latency reduction on literals and offsets. */ +#define jnextb0np jnextb0yp +#define jnextb0yp GETBITp; jnc +#define jnextb1np jnextb1yp +#define jnextb1yp GETBITp; jc +#define GETBITp \ + addl bits,bits; jnz 0f; \ + movl (%rsi),bits; subq $-4,%rsi; \ + adcl bits,bits; movb (%rsi),%dl; \ +0: +/* Same, but without prefetch (not useful for length of match.) */ +#define jnextb0n jnextb0y +#define jnextb0y GETBIT; jnc +#define jnextb1n jnextb1y +#define jnextb1y GETBIT; jc +#define GETBIT \ + addl bits,bits; jnz 0f; \ + movl (%rsi),bits; subq $-4,%rsi; \ + adcl bits,bits; \ +0: + +/* rotate next bit into bottom bit of reg */ +#define getnextbp(reg) call *%r11; adcl reg,reg +#define getnextb(reg) getnextbp(reg) + + .p2align 3 +getbit: + addl bits,bits; jz refill // Carry= next bit + rep; ret +refill: + movl (%rsi),bits; subq $-4,%rsi // next 32 bits; set Carry + adcl bits,bits // LSB= 1 (CarryIn); CarryOut= next bit + movb (%rsi),%dl // speculate: literal, or bottom 8 bits of offset + rep; ret + +copy: // In: len, %rdi, disp; Out: 0==len, %rdi, disp; trashes %rax, %rdx + leaq (%rdi,disp),%rax; cmpl $5,len // <=3 is forced + movb (%rax),%dl; jbe copy1 // <=5 for better branch predict + cmpq $-4,disp; ja copy1 // 4-byte chunks would overlap + subl $4,len // adjust for termination cases +copy4: + movl (%rax),%edx; addq $4, %rax; subl $4,len + movl %edx,(%rdi); leaq 4(%rdi),%rdi; jnc copy4 + addl $4,len; movb (%rax),%dl; jz copy0 +copy1: + incq %rax; movb %dl,(%rdi); subl $1,len + movb (%rax),%dl + leaq 1(%rdi),%rdi; jnz copy1 +copy0: + rep; ret + +#include "arch/amd64/nrv2e_d.S" +#include "arch/amd64/nrv2b_d.S" + +setup: + cld + pop %r11 // addq $ getbit - ra_setup,%r11 # &getbit + cmpl $ M_NRV2E_LE32,meth; je top_n2e + cmpl $ M_NRV2B_LE32,meth; je top_n2b +eof: + pop %rcx // &input_eof + movq %rsi,%rax; subq %rcx,%rax // src -= eof; // return 0: good; else: bad + pop %rdx; subq %rdx,%rdi // dst -= original dst + pop %rcx; movl %edi,(%rcx) // actual length used at dst XXX: 4GB + pop %rbx; pop %rbp + ret + +/* Temporary until we get the buildLoader stuff working ... */ + .ascii "\n$Id: UPX (C) 1996-2006 the UPX Team. " + .asciz "All Rights Reserved. http://upx.sf.net $\n" + +/* These from /usr/include/asm-x86_64/unistd.h */ +__NR_write = 1 +__NR_exit = 60 + +msg_SELinux: + push $ L71 - L70; pop %arg3 // length + call L71 +L70: + .asciz "PROT_EXEC|PROT_WRITE failed.\n" +L71: + pop %arg2 // message text + push $2; pop %arg1 // fd stderr + push $ __NR_write; pop %rax + syscall +die: + push $127; pop %arg1 + push $ __NR_exit; pop %rax + syscall + +/* Decompress the rest of this loader, and jump to it. + Map a page to hold the decompressed bytes. Logically this could + be done by setting .p_memsz for our first PT_LOAD. But as of 2005-11-09, + linux 2.6.14 only does ".bss expansion" on the PT_LOAD that describes the + highest address. [I regard this as a bug, and it makes the kernel's + fs/binfmt_elf.c complicated, buggy, and insecure.] For us, that is the 2nd + PT_LOAD, which is the only way that linux allows to set the brk() for the + uncompressed program. [This is a significant kernel misfeature.] +*/ +unfold: + pop %rbx // &b_info + +/* Get some pages. If small, then get 1 page located just after the end + of the first PT_LOAD of the compressed program. This will still be below + all of the uncompressed program. If large (>=3MB compressed), then get enough + to duplicate the entire compressed PT_LOAD, plus 1 page, located just after + the brk() of the _un_compressed program. The address and length are pre- + calculated by PackLinuxElf64amd::pack3(), and patched in at compress time. +*/ + movl $ ADRM,%edi // XXX: 4GB + push $ PROT_READ | PROT_WRITE | PROT_EXEC; pop %arg3 + movl $ LENM,%esi // XXX: 4GB + push $ MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS; pop %sys4 + subl %arg5l,%arg5l //; subl %arg6l,%arg6l // MAP_ANON ==> ignore offset + push $ SYS_mmap; pop %rax + syscall // %rax= result; trashes %rcx,%r11 only + cmpl %eax,%edi; jne msg_SELinux // XXX: 4GB + +/* Load the addresses and lengths that ::pack3() patched in. + XXX: 2GB Note that PUSH $imm32 sign-extends to 64 bits. + XXX: 4GB Note that MOVL $imm32,reg zero-extends to 64-bits. + (Use an temporary register to obtain 4GB range on PUSH constant.) +*/ + push $ JMPU // for unmap in fold + push $ ADRU // for unmap in fold + movl $ ADRC,%esi + push $ LENU // for unmap in fold + movl $ CNTC,%ecx + push $ ADRX //# for upx_main + push $ LENX // for upx_main + +/* Move and relocate if compressed overlaps uncompressed. + Move by 0 when total compressed executable is < 3MB. +*/ + movl %edi,%edx // ADRM + subl %esi,%edx // (ADRM - ADRC) == relocation amount + addl %edx,%ebp // update &decompress + addl %edx,%ebx // update &b_info + + cld + rep; movsq + xchgl %eax,%edi + +/* Decompress the folded part of this stub, then execute it. */ + movl %ebx,%esi // %arg2l= &b_info (relocated) + push %rax // ret_addr after decompression + xchgl %eax,%arg3l // %arg3= dst for unfolding XXX: 4GB + lodsl; push %rax // allocate slot on stack + movq %rsp,%arg4 // &len_dst ==> &do_not_care + lodsl; xchgl %eax,%arg1l // sz_cpr XXX: 4GB + lodsl; movzbl %al,%arg5l // b_method + xchg %arg1l,%arg2l // XXX: 4GB + call *%rbp // decompress + pop %rcx // discard len_dst + ret + +main: + // int3 # uncomment for debugging + pop %rbp // &decompress + call unfold // push &b_info + /* { b_info={sz_unc, sz_cpr, {4 char}}, folded_loader...} */ + +/*__XTHEENDX__*/ + +/* +vi:ts=8:et:nowrap +*/ +