Merge branch 'devel' into jreiser

This commit is contained in:
John Reiser
2017-03-31 13:10:08 -07:00
+44 -41
View File
@@ -1508,18 +1508,17 @@ bool PackLinuxElf32::canPack()
} }
unsigned const p_type = get_te32(&phdr->p_type); unsigned const p_type = get_te32(&phdr->p_type);
unsigned const p_offset = get_te32(&phdr->p_offset); unsigned const p_offset = get_te32(&phdr->p_offset);
if (1!=exetype && phdr->PT_LOAD32 == p_type) { if (1!=exetype && phdr->PT_LOAD32 == p_type) { // 1st PT_LOAD
exetype = 1; exetype = 1;
load_va = get_te32(&phdr->p_vaddr); load_va = get_te32(&phdr->p_vaddr); // class data member
unsigned file_offset = get_te32(&phdr->p_offset); unsigned const off = ~page_mask & load_va;
if (~(upx_uint64_t)page_mask & file_offset) { if (off && off == p_offset) { // specific hint
if ((~page_mask & (unsigned)load_va) == file_offset) {
throwCantPack("Go-language PT_LOAD: try hemfix.c, or try '--force-execve'"); throwCantPack("Go-language PT_LOAD: try hemfix.c, or try '--force-execve'");
// Fixing it inside upx fails because packExtent() reads original file. // Fixing it inside upx fails because packExtent() reads original file.
return false;
} }
else { if (0 != p_offset) { // 1st PT_LOAD must cover Ehdr and Phdr
throwCantPack("invalid Phdr p_offset; try '--force-execve'"); throwCantPack("first PT_LOAD.p_offset != 0; try '--force-execve'");
}
return false; return false;
} }
} }
@@ -1530,9 +1529,7 @@ bool PackLinuxElf32::canPack()
throwCantPack("PT_NOTEs too big; try '--force-execve'"); throwCantPack("PT_NOTEs too big; try '--force-execve'");
return false; return false;
} }
} if (osabi_note && Elf32_Ehdr::ELFOSABI_NONE==osabi0) { // Still seems to be generic.
if (Elf32_Ehdr::ELFOSABI_NONE==osabi0 // Still seems to be generic.
&& NULL!=osabi_note && phdr->PT_NOTE == p_type) {
struct { struct {
struct Elf32_Nhdr nhdr; struct Elf32_Nhdr nhdr;
char name[8]; char name[8];
@@ -1552,6 +1549,7 @@ bool PackLinuxElf32::canPack()
} }
} }
} }
}
if (Elf32_Ehdr::ELFOSABI_NONE ==osabi0 if (Elf32_Ehdr::ELFOSABI_NONE ==osabi0
|| Elf32_Ehdr::ELFOSABI_LINUX==osabi0) { // No EI_OSBAI, no PT_NOTE. || Elf32_Ehdr::ELFOSABI_LINUX==osabi0) { // No EI_OSBAI, no PT_NOTE.
unsigned const arm_eabi = 0xff000000u & get_te32(&ehdr->e_flags); unsigned const arm_eabi = 0xff000000u & get_te32(&ehdr->e_flags);
@@ -1716,20 +1714,21 @@ PackLinuxElf64ppcle::canPack()
for (unsigned j=0; j < e_phnum; ++phdr, ++j) { for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
if (j >= 14) if (j >= 14)
return false; return false;
if (phdr->PT_LOAD64 == get_te32(&phdr->p_type)) { unsigned const p_type = get_te32(&phdr->p_type);
load_va = get_te64(&phdr->p_vaddr); if (1!=exetype && phdr->PT_LOAD64 == p_type) { // 1st PT_LOAD
upx_uint64_t file_offset = get_te64(&phdr->p_offset); exetype = 1;
if (~page_mask & file_offset) { load_va = get_te64(&phdr->p_vaddr); // class data member
if ((~page_mask & load_va) == file_offset) { upx_uint64_t const p_offset = get_te64(&phdr->p_offset);
upx_uint64_t const off = ~page_mask & load_va;
if (off && off == p_offset) { // specific hint
throwCantPack("Go-language PT_LOAD: try hemfix.c, or try '--force-execve'"); throwCantPack("Go-language PT_LOAD: try hemfix.c, or try '--force-execve'");
// Fixing it inside upx fails because packExtent() reads original file. // Fixing it inside upx fails because packExtent() reads original file.
}
else {
throwCantPack("invalid Phdr p_offset; try '--force-execve'");
}
return false; return false;
} }
exetype = 1; if (0 != p_offset) { // 1st PT_LOAD must cover Ehdr and Phdr
throwCantPack("first PT_LOAD.p_offset != 0; try '--force-execve'");
return false;
}
break; break;
} }
} }
@@ -1909,20 +1908,21 @@ PackLinuxElf64amd::canPack()
for (unsigned j=0; j < e_phnum; ++phdr, ++j) { for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
if (j >= 14) if (j >= 14)
return false; return false;
if (phdr->PT_LOAD64 == get_te32(&phdr->p_type)) { unsigned const p_type = get_te32(&phdr->p_type);
load_va = get_te64(&phdr->p_vaddr); if (1!=exetype && phdr->PT_LOAD64 == p_type) { // 1st PT_LOAD
upx_uint64_t file_offset = get_te64(&phdr->p_offset); exetype = 1;
if (~page_mask & file_offset) { load_va = get_te64(&phdr->p_vaddr); // class data member
if ((~page_mask & load_va) == file_offset) { upx_uint64_t const p_offset = get_te64(&phdr->p_offset);
upx_uint64_t const off = ~page_mask & load_va;
if (off && off == p_offset) { // specific hint
throwCantPack("Go-language PT_LOAD: try hemfix.c, or try '--force-execve'"); throwCantPack("Go-language PT_LOAD: try hemfix.c, or try '--force-execve'");
// Fixing it inside upx fails because packExtent() reads original file. // Fixing it inside upx fails because packExtent() reads original file.
}
else {
throwCantPack("invalid Phdr p_offset; try '--force-execve'");
}
return false; return false;
} }
exetype = 1; if (0 != p_offset) { // 1st PT_LOAD must cover Ehdr and Phdr
throwCantPack("first PT_LOAD.p_offset != 0; try '--force-execve'");
return false;
}
break; break;
} }
} }
@@ -2103,20 +2103,21 @@ PackLinuxElf64arm::canPack()
for (unsigned j=0; j < e_phnum; ++phdr, ++j) { for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
if (j >= 14) if (j >= 14)
return false; return false;
if (phdr->PT_LOAD64 == get_te32(&phdr->p_type)) { unsigned const p_type = get_te32(&phdr->p_type);
load_va = get_te64(&phdr->p_vaddr); if (1!=exetype && phdr->PT_LOAD64 == p_type) { // 1st PT_LOAD
upx_uint64_t file_offset = get_te64(&phdr->p_offset); exetype = 1;
if (~page_mask & file_offset) { load_va = get_te64(&phdr->p_vaddr); // class data member
if ((~page_mask & load_va) == file_offset) { upx_uint64_t const p_offset = get_te64(&phdr->p_offset);
upx_uint64_t const off = ~page_mask & load_va;
if (off && off == p_offset) { // specific hint
throwCantPack("Go-language PT_LOAD: try hemfix.c, or try '--force-execve'"); throwCantPack("Go-language PT_LOAD: try hemfix.c, or try '--force-execve'");
// Fixing it inside upx fails because packExtent() reads original file. // Fixing it inside upx fails because packExtent() reads original file.
}
else {
throwCantPack("invalid Phdr p_offset; try '--force-execve'");
}
return false; return false;
} }
exetype = 1; if (0 != p_offset) { // 1st PT_LOAD must cover Ehdr and Phdr
throwCantPack("first PT_LOAD.p_offset != 0; try '--force-execve'");
return false;
}
break; break;
} }
} }
@@ -3780,6 +3781,7 @@ void PackLinuxElf64::unpack(OutputFile *fo)
else { // main executable else { // main executable
// Decompress each PT_LOAD. // Decompress each PT_LOAD.
bool first_PF_X = true; bool first_PF_X = true;
phdr = (Elf64_Phdr *) (void *) (1+ ehdr); // uncompressed
for (unsigned j=0; j < u_phnum; ++phdr, ++j) { for (unsigned j=0; j < u_phnum; ++phdr, ++j) {
if (PT_LOAD64==get_te32(&phdr->p_type)) { if (PT_LOAD64==get_te32(&phdr->p_type)) {
unsigned const filesz = get_te64(&phdr->p_filesz); unsigned const filesz = get_te64(&phdr->p_filesz);
@@ -4400,6 +4402,7 @@ void PackLinuxElf32::unpack(OutputFile *fo)
else { // main executable else { // main executable
// Decompress each PT_LOAD. // Decompress each PT_LOAD.
bool first_PF_X = true; bool first_PF_X = true;
phdr = (Elf32_Phdr *) (void *) (1+ ehdr); // uncompressed
for (unsigned j=0; j < u_phnum; ++phdr, ++j) { for (unsigned j=0; j < u_phnum; ++phdr, ++j) {
if (PT_LOAD32==get_te32(&phdr->p_type)) { if (PT_LOAD32==get_te32(&phdr->p_type)) {
unsigned const filesz = get_te32(&phdr->p_filesz); unsigned const filesz = get_te32(&phdr->p_filesz);