mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
PackVmlinuxBase::canPack(); templates are fun!
This commit is contained in:
parent
277d862172
commit
4c068e3e00
327
src/p_vmlinx.cpp
327
src/p_vmlinx.cpp
|
@ -58,6 +58,12 @@ PackVmlinuxBase<T>::~PackVmlinuxBase()
|
|||
delete [] shdri;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int PackVmlinuxBase<T>::is_valid_e_entry(Addr /*e_entry*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int PackVmlinuxBase<T>::getStrategy(Filter &/*ft*/)
|
||||
{
|
||||
|
@ -69,6 +75,21 @@ int PackVmlinuxBase<T>::getStrategy(Filter &/*ft*/)
|
|||
return (opt->no_filter ? -3 : ((opt->filter > 0) ? -2 : 2));
|
||||
};
|
||||
|
||||
template <class T>
|
||||
int __acc_cdecl_qsort
|
||||
PackVmlinuxBase<T>::compare_Phdr(void const *aa, void const *bb)
|
||||
{
|
||||
Phdr const *const a = (Phdr const *)aa;
|
||||
Phdr const *const b = (Phdr const *)bb;
|
||||
unsigned const xa = a->p_type - Phdr::PT_LOAD;
|
||||
unsigned const xb = b->p_type - Phdr::PT_LOAD;
|
||||
if (xa < xb) return -1; // PT_LOAD first
|
||||
if (xa > xb) return 1;
|
||||
if (a->p_paddr < b->p_paddr) return -1; // ascending by .p_paddr
|
||||
if (a->p_paddr > b->p_paddr) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class T::Shdr const *PackVmlinuxBase<T>::getElfSections()
|
||||
{
|
||||
|
@ -94,7 +115,79 @@ class T::Shdr const *PackVmlinuxBase<T>::getElfSections()
|
|||
}
|
||||
}
|
||||
return shstrsec;
|
||||
};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool PackVmlinuxBase<T>::canPack()
|
||||
{
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(&ehdri, sizeof(ehdri));
|
||||
|
||||
// now check the ELF header
|
||||
if (memcmp(&ehdri, "\x7f\x45\x4c\x46", 4)
|
||||
|| ehdri.e_ident[/*EI_CLASS*/ 4]!=my_elfclass
|
||||
|| ehdri.e_ident[/*EI_DATA*/ 5]!=my_elfdata
|
||||
|| ehdri.e_ident[/*EI_VERSION*/ 6]!=1 // EV_CURRENT
|
||||
|| !memcmp(&ehdri.e_ident[8], "FreeBSD", 7) // branded
|
||||
|| ehdri.e_version != 1 // version
|
||||
|| ehdri.e_ehsize != sizeof(ehdri) // different <elf.h> ?
|
||||
|| ehdri.e_phoff != sizeof(ehdri) // Phdrs not contiguous with Ehdr
|
||||
|| ehdri.e_phentsize!=sizeof(Phdr)
|
||||
)
|
||||
return false;
|
||||
|
||||
// additional requirements for vmlinux
|
||||
if (ehdri.e_machine != my_e_machine
|
||||
|| ehdri.e_type!=Ehdr::ET_EXEC
|
||||
|| !is_valid_e_entry(ehdri.e_entry)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// A Linux kernel must have a __ksymtab section. [??]
|
||||
Shdr const *p, *const shstrsec = getElfSections();
|
||||
if (0==shstrsec) {
|
||||
return false;
|
||||
}
|
||||
{
|
||||
int j;
|
||||
for (p = shdri, j= ehdri.e_shnum; --j>=0; ++p) {
|
||||
if (Shdr::SHT_PROGBITS==p->sh_type
|
||||
&& 0==strcmp("__ksymtab", p->sh_name + shstrtab)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j < 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
phdri = new Phdr[(unsigned) ehdri.e_phnum];
|
||||
fi->seek(ehdri.e_phoff, SEEK_SET);
|
||||
fi->readx(phdri, ehdri.e_phnum * sizeof(*phdri));
|
||||
|
||||
// Put PT_LOAD together at the beginning, ascending by .p_paddr.
|
||||
qsort(phdri, ehdri.e_phnum, sizeof(*phdri), compare_Phdr);
|
||||
|
||||
// Check that PT_LOADs form one contiguous chunk of the file.
|
||||
for (unsigned j = 0; j < ehdri.e_phnum; ++j) {
|
||||
if (Phdr::PT_LOAD==phdri[j].p_type) {
|
||||
if (0xfff & (phdri[j].p_offset | phdri[j].p_paddr
|
||||
| phdri[j].p_align | phdri[j].p_vaddr) ) {
|
||||
return false;
|
||||
}
|
||||
if (0 < j) {
|
||||
unsigned const sz = (0u - phdri[j-1].p_align)
|
||||
& (phdri[j-1].p_align -1 + phdri[j-1].p_filesz);
|
||||
if ((sz + phdri[j-1].p_offset)!=phdri[j].p_offset) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
++n_ptload;
|
||||
sz_ptload = phdri[j].p_filesz + phdri[j].p_offset - phdri[0].p_offset;
|
||||
}
|
||||
}
|
||||
return 0 < n_ptload;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
|
@ -126,20 +219,6 @@ const int *PackVmlinuxARM::getFilters() const
|
|||
return f50;
|
||||
}
|
||||
|
||||
static int __acc_cdecl_qsort
|
||||
compare_Phdr(void const *aa, void const *bb)
|
||||
{
|
||||
Elf32_Phdr const *const a = (Elf32_Phdr const *)aa;
|
||||
Elf32_Phdr const *const b = (Elf32_Phdr const *)bb;
|
||||
unsigned const xa = a->p_type - Elf32_Phdr::PT_LOAD;
|
||||
unsigned const xb = b->p_type - Elf32_Phdr::PT_LOAD;
|
||||
if (xa < xb) return -1; // PT_LOAD first
|
||||
if (xa > xb) return 1;
|
||||
if (a->p_paddr < b->p_paddr) return -1; // ascending by .p_paddr
|
||||
if (a->p_paddr > b->p_paddr) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Examples as of 2004-07-16 [readelf --segments vmlinux # before fiddling]:
|
||||
//
|
||||
|
@ -165,72 +244,9 @@ compare_Phdr(void const *aa, void const *bb)
|
|||
// LOAD 0x27b000 0xc067a000 0x0067a000 0x10ee64 0x1b07e8 RWE 0x1000
|
||||
// NOTE 0x000000 0x00000000 0x00000000 0x00000 0x00000 R 0x4
|
||||
|
||||
bool PackVmlinuxI386::canPack()
|
||||
int PackVmlinuxI386::is_valid_e_entry(Addr e_entry)
|
||||
{
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(&ehdri, sizeof(ehdri));
|
||||
|
||||
// now check the ELF header
|
||||
if (memcmp(&ehdri, "\x7f\x45\x4c\x46\x01\x01\x01", 7) // ELF 32-bit LSB
|
||||
|| !memcmp(&ehdri.e_ident[8], "FreeBSD", 7) // branded
|
||||
|| ehdri.e_version != 1 // version
|
||||
|| ehdri.e_ehsize != sizeof(ehdri) // different <elf.h> ?
|
||||
|| ehdri.e_phoff != sizeof(ehdri) // Phdrs not contiguous with Ehdr
|
||||
|| ehdri.e_phentsize!=sizeof(Elf32_Phdr)
|
||||
)
|
||||
return false;
|
||||
|
||||
// additional requirements for vmlinux
|
||||
if (ehdri.e_machine != Elf32_Ehdr::EM_386
|
||||
|| ehdri.e_type!=Elf32_Ehdr::ET_EXEC
|
||||
|| 0!=(0x000fffff & ehdri.e_entry) // entry not on whole 1MB
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// A Linux kernel must have a __ksymtab section. [??]
|
||||
Elf_LE32_Shdr const *p, *const shstrsec = getElfSections();
|
||||
if (0==shstrsec) {
|
||||
return false;
|
||||
}
|
||||
{
|
||||
int j;
|
||||
for (p = shdri, j= ehdri.e_shnum; --j>=0; ++p) {
|
||||
if (Elf32_Shdr::SHT_PROGBITS==p->sh_type
|
||||
&& 0==strcmp("__ksymtab", p->sh_name + shstrtab)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j < 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
phdri = new Elf_LE32_Phdr[(unsigned) ehdri.e_phnum];
|
||||
fi->seek(ehdri.e_phoff, SEEK_SET);
|
||||
fi->readx(phdri, ehdri.e_phnum * sizeof(*phdri));
|
||||
|
||||
// Put PT_LOAD together at the beginning, ascending by .p_paddr.
|
||||
qsort(phdri, ehdri.e_phnum, sizeof(*phdri), compare_Phdr);
|
||||
|
||||
// Check that PT_LOADs form one contiguous chunk of the file.
|
||||
for (unsigned j = 0; j < ehdri.e_phnum; ++j) {
|
||||
if (Elf32_Phdr::PT_LOAD==phdri[j].p_type) {
|
||||
if (0xfff & (phdri[j].p_offset | phdri[j].p_paddr
|
||||
| phdri[j].p_align | phdri[j].p_vaddr) ) {
|
||||
return false;
|
||||
}
|
||||
if (0 < j) {
|
||||
unsigned const sz = (0u - phdri[j-1].p_align)
|
||||
& (phdri[j-1].p_align -1 + phdri[j-1].p_filesz);
|
||||
if ((sz + phdri[j-1].p_offset)!=phdri[j].p_offset) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
++n_ptload;
|
||||
sz_ptload = phdri[j].p_filesz + phdri[j].p_offset - phdri[0].p_offset;
|
||||
}
|
||||
}
|
||||
return 0 < n_ptload;
|
||||
return 0==(0x000fffff & e_entry); // entry on whole 1MB
|
||||
}
|
||||
|
||||
|
||||
|
@ -265,75 +281,11 @@ void PackVmlinuxI386::buildLoader(const Filter *ft)
|
|||
"LINUX992,IDENTSTR,UPX1HEAD", NULL);
|
||||
}
|
||||
|
||||
bool PackVmlinuxARM::canPack()
|
||||
int PackVmlinuxARM::is_valid_e_entry(Addr e_entry)
|
||||
{
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(&ehdri, sizeof(ehdri));
|
||||
|
||||
// now check the ELF header
|
||||
if (memcmp(&ehdri, "\x7f\x45\x4c\x46\x01\x01\x01", 7) // ELF 32-bit LSB
|
||||
|| !memcmp(&ehdri.e_ident[8], "FreeBSD", 7) // branded
|
||||
|| ehdri.e_version != 1 // version
|
||||
|| ehdri.e_ehsize != sizeof(ehdri) // different <elf.h> ?
|
||||
|| ehdri.e_phoff != sizeof(ehdri) // Phdrs not contiguous with Ehdr
|
||||
|| ehdri.e_phentsize!=sizeof(Elf32_Phdr)
|
||||
)
|
||||
return false;
|
||||
|
||||
// additional requirements for vmlinux
|
||||
if (ehdri.e_machine != Elf32_Ehdr::EM_ARM
|
||||
|| ehdri.e_type!=Elf32_Ehdr::ET_EXEC
|
||||
|| 0xc0008000!=ehdri.e_entry
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// A Linux kernel must have a __ksymtab section. [??]
|
||||
Elf_LE32_Shdr const *p, *const shstrsec = getElfSections();
|
||||
if (0==shstrsec) {
|
||||
return false;
|
||||
}
|
||||
{
|
||||
int j;
|
||||
for (p = shdri, j= ehdri.e_shnum; --j>=0; ++p) {
|
||||
if (Elf32_Shdr::SHT_PROGBITS==p->sh_type
|
||||
&& 0==strcmp("__ksymtab", p->sh_name + shstrtab)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j < 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
phdri = new Elf_LE32_Phdr[(unsigned) ehdri.e_phnum];
|
||||
fi->seek(ehdri.e_phoff, SEEK_SET);
|
||||
fi->readx(phdri, ehdri.e_phnum * sizeof(*phdri));
|
||||
|
||||
// Put PT_LOAD together at the beginning, ascending by .p_paddr.
|
||||
qsort(phdri, ehdri.e_phnum, sizeof(*phdri), compare_Phdr);
|
||||
|
||||
// Check that PT_LOADs form one contiguous chunk of the file.
|
||||
for (unsigned j = 0; j < ehdri.e_phnum; ++j) {
|
||||
if (Elf32_Phdr::PT_LOAD==phdri[j].p_type) {
|
||||
if (0xfff & (phdri[j].p_offset | phdri[j].p_paddr
|
||||
| phdri[j].p_align | phdri[j].p_vaddr) ) {
|
||||
return false;
|
||||
}
|
||||
if (0 < j) {
|
||||
unsigned const sz = (0u - phdri[j-1].p_align)
|
||||
& (phdri[j-1].p_align -1 + phdri[j-1].p_filesz);
|
||||
if ((sz + phdri[j-1].p_offset)!=phdri[j].p_offset) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
++n_ptload;
|
||||
sz_ptload = phdri[j].p_filesz + phdri[j].p_offset - phdri[0].p_offset;
|
||||
}
|
||||
}
|
||||
return 0 < n_ptload;
|
||||
return 0xc0008000==e_entry;
|
||||
}
|
||||
|
||||
|
||||
Linker* PackVmlinuxARM::newLinker() const
|
||||
{
|
||||
return new ElfLinkerArmLE;
|
||||
|
@ -1215,90 +1167,11 @@ const int *PackVmlinuxAMD64::getFilters() const
|
|||
return filters;
|
||||
}
|
||||
|
||||
static int __acc_cdecl_qsort
|
||||
compare_Phdr64(void const *aa, void const *bb)
|
||||
int PackVmlinuxAMD64::is_valid_e_entry(Addr e_entry)
|
||||
{
|
||||
Elf64_Phdr const *const a = (Elf64_Phdr const *)aa;
|
||||
Elf64_Phdr const *const b = (Elf64_Phdr const *)bb;
|
||||
unsigned const xa = a->p_type - Elf64_Phdr::PT_LOAD;
|
||||
unsigned const xb = b->p_type - Elf64_Phdr::PT_LOAD;
|
||||
if (xa < xb) return -1; // PT_LOAD first
|
||||
if (xa > xb) return 1;
|
||||
if (a->p_paddr < b->p_paddr) return -1; // ascending by .p_paddr
|
||||
if (a->p_paddr > b->p_paddr) return 1;
|
||||
return 0;
|
||||
return 0x200000<=e_entry; // 2MB
|
||||
}
|
||||
|
||||
bool PackVmlinuxAMD64::canPack()
|
||||
{
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(&ehdri, sizeof(ehdri));
|
||||
|
||||
// now check the ELF header
|
||||
if (memcmp(&ehdri, "\x7f\x45\x4c\x46\x02\x01\x01", 7) // ELF 64-bit LSB
|
||||
|| ehdri.e_version != 1 // version
|
||||
|| ehdri.e_ehsize != sizeof(ehdri) // different <elf.h> ?
|
||||
|| ehdri.e_phoff != sizeof(ehdri) // Phdrs not contiguous with Ehdr
|
||||
|| ehdri.e_phentsize!=sizeof(Elf64_Phdr)
|
||||
)
|
||||
return false;
|
||||
|
||||
// additional requirements for vmlinux
|
||||
if (ehdri.e_machine != Elf64_Ehdr::EM_X86_64
|
||||
|| ehdri.e_type!=Elf64_Ehdr::ET_EXEC
|
||||
|| ehdri.e_entry < 0x200000 // entry below 2MB
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// A Linux kernel must have a __ksymtab section. [??]
|
||||
Elf_LE64_Shdr const *p, *const shstrsec = getElfSections();
|
||||
if (0==shstrsec) {
|
||||
return false;
|
||||
}
|
||||
int j;
|
||||
for (p = shdri, j= ehdri.e_shnum; --j>=0; ++p) {
|
||||
if (Elf64_Shdr::SHT_PROGBITS==p->sh_type
|
||||
&& 0==strcmp("__ksymtab", p->sh_name + shstrtab)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
phdri = new Elf_LE64_Phdr[(unsigned) ehdri.e_phnum];
|
||||
fi->seek(ehdri.e_phoff, SEEK_SET);
|
||||
fi->readx(phdri, ehdri.e_phnum * sizeof(*phdri));
|
||||
|
||||
// Put PT_LOAD together at the beginning, ascending by .p_paddr.
|
||||
qsort(phdri, ehdri.e_phnum, sizeof(*phdri), compare_Phdr64);
|
||||
|
||||
// Check that PT_LOADs form one contiguous chunk of the file.
|
||||
for (unsigned j = 0; j < ehdri.e_phnum; ++j) {
|
||||
if (Elf64_Phdr::PT_LOAD==phdri[j].p_type) {
|
||||
if (0xfff & (phdri[j].p_offset | phdri[j].p_paddr
|
||||
| phdri[j].p_align | phdri[j].p_vaddr) ) {
|
||||
return false;
|
||||
}
|
||||
if (0 < j) {
|
||||
unsigned const org = (0u - phdri[j].p_align) &
|
||||
(-1 + phdri[j].p_align +
|
||||
phdri[j-1].p_filesz + phdri[j-1].p_offset);
|
||||
unsigned const loc = (0u - phdri[j].p_align) &
|
||||
(-1 + phdri[j].p_align + phdri[j].p_offset);
|
||||
if (org!=loc) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
++n_ptload;
|
||||
sz_ptload = phdri[j].p_filesz + phdri[j].p_offset - phdri[0].p_offset;
|
||||
}
|
||||
}
|
||||
return 0 < n_ptload;
|
||||
}
|
||||
|
||||
|
||||
Linker* PackVmlinuxAMD64::newLinker() const
|
||||
{
|
||||
return new ElfLinkerX86;
|
||||
|
|
|
@ -44,10 +44,14 @@ protected:
|
|||
typedef typename TElfClass::Ehdr Ehdr;
|
||||
typedef typename TElfClass::Shdr Shdr;
|
||||
typedef typename TElfClass::Phdr Phdr;
|
||||
typedef /*typename TElfClass::Addr*/ unsigned long Addr;
|
||||
|
||||
public:
|
||||
PackVmlinuxBase(InputFile *f) :
|
||||
super(f), n_ptload(0), phdri(NULL), shdri(NULL), shstrtab(NULL)
|
||||
PackVmlinuxBase(InputFile *f,
|
||||
unsigned e_machine, unsigned elfclass, unsigned elfdata) :
|
||||
super(f),
|
||||
my_e_machine(e_machine), my_elfclass(elfclass), my_elfdata(elfdata),
|
||||
n_ptload(0), phdri(NULL), shdri(NULL), shstrtab(NULL)
|
||||
{
|
||||
bele = N_BELE_CTP::getRTP<typename TElfClass::BeLePolicy>();
|
||||
}
|
||||
|
@ -55,6 +59,9 @@ public:
|
|||
virtual int getVersion() const { return 13; }
|
||||
|
||||
protected:
|
||||
unsigned int const my_e_machine;
|
||||
unsigned char const my_elfclass;
|
||||
unsigned char const my_elfdata;
|
||||
int n_ptload;
|
||||
unsigned sz_ptload;
|
||||
Phdr *phdri; // from input file
|
||||
|
@ -67,6 +74,9 @@ protected:
|
|||
|
||||
virtual Shdr const *getElfSections();
|
||||
virtual int getStrategy(Filter &/*ft*/);
|
||||
virtual int is_valid_e_entry(Addr);
|
||||
virtual bool canPack();
|
||||
static int __acc_cdecl_qsort compare_Phdr(void const *aa, void const *bb);
|
||||
};
|
||||
|
||||
|
||||
|
@ -74,7 +84,8 @@ class PackVmlinuxI386 : public PackVmlinuxBase<ElfClass_LE32>
|
|||
{
|
||||
typedef PackVmlinuxBase<ElfClass_LE32> super;
|
||||
public:
|
||||
PackVmlinuxI386(InputFile *f) : super(f) { }
|
||||
PackVmlinuxI386(InputFile *f) : super(f, Elf32_Ehdr::EM_386,
|
||||
Elf32_Ehdr::ELFCLASS32, Elf32_Ehdr::ELFDATA2LSB) { }
|
||||
virtual int getFormat() const { return UPX_F_VMLINUX_i386; }
|
||||
virtual const char *getName() const { return "vmlinux/386"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "i386-linux.kernel.vmlinux"; }
|
||||
|
@ -84,12 +95,12 @@ public:
|
|||
virtual void pack(OutputFile *fo);
|
||||
virtual void unpack(OutputFile *fo);
|
||||
|
||||
virtual bool canPack();
|
||||
virtual int canUnpack();
|
||||
|
||||
protected:
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
virtual Linker* newLinker() const;
|
||||
virtual int is_valid_e_entry(Addr);
|
||||
};
|
||||
|
||||
|
||||
|
@ -97,7 +108,8 @@ class PackVmlinuxARM : public PackVmlinuxBase<ElfClass_LE32>
|
|||
{
|
||||
typedef PackVmlinuxBase<ElfClass_LE32> super;
|
||||
public:
|
||||
PackVmlinuxARM(InputFile *f) : super(f) { }
|
||||
PackVmlinuxARM(InputFile *f) : super(f, Elf32_Ehdr::EM_ARM,
|
||||
Elf32_Ehdr::ELFCLASS32, Elf32_Ehdr::ELFDATA2LSB) { }
|
||||
virtual int getFormat() const { return UPX_F_VMLINUX_ARM; }
|
||||
virtual const char *getName() const { return "vmlinux/ARM"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "ARM-linux.kernel.vmlinux"; }
|
||||
|
@ -107,12 +119,12 @@ public:
|
|||
virtual void pack(OutputFile *fo);
|
||||
virtual void unpack(OutputFile *fo);
|
||||
|
||||
virtual bool canPack();
|
||||
virtual int canUnpack();
|
||||
|
||||
protected:
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
virtual Linker* newLinker() const;
|
||||
virtual int is_valid_e_entry(Addr);
|
||||
};
|
||||
|
||||
|
||||
|
@ -120,7 +132,8 @@ class PackVmlinuxAMD64 : public PackVmlinuxBase<ElfClass_LE64>
|
|||
{
|
||||
typedef PackVmlinuxBase<ElfClass_LE64> super;
|
||||
public:
|
||||
PackVmlinuxAMD64(InputFile *f) : super(f) { }
|
||||
PackVmlinuxAMD64(InputFile *f) : super(f, Elf64_Ehdr::EM_X86_64,
|
||||
Elf64_Ehdr::ELFCLASS64, Elf64_Ehdr::ELFDATA2LSB) { }
|
||||
virtual int getFormat() const { return UPX_F_VMLINUX_AMD64; }
|
||||
virtual const char *getName() const { return "vmlinux/AMD64"; }
|
||||
virtual const char *getFullName(const options_t *) const { return "amd64-linux.kernel.vmlinux"; }
|
||||
|
@ -130,12 +143,12 @@ public:
|
|||
virtual void pack(OutputFile *fo);
|
||||
virtual void unpack(OutputFile *fo);
|
||||
|
||||
virtual bool canPack();
|
||||
virtual int canUnpack();
|
||||
|
||||
protected:
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
virtual Linker* newLinker() const;
|
||||
virtual int is_valid_e_entry(Addr);
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user