Stronger test and better message for PT_LOAD[0].p_offset != 0
https://github.com/upx/upx/issues/80 modified: p_lx_elf.cpp
This commit is contained in:
+42
-41
@@ -1515,18 +1515,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1537,9 +1536,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];
|
||||||
@@ -1559,6 +1556,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);
|
||||||
@@ -1723,20 +1721,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1916,20 +1915,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2110,20 +2110,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user