getElfSections concentrates on _Shdr[.e_shstrndx]

https://github.com/upx/upx/issues/363
	modified:   p_vmlinx.cpp
This commit is contained in:
John Reiser
2020-04-15 13:29:01 -07:00
committed by Markus F.X.J. Oberhumer
parent 87a5a4ef32
commit 6868ca7953
+25 -29
View File
@@ -104,42 +104,38 @@ PackVmlinuxBase<T>::compare_Phdr(void const *aa, void const *bb)
template <class T> template <class T>
typename T::Shdr const *PackVmlinuxBase<T>::getElfSections() typename T::Shdr const *PackVmlinuxBase<T>::getElfSections()
{ {
Shdr const *p, *shstrsec=0; Shdr const *p;
unsigned const e_shnum = ehdri.e_shnum;
if (ehdri.e_shentsize != sizeof(*shdri) if (ehdri.e_shentsize != sizeof(*shdri)
|| (unsigned long)file_size < ehdri.e_shoff || (unsigned long)file_size < ehdri.e_shoff
|| (unsigned long)file_size < ehdri.e_shoff + ehdri.e_shentsize * ehdri.e_shnum) { || (unsigned long)file_size < ehdri.e_shoff + ehdri.e_shentsize * e_shnum) {
throwCantPack("bad ElfXX_Shdrs"); throwCantPack("bad ElfXX_Shdrs");
} }
shdri = new Shdr[(unsigned) ehdri.e_shnum]; shdri = new Shdr[(unsigned) e_shnum];
fi->seek(ehdri.e_shoff, SEEK_SET); fi->seek(ehdri.e_shoff, SEEK_SET);
fi->readx(shdri, ehdri.e_shnum * sizeof(*shdri)); fi->readx(shdri, e_shnum * sizeof(*shdri));
unsigned e_shnum = ehdri.e_shnum; p = &shdri[ehdri.e_shstrndx]; // supposed
unsigned j; if (Shdr::SHT_STRTAB==p->sh_type
for (p = shdri, j = 0; j < e_shnum; ++j, ++p) { && p->sh_offset <= ((unsigned long)file_size - sizeof(*shdri))
if (Shdr::SHT_STRTAB==p->sh_type && p->sh_size <= ((unsigned long)file_size - p->sh_offset)
&& p->sh_offset <= ((unsigned long)file_size - sizeof(*shdri)) && p->sh_name <= ((unsigned long)file_size - p->sh_offset)
&& p->sh_size <= ((unsigned long)file_size - p->sh_offset) && 10 <= ((unsigned long)file_size - p->sh_name)
&& p->sh_name <= ((unsigned long)file_size - p->sh_offset) // 10 == (1+ strlen(".shstrtab"))
&& 10 <= ((unsigned long)file_size - p->sh_name) ) {
// 10 == (1+ strlen(".shstrtab")) if (p->sh_size <= p->sh_name) {
) { char msg[50]; snprintf(msg, sizeof(msg),
if (p->sh_size <= p->sh_name) { "bad .shstrtab _Shdr[%u]", (unsigned)ehdri.e_shstrndx);
char msg[50]; snprintf(msg, sizeof(msg), throwCantPack(msg);
"bad SHT_STRTAB[%u]", j); }
throwCantPack(msg); shstrtab = new char[1+ p->sh_size];
} fi->seek(p->sh_offset, SEEK_SET);
delete [] shstrtab; fi->readx(shstrtab, p->sh_size);
shstrtab = new char[1+ p->sh_size]; shstrtab[p->sh_size] = '\0';
fi->seek(p->sh_offset, SEEK_SET); if (0==strcmp(".shstrtab", shstrtab + p->sh_name)) {
fi->readx(shstrtab, p->sh_size); return p;
shstrtab[p->sh_size] = '\0';
if (0==strcmp(".shstrtab", shstrtab + p->sh_name)) {
shstrsec = p;
break;
}
} }
} }
return shstrsec; return 0;
} }
template <class T> template <class T>