1 /* p_vmlinx.h -- 2 3 This file is part of the UPX executable compressor. 4 5 Copyright (C) 1996-2020 Markus Franz Xaver Johannes Oberhumer 6 Copyright (C) 1996-2020 Laszlo Molnar 7 All Rights Reserved. 8 9 UPX and the UCL library are free software; you can redistribute them 10 and/or modify them under the terms of the GNU General Public License as 11 published by the Free Software Foundation; either version 2 of 12 the License, or (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; see the file COPYING. 21 If not, write to the Free Software Foundation, Inc., 22 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 24 Markus F.X.J. Oberhumer Laszlo Molnar 25 <markus@oberhumer.com> <ezerotven+github@gmail.com> 26 */ 27 28 29 #ifndef __UPX_P_VMLINX_H 30 #define __UPX_P_VMLINX_H 1 31 32 #include "p_elf.h" 33 34 35 /************************************************************************* 36 // vmlinx/i386 (bare binary Linux kernel image) 37 **************************************************************************/ 38 39 template <class TElfClass> 40 class PackVmlinuxBase : public Packer 41 { 42 typedef Packer super; 43 protected: 44 typedef TElfClass ElfClass; 45 typedef typename ElfClass::BeLePolicy BeLePolicy; 46 typedef typename ElfClass::ElfITypes ElfITypes; 47 // integral types 48 typedef typename ElfClass::TE16 TE16; 49 typedef typename ElfClass::TE32 TE32; 50 typedef typename ElfClass::TE64 TE64; 51 typedef typename ElfITypes::Addr Addr; 52 // ELF types 53 typedef typename ElfClass::Ehdr Ehdr; 54 typedef typename ElfClass::Shdr Shdr; 55 typedef typename ElfClass::Phdr Phdr; 56 typedef typename ElfClass::Dyn Dyn; 57 typedef typename ElfClass::Sym Sym; 58 59 public: 60 PackVmlinuxBase(InputFile *, unsigned, unsigned, unsigned, char const *); 61 virtual ~PackVmlinuxBase(); getVersion()62 virtual int getVersion() const { return 13; } 63 64 protected: 65 unsigned int const my_e_machine; 66 unsigned char const my_elfclass; 67 unsigned char const my_elfdata; 68 char const *const my_boot_label; 69 70 int n_ptload; 71 unsigned sz_ptload; 72 unsigned paddr_min; 73 Phdr *phdri; // from input file 74 Shdr *shdri; // from input file 75 char *shstrtab; // from input file 76 Shdr *p_text; 77 Shdr *p_note0; 78 Shdr *p_note1; 79 Ehdr ehdri; // from input file 80 81 virtual Shdr const *getElfSections(); 82 virtual int getStrategy(Filter &/*ft*/); 83 virtual bool is_valid_e_entry(Addr) = 0; 84 virtual bool has_valid_vmlinux_head() = 0; 85 virtual bool canPack(); 86 virtual void pack(OutputFile *fo); 87 virtual int canUnpack(); // bool, except -1: format known, but not packed 88 virtual void unpack(OutputFile *fo); 89 virtual unsigned write_vmlinux_head( 90 OutputFile *fo, 91 Shdr *stxt 92 ) = 0; 93 static int __acc_cdecl_qsort compare_Phdr(void const *aa, void const *bb); 94 }; 95 96 97 class PackVmlinuxI386 : public PackVmlinuxBase<ElfClass_LE32> 98 { 99 typedef PackVmlinuxBase<ElfClass_LE32> super; 100 public: PackVmlinuxI386(InputFile * f)101 PackVmlinuxI386(InputFile *f) : super(f, Ehdr::EM_386, 102 Ehdr::ELFCLASS32, Ehdr::ELFDATA2LSB, "startup_32") { } getFormat()103 virtual int getFormat() const { return UPX_F_VMLINUX_i386; } getName()104 virtual const char *getName() const { return "vmlinux/i386"; } getFullName(const options_t *)105 virtual const char *getFullName(const options_t *) const { return "i386-linux.kernel.vmlinux"; } 106 virtual const int *getCompressionMethods(int method, int level) const; 107 virtual const int *getFilters() const; 108 109 protected: 110 virtual void buildLoader(const Filter *ft); 111 virtual void defineDecompressorSymbols(); 112 virtual Linker* newLinker() const; 113 virtual bool is_valid_e_entry(Addr); 114 virtual bool has_valid_vmlinux_head(); 115 virtual unsigned write_vmlinux_head( 116 OutputFile *fo, 117 Shdr *stxt 118 ); 119 }; 120 121 122 class PackVmlinuxARMEL : public PackVmlinuxBase<ElfClass_LE32> 123 { 124 typedef PackVmlinuxBase<ElfClass_LE32> super; 125 public: PackVmlinuxARMEL(InputFile * f)126 PackVmlinuxARMEL(InputFile *f) : super(f, Ehdr::EM_ARM, 127 Ehdr::ELFCLASS32, Ehdr::ELFDATA2LSB, "decompress_kernel") { } getFormat()128 virtual int getFormat() const { return UPX_F_VMLINUX_ARMEL; } getName()129 virtual const char *getName() const { return "vmlinux/arm"; } getFullName(const options_t *)130 virtual const char *getFullName(const options_t *) const { return "arm-linux.kernel.vmlinux"; } 131 virtual const int *getCompressionMethods(int method, int level) const; 132 virtual const int *getFilters() const; 133 134 protected: 135 virtual void buildLoader(const Filter *ft); 136 virtual void defineDecompressorSymbols(); 137 virtual Linker* newLinker() const; 138 virtual bool is_valid_e_entry(Addr); 139 virtual bool has_valid_vmlinux_head(); 140 virtual unsigned write_vmlinux_head( 141 OutputFile *fo, 142 Shdr *stxt 143 ); 144 }; 145 146 class PackVmlinuxARMEB : public PackVmlinuxBase<ElfClass_BE32> 147 { 148 typedef PackVmlinuxBase<ElfClass_BE32> super; 149 public: PackVmlinuxARMEB(InputFile * f)150 PackVmlinuxARMEB(InputFile *f) : super(f, Ehdr::EM_ARM, 151 Ehdr::ELFCLASS32, Ehdr::ELFDATA2MSB, "decompress_kernel") { } getFormat()152 virtual int getFormat() const { return UPX_F_VMLINUX_ARMEB; } getName()153 virtual const char *getName() const { return "vmlinux/armeb"; } getFullName(const options_t *)154 virtual const char *getFullName(const options_t *) const { return "armeb-linux.kernel.vmlinux"; } 155 virtual const int *getCompressionMethods(int method, int level) const; 156 virtual const int *getFilters() const; 157 158 protected: 159 virtual void buildLoader(const Filter *ft); 160 virtual void defineDecompressorSymbols(); 161 virtual Linker* newLinker() const; 162 virtual bool is_valid_e_entry(Addr); 163 virtual bool has_valid_vmlinux_head(); 164 virtual unsigned write_vmlinux_head( 165 OutputFile *fo, 166 Shdr *stxt 167 ); 168 }; 169 170 class PackVmlinuxPPC32 : public PackVmlinuxBase<ElfClass_BE32> 171 { 172 typedef PackVmlinuxBase<ElfClass_BE32> super; 173 public: PackVmlinuxPPC32(InputFile * f)174 PackVmlinuxPPC32(InputFile *f) : super(f, Ehdr::EM_PPC, 175 Ehdr::ELFCLASS32, Ehdr::ELFDATA2MSB, "_vmlinux_start") { } getFormat()176 virtual int getFormat() const { return UPX_F_VMLINUX_PPC32; } getName()177 virtual const char *getName() const { return "vmlinux/ppc32"; } getFullName(const options_t *)178 virtual const char *getFullName(const options_t *) const { return "powerpc-linux.kernel.vmlinux"; } 179 virtual const int *getCompressionMethods(int method, int level) const; 180 virtual const int *getFilters() const; 181 182 protected: 183 virtual void buildLoader(const Filter *ft); 184 virtual void defineDecompressorSymbols(); 185 virtual Linker* newLinker() const; 186 virtual bool is_valid_e_entry(Addr); 187 virtual bool has_valid_vmlinux_head(); 188 virtual unsigned write_vmlinux_head( 189 OutputFile *fo, 190 Shdr *stxt 191 ); 192 }; 193 194 class PackVmlinuxPPC64LE : public PackVmlinuxBase<ElfClass_LE64> 195 { 196 typedef PackVmlinuxBase<ElfClass_LE64> super; 197 public: PackVmlinuxPPC64LE(InputFile * f)198 PackVmlinuxPPC64LE(InputFile *f) : super(f, Ehdr::EM_PPC64, 199 Ehdr::ELFCLASS64, Ehdr::ELFDATA2LSB, "_vmlinux_start") { } getFormat()200 virtual int getFormat() const { return UPX_F_VMLINUX_PPC64LE; } getName()201 virtual const char *getName() const { return "vmlinux/ppc64le"; } getFullName(const options_t *)202 virtual const char *getFullName(const options_t *) const { return "powerpc64le-linux.kernel.vmlinux"; } 203 virtual const int *getCompressionMethods(int method, int level) const; 204 virtual const int *getFilters() const; 205 206 protected: 207 virtual void buildLoader(const Filter *ft); 208 virtual void defineDecompressorSymbols(); 209 virtual Linker* newLinker() const; 210 virtual bool is_valid_e_entry(Addr); 211 virtual bool has_valid_vmlinux_head(); 212 virtual unsigned write_vmlinux_head( 213 OutputFile *fo, 214 Shdr *stxt 215 ); 216 }; 217 218 219 class PackVmlinuxAMD64 : public PackVmlinuxBase<ElfClass_LE64> 220 { 221 typedef PackVmlinuxBase<ElfClass_LE64> super; 222 public: PackVmlinuxAMD64(InputFile * f)223 PackVmlinuxAMD64(InputFile *f) : super(f, Ehdr::EM_X86_64, 224 Ehdr::ELFCLASS64, Ehdr::ELFDATA2LSB, "startup_32") { } getFormat()225 virtual int getFormat() const { return UPX_F_VMLINUX_AMD64; } getName()226 virtual const char *getName() const { return "vmlinux/amd64"; } getFullName(const options_t *)227 virtual const char *getFullName(const options_t *) const { return "amd64-linux.kernel.vmlinux"; } 228 virtual const int *getCompressionMethods(int method, int level) const; 229 virtual const int *getFilters() const; 230 231 protected: 232 virtual void buildLoader(const Filter *ft); 233 virtual void defineDecompressorSymbols(); 234 virtual Linker* newLinker() const; 235 virtual bool is_valid_e_entry(Addr); 236 virtual bool has_valid_vmlinux_head(); 237 virtual unsigned write_vmlinux_head( 238 OutputFile *fo, 239 Shdr *stxt 240 ); 241 }; 242 243 244 #endif /* already included */ 245 246 /* vim:set ts=4 sw=4 et: */ 247