4
0
mirror of https://github.com/QuasarApp/LIEF.git synced 2025-05-12 19:39:32 +00:00

Add support for endianness

This commit is contained in:
yd0b0N 2018-05-15 11:38:56 +02:00 committed by Romain Thomas
parent 9e3b5b45f7
commit e794ac1502
10 changed files with 442 additions and 43 deletions

@ -77,6 +77,7 @@ set(LIBLIEF_SOURCE_FILES
"${CMAKE_CURRENT_SOURCE_DIR}/src/Visitor.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/BinaryStream/BinaryStream.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/BinaryStream/VectorStream.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/BinaryStream/Convert.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/visitors/hash.cpp")
@ -102,6 +103,7 @@ set(LIEF_INC_FILES
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/visitor_macros.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/BinaryStream/BinaryStream.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/BinaryStream/VectorStream.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/BinaryStream/Convert.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/frozen.hpp"
)

@ -21,6 +21,9 @@
#include <vector>
#include <istream>
#include <utility>
#include <memory>
#include "LIEF/BinaryStream/Convert.hpp"
class BinaryStream {
public:
@ -79,9 +82,26 @@ class BinaryStream {
size_t align(size_t align_on) const;
/* Read an integer value and adjust endianness as needed */
template<typename T>
T read_conv() const;
/* Read an array of values and adjust endianness as needed */
template<typename T>
std::unique_ptr<T[]> read_conv_array(size_t size, bool check = true) const;
template<typename T>
T peek_conv(size_t offset) const;
template<typename T>
std::unique_ptr<T[]> peek_conv_array(size_t offset, size_t size, bool check = true) const;
void set_endian_swap(bool swap);
protected:
virtual const void* read_at(uint64_t offset, uint64_t size, bool throw_error = true) const = 0;
mutable size_t pos_{0};
bool endian_swap_{false};
};
@ -167,5 +187,62 @@ const T* BinaryStream::read_array(size_t size, bool check) const {
}
template<typename T>
T BinaryStream::read_conv(void) const {
T t = this->read<T>();
if (this->endian_swap_) {
LIEF::Convert::swap_endian<T>(& t);
}
return t;
}
template<typename T>
std::unique_ptr<T[]> BinaryStream::read_conv_array(size_t size, bool check) const {
const T *t = this->read_array<T>(size, check);
if (t == nullptr) {
return nullptr;
}
std::unique_ptr<T[]> uptr(new T[size]);
for (size_t i = 0; i < size; i++) {
uptr[i] = t[i];
if (this->endian_swap_) {
LIEF::Convert::swap_endian<T>(& uptr[i]);
} /* else no conversion, just provide the copied data */
}
return uptr;
}
template<class T>
T BinaryStream::peek_conv(size_t offset) const {
T t = this->peek<T>(offset);
if (this->endian_swap_) {
LIEF::Convert::swap_endian(&t);
}
return t;
}
template<typename T>
std::unique_ptr<T[]> BinaryStream::peek_conv_array(size_t offset, size_t size, bool check) const {
const T *t = this->peek_array<T>(offset, size, check);
if (t == nullptr) {
return nullptr;
}
std::unique_ptr<T[]> uptr(new T[size]);
for (size_t i = 0; i < size; i++) {
uptr[i] = t[i];
if (this->endian_swap_) {
LIEF::Convert::swap_endian<T>(& uptr[i]);
} /* else no conversion, just provide the copied data */
}
return uptr;
}
#endif

@ -0,0 +1,12 @@
#ifndef LIEF_CONVERT_H_
#define LIEF_CONVERT_H_
namespace LIEF {
namespace Convert {
template<typename X>
void swap_endian(X* x);
}
}
#endif // LIEF_CONVERT_H_

@ -96,6 +96,8 @@ class LIEF_API Parser : public LIEF::Parser {
void init(const std::string& name = "");
bool should_swap(void) const;
// map, dynamic_symbol.version <----> symbol_version
// symbol_version comes from symbol_version table
void link_symbol_version(void);

@ -218,3 +218,7 @@ std::string BinaryStream::read_mutf8(size_t maxsize) const {
return u8str_clean;
}
void BinaryStream::set_endian_swap(bool swap) {
this->endian_swap_ = swap;
}

@ -0,0 +1,23 @@
#include "LIEF/BinaryStream/Convert.hpp"
#include "LIEF/BinaryStream/BinaryStream.hpp"
/* In place conversions for BinaryStream/VectorStream data */
namespace LIEF {
namespace Convert {
template<typename T>
void swap_endian(T *v) {
static_assert(std::is_integral<T>::value, "Only integer types can use generic endian swap");
*v = BinaryStream::swap_endian(*v);
}
/*
* Force instantiation of template for types used
*/
template void swap_endian<uint16_t>(uint16_t *v);
template void swap_endian<uint32_t>(uint32_t *v);
template void swap_endian<uint64_t>(uint64_t *v);
}
}

@ -15,6 +15,7 @@ configure_file(
)
set(LIEF_ELF_SRC
"${CMAKE_CURRENT_LIST_DIR}/Convert.cpp"
"${CMAKE_CURRENT_LIST_DIR}/DynamicEntryArray.cpp"
"${CMAKE_CURRENT_LIST_DIR}/utils.cpp"
"${CMAKE_CURRENT_LIST_DIR}/SymbolVersionRequirement.cpp"

248
src/ELF/Convert.cpp Normal file

@ -0,0 +1,248 @@
#include "LIEF/BinaryStream/Convert.hpp"
#include "LIEF/BinaryStream/BinaryStream.hpp"
#include "LIEF/ELF/Structures.hpp"
/* In place conversions for BinaryStream/VectorStream data */
namespace LIEF {
namespace Convert {
/*
* ELF conversions
*/
/** ELF header */
template <typename Elf_Ehdr>
void swap_endian_ehdr(Elf_Ehdr *hdr) {
hdr->e_type = BinaryStream::swap_endian(hdr->e_type);
hdr->e_machine = BinaryStream::swap_endian(hdr->e_machine);
hdr->e_version = BinaryStream::swap_endian(hdr->e_version);
hdr->e_entry = BinaryStream::swap_endian(hdr->e_entry);
hdr->e_phoff = BinaryStream::swap_endian(hdr->e_phoff);
hdr->e_shoff = BinaryStream::swap_endian(hdr->e_shoff);
hdr->e_flags = BinaryStream::swap_endian(hdr->e_flags);
hdr->e_ehsize = BinaryStream::swap_endian(hdr->e_ehsize);
hdr->e_phentsize = BinaryStream::swap_endian(hdr->e_phentsize);
hdr->e_phnum = BinaryStream::swap_endian(hdr->e_phnum);
hdr->e_shentsize = BinaryStream::swap_endian(hdr->e_shentsize);
hdr->e_shnum = BinaryStream::swap_endian(hdr->e_shnum);
hdr->e_shstrndx = BinaryStream::swap_endian(hdr->e_shstrndx);
}
template<>
void swap_endian<LIEF::ELF::Elf32_Ehdr>(LIEF::ELF::Elf32_Ehdr *hdr) {
swap_endian_ehdr(hdr);
}
template<>
void swap_endian<LIEF::ELF::Elf64_Ehdr>(LIEF::ELF::Elf64_Ehdr *hdr) {
swap_endian_ehdr(hdr);
}
/** ELF Section Header */
template <typename Elf_Shdr>
void swap_endian_shdr(Elf_Shdr *shdr) {
shdr->sh_name = BinaryStream::swap_endian(shdr->sh_name);
shdr->sh_type = BinaryStream::swap_endian(shdr->sh_type);
shdr->sh_flags = BinaryStream::swap_endian(shdr->sh_flags);
shdr->sh_addr = BinaryStream::swap_endian(shdr->sh_addr);
shdr->sh_offset = BinaryStream::swap_endian(shdr->sh_offset);
shdr->sh_size = BinaryStream::swap_endian(shdr->sh_size);
shdr->sh_link = BinaryStream::swap_endian(shdr->sh_link);
shdr->sh_info = BinaryStream::swap_endian(shdr->sh_info);
shdr->sh_addralign = BinaryStream::swap_endian(shdr->sh_addralign);
shdr->sh_entsize = BinaryStream::swap_endian(shdr->sh_entsize);
}
template<>
void swap_endian<LIEF::ELF::Elf32_Shdr>(LIEF::ELF::Elf32_Shdr *shdr) {
swap_endian_shdr(shdr);
}
template<>
void swap_endian<LIEF::ELF::Elf64_Shdr>(LIEF::ELF::Elf64_Shdr *shdr) {
swap_endian_shdr(shdr);
}
/** ELF Program Header */
template <typename Elf_Phdr>
void swap_endian_phdr(Elf_Phdr *phdr) {
phdr->p_type = BinaryStream::swap_endian(phdr->p_type);
phdr->p_offset = BinaryStream::swap_endian(phdr->p_offset);
phdr->p_vaddr = BinaryStream::swap_endian(phdr->p_vaddr);
phdr->p_paddr = BinaryStream::swap_endian(phdr->p_paddr);
phdr->p_filesz = BinaryStream::swap_endian(phdr->p_filesz);
phdr->p_memsz = BinaryStream::swap_endian(phdr->p_memsz);
phdr->p_flags = BinaryStream::swap_endian(phdr->p_flags);
phdr->p_align = BinaryStream::swap_endian(phdr->p_align);
}
template<>
void swap_endian<LIEF::ELF::Elf32_Phdr>(LIEF::ELF::Elf32_Phdr *phdr) {
swap_endian_phdr(phdr);
}
template<>
void swap_endian<LIEF::ELF::Elf64_Phdr>(LIEF::ELF::Elf64_Phdr *phdr) {
swap_endian_phdr(phdr);
}
/** ELF Symbols */
template <typename Elf_Sym>
void swap_endian_sym(Elf_Sym *sym) {
sym->st_name = BinaryStream::swap_endian(sym->st_name);
sym->st_value = BinaryStream::swap_endian(sym->st_value);
sym->st_size = BinaryStream::swap_endian(sym->st_size);
sym->st_info = BinaryStream::swap_endian(sym->st_info);
sym->st_other = BinaryStream::swap_endian(sym->st_other);
sym->st_shndx = BinaryStream::swap_endian(sym->st_shndx);
}
template<>
void swap_endian<LIEF::ELF::Elf32_Sym>(LIEF::ELF::Elf32_Sym *sym) {
swap_endian_sym(sym);
}
template<>
void swap_endian<LIEF::ELF::Elf64_Sym>(LIEF::ELF::Elf64_Sym *sym) {
swap_endian_sym(sym);
}
/** ELF Relocations */
template <typename REL_T>
void swap_endian_rel(REL_T *rel) {
rel->r_offset = BinaryStream::swap_endian(rel->r_offset);
rel->r_info = BinaryStream::swap_endian(rel->r_info);
}
template <typename RELA_T>
void swap_endian_rela(RELA_T *rel) {
rel->r_offset = BinaryStream::swap_endian(rel->r_offset);
rel->r_info = BinaryStream::swap_endian(rel->r_info);
rel->r_addend = BinaryStream::swap_endian(rel->r_addend);
}
template<>
void swap_endian<LIEF::ELF::Elf32_Rel>(LIEF::ELF::Elf32_Rel *rel) {
swap_endian_rel(rel);
}
template<>
void swap_endian<LIEF::ELF::Elf64_Rel>(LIEF::ELF::Elf64_Rel *rel) {
swap_endian_rel(rel);
}
template<>
void swap_endian<LIEF::ELF::Elf32_Rela>(LIEF::ELF::Elf32_Rela *rel) {
swap_endian_rela(rel);
}
template<>
void swap_endian<LIEF::ELF::Elf64_Rela>(LIEF::ELF::Elf64_Rela *rel) {
swap_endian_rela(rel);
}
/** ELF Dynamic Symbol */
template <typename Elf_Dyn>
void swap_endian_dyn(Elf_Dyn *dyn) {
dyn->d_tag = BinaryStream::swap_endian(dyn->d_tag);
dyn->d_un.d_val = BinaryStream::swap_endian(dyn->d_un.d_val);
}
template<>
void swap_endian<LIEF::ELF::Elf32_Dyn>(LIEF::ELF::Elf32_Dyn *dyn) {
swap_endian_dyn(dyn);
}
template<>
void swap_endian<LIEF::ELF::Elf64_Dyn>(LIEF::ELF::Elf64_Dyn *dyn) {
swap_endian_dyn(dyn);
}
/** ELF Verneed */
template <typename Elf_Verneed>
void swap_endian_verneed(Elf_Verneed *ver) {
ver->vn_version = BinaryStream::swap_endian(ver->vn_version);
ver->vn_cnt = BinaryStream::swap_endian(ver->vn_cnt);
ver->vn_file = BinaryStream::swap_endian(ver->vn_file);
ver->vn_aux = BinaryStream::swap_endian(ver->vn_aux);
ver->vn_next = BinaryStream::swap_endian(ver->vn_next);
}
template<>
void swap_endian<LIEF::ELF::Elf32_Verneed>(LIEF::ELF::Elf32_Verneed *ver) {
swap_endian_verneed(ver);
}
template<>
void swap_endian<LIEF::ELF::Elf64_Verneed>(LIEF::ELF::Elf64_Verneed *ver) {
swap_endian_verneed(ver);
}
/** ELF Vernaux */
template <typename Elf_Vernaux>
void swap_endian_vernaux(Elf_Vernaux *ver) {
ver->vna_hash = BinaryStream::swap_endian(ver->vna_hash);
ver->vna_flags = BinaryStream::swap_endian(ver->vna_flags);
ver->vna_other = BinaryStream::swap_endian(ver->vna_other);
ver->vna_name = BinaryStream::swap_endian(ver->vna_name);
ver->vna_next = BinaryStream::swap_endian(ver->vna_next);
}
template<>
void swap_endian<LIEF::ELF::Elf32_Vernaux>(LIEF::ELF::Elf32_Vernaux *ver) {
swap_endian_vernaux(ver);
}
template<>
void swap_endian<LIEF::ELF::Elf64_Vernaux>(LIEF::ELF::Elf64_Vernaux *ver) {
swap_endian_vernaux(ver);
}
/** ELF Symbol Version Definition */
template <typename Elf_Verdef>
void swap_endian_verdef(Elf_Verdef *ver) {
ver->vd_version = BinaryStream::swap_endian(ver->vd_version);
ver->vd_flags = BinaryStream::swap_endian(ver->vd_flags);
ver->vd_ndx = BinaryStream::swap_endian(ver->vd_ndx);
ver->vd_cnt = BinaryStream::swap_endian(ver->vd_cnt);
ver->vd_hash = BinaryStream::swap_endian(ver->vd_hash);
ver->vd_aux = BinaryStream::swap_endian(ver->vd_aux);
ver->vd_next = BinaryStream::swap_endian(ver->vd_next);
}
template<>
void swap_endian<LIEF::ELF::Elf32_Verdef>(LIEF::ELF::Elf32_Verdef *ver) {
swap_endian_verdef(ver);
}
template<>
void swap_endian<LIEF::ELF::Elf64_Verdef>(LIEF::ELF::Elf64_Verdef *ver) {
swap_endian_verdef(ver);
}
template <typename Elf_Verdaux>
void swap_endian_verdaux(Elf_Verdaux *ver) {
ver->vda_name = BinaryStream::swap_endian(ver->vda_name);
ver->vda_next = BinaryStream::swap_endian(ver->vda_next);
}
template<>
void swap_endian<LIEF::ELF::Elf32_Verdaux>(LIEF::ELF::Elf32_Verdaux *ver) {
swap_endian_verdaux(ver);
}
template<>
void swap_endian<LIEF::ELF::Elf64_Verdaux>(LIEF::ELF::Elf64_Verdaux *ver) {
swap_endian_verdaux(ver);
}
}
}

@ -31,6 +31,7 @@
#include "LIEF/ELF/AndroidNote.hpp"
#include "Parser.tcc"
@ -84,6 +85,29 @@ Parser::Parser(const std::string& file, DYNSYM_COUNT_METHODS count_mtd, Binary*
this->init(filesystem::path(file).filename());
}
bool Parser::should_swap(void) const {
if (not this->stream_->can_read<Elf32_Ehdr>(0)) {
return false;
}
const Elf32_Ehdr& elf_hdr = this->stream_->peek<Elf32_Ehdr>(0);
ELF_DATA endian = static_cast<ELF_DATA>(elf_hdr.e_ident[static_cast<uint8_t>(IDENTITY::EI_DATA)]);
switch (endian) {
#ifdef __BYTE_ORDER__
#if defined(__ORDER_LITTLE_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
case ELF_DATA::ELFDATA2MSB:
#elif defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
case ELF_DATA::ELFDATA2LSB:
#endif
return true;
#endif // __BYTE_ORDER__
default:
// we're good (or don't know what to do), consider bytes are in the expected order
return false;
}
}
void Parser::init(const std::string& name) {
VLOG(VDEBUG) << "Parsing binary: " << name << std::endl;
@ -92,7 +116,9 @@ void Parser::init(const std::string& name) {
this->binary_->name(name);
this->binary_->datahandler_ = new DataHandler::Handler{this->stream_->content()};
uint32_t type = this->stream_->peek<Elf32_Ehdr>(0).e_ident[static_cast<size_t>(IDENTITY::EI_CLASS)];
const Elf32_Ehdr& elf_hdr = this->stream_->peek<Elf32_Ehdr>(0);
this->stream_->set_endian_swap(this->should_swap());
uint32_t type = elf_hdr.e_ident[static_cast<size_t>(IDENTITY::EI_CLASS)];
this->binary_->type_ = static_cast<ELF_CLASS>(type);
this->type_ = static_cast<ELF_CLASS>(type);
@ -157,7 +183,7 @@ void Parser::parse_symbol_version(uint64_t symbol_version_offset) {
if (not this->stream_->can_read<uint16_t>()) {
break;
}
this->binary_->symbol_version_table_.push_back(new SymbolVersion{this->stream_->read<uint16_t>()});
this->binary_->symbol_version_table_.push_back(new SymbolVersion{this->stream_->read_conv<uint16_t>()});
}
}
@ -189,7 +215,7 @@ uint64_t Parser::get_dynamic_string_table_from_segments(void) const {
if (not this->stream_->can_read<Elf32_Dyn>()) {
return 0;
}
const Elf32_Dyn& e = this->stream_->read<Elf32_Dyn>();
const Elf32_Dyn e = this->stream_->read_conv<Elf32_Dyn>();
if (static_cast<DYNAMIC_TAGS>(e.d_tag) == DYNAMIC_TAGS::DT_STRTAB) {
return this->binary_->virtual_address_to_offset(e.d_un.d_val);
@ -203,7 +229,7 @@ uint64_t Parser::get_dynamic_string_table_from_segments(void) const {
if (not this->stream_->can_read<Elf64_Dyn>()) {
return 0;
}
const Elf64_Dyn& e = this->stream_->read<Elf64_Dyn>();
const Elf64_Dyn e = this->stream_->read_conv<Elf64_Dyn>();
if (static_cast<DYNAMIC_TAGS>(e.d_tag) == DYNAMIC_TAGS::DT_STRTAB) {
return this->binary_->virtual_address_to_offset(e.d_un.d_val);
@ -258,7 +284,7 @@ void Parser::parse_symbol_sysv_hash(uint64_t offset) {
SysvHash sysvhash;
this->stream_->setpos(offset);
const uint32_t* header = this->stream_->read_array<uint32_t>(2, /* check */false);
std::unique_ptr<uint32_t[]> header = this->stream_->read_conv_array<uint32_t>(2, /* check */false);
if (header == nullptr) {
LOG(ERROR) << "Can't read SYSV Hash header";
@ -274,7 +300,7 @@ void Parser::parse_symbol_sysv_hash(uint64_t offset) {
if (not this->stream_->can_read<uint32_t>()) {
break;
}
buckets[i] = this->stream_->read<uint32_t>();
buckets[i] = this->stream_->read_conv<uint32_t>();
}
sysvhash.buckets_ = std::move(buckets);
@ -285,7 +311,7 @@ void Parser::parse_symbol_sysv_hash(uint64_t offset) {
if (not this->stream_->can_read<uint32_t>()) {
break;
}
chains[i] = this->stream_->read<uint32_t>();
chains[i] = this->stream_->read_conv<uint32_t>();
}
sysvhash.chains_ = std::move(chains);
@ -304,21 +330,21 @@ void Parser::parse_notes(uint64_t offset, uint64_t size) {
if (not this->stream_->can_read<uint32_t>()) {
break;
}
uint32_t namesz = this->stream_->read<uint32_t>();
uint32_t namesz = this->stream_->read_conv<uint32_t>();
VLOG(VDEBUG) << "Name size: " << std::hex << namesz;
if (not this->stream_->can_read<uint32_t>()) {
break;
}
uint32_t descsz = std::min(this->stream_->read<uint32_t>(), Parser::MAX_NOTE_DESCRIPTION);
uint32_t descsz = std::min(this->stream_->read_conv<uint32_t>(), Parser::MAX_NOTE_DESCRIPTION);
VLOG(VDEBUG) << "Description size: " << std::hex << descsz;
if (not this->stream_->can_read<uint32_t>()) {
break;
}
NOTE_TYPES type = static_cast<NOTE_TYPES>(this->stream_->read<uint32_t>());
NOTE_TYPES type = static_cast<NOTE_TYPES>(this->stream_->read_conv<uint32_t>());
VLOG(VDEBUG) << "Type: " << std::hex << static_cast<size_t>(type);
if (namesz == 0) { // System reserves
@ -331,9 +357,12 @@ void Parser::parse_notes(uint64_t offset, uint64_t size) {
std::vector<uint8_t> description;
if (descsz > 0) {
const uint8_t* desc_ptr = this->stream_->read_array<uint8_t>(descsz, /* check */false);
const size_t nb_chunks = (descsz - 1) / sizeof(uint32_t) + 1;
std::unique_ptr<uint32_t[]> desc_ptr = this->stream_->read_conv_array<uint32_t>(nb_chunks, /* check */ false);
if (desc_ptr != nullptr) {
description = {desc_ptr, desc_ptr + descsz};
description = {
reinterpret_cast<uint8_t *>(desc_ptr.get()),
reinterpret_cast<uint8_t *>(desc_ptr.get()) + descsz};
}
this->stream_->align(sizeof(uint32_t));
}

@ -454,7 +454,8 @@ bool Parser::parse_header(void) {
VLOG(VDEBUG) << "[+] Parsing Header";
this->stream_->setpos(0);
if (this->stream_->can_read<Elf_Ehdr>()) {
this->binary_->header_ = &this->stream_->read<Elf_Ehdr>();
Elf_Ehdr hdr = this->stream_->read_conv<Elf_Ehdr>();
this->binary_->header_ = &hdr;
return true;
} else {
LOG(FATAL) << "Can't read header!";
@ -648,7 +649,7 @@ uint32_t Parser::max_relocation_index(uint64_t relocations_offset, uint64_t size
if (not this->stream_->can_read<REL_T>()) {
break;
}
const REL_T& reloc_entry = this->stream_->read<REL_T>();
const REL_T reloc_entry = this->stream_->read_conv<REL_T>();
idx = std::max(idx, static_cast<uint32_t>(reloc_entry.r_info >> shift));
}
return (idx + 1);
@ -704,7 +705,7 @@ uint32_t Parser::nb_dynsym_sysv_hash(void) const {
this->stream_->setpos(sysv_hash_offset + sizeof(uint32_t));
if (not this->stream_->can_read<uint32_t>()) {
return this->stream_->read<uint32_t>();
return this->stream_->read_conv<uint32_t>();
}
return 0;
@ -724,25 +725,25 @@ uint32_t Parser::nb_dynsym_gnu_hash(void) const {
return 0;
}
const uint32_t nbuckets = std::min(this->stream_->read<uint32_t>(), Parser::NB_MAX_BUCKETS);
const uint32_t nbuckets = std::min(this->stream_->read_conv<uint32_t>(), Parser::NB_MAX_BUCKETS);
if (not this->stream_->can_read<uint32_t>()) {
return 0;
}
const uint32_t symndx = this->stream_->read<uint32_t>();
const uint32_t symndx = this->stream_->read_conv<uint32_t>();
if (not this->stream_->can_read<uint32_t>()) {
return 0;
}
const uint32_t maskwords = std::min(this->stream_->read<uint32_t>(), Parser::NB_MAX_MASKWORD);
const uint32_t maskwords = std::min(this->stream_->read_conv<uint32_t>(), Parser::NB_MAX_MASKWORD);
if (not this->stream_->can_read<uint32_t>()) {
return 0;
}
const uint32_t shift2 = this->stream_->read<uint32_t>();
const uint32_t shift2 = this->stream_->read_conv<uint32_t>();
if (maskwords & (maskwords - 1)) {
LOG(WARNING) << "maskwords is not a power of 2";
@ -762,7 +763,7 @@ uint32_t Parser::nb_dynsym_gnu_hash(void) const {
return 0;
}
bloom_filters[i] = this->stream_->read<uint__>();
bloom_filters[i] = this->stream_->read_conv<uint__>();
}
std::vector<uint32_t> buckets;
@ -777,7 +778,7 @@ uint32_t Parser::nb_dynsym_gnu_hash(void) const {
return 0;
}
buckets.push_back(this->stream_->read<uint32_t>());
buckets.push_back(this->stream_->read_conv<uint32_t>());
}
if (buckets.size() == 0) {
@ -806,7 +807,7 @@ uint32_t Parser::nb_dynsym_gnu_hash(void) const {
if (not this->stream_->can_read<uint32_t>()) {
return 0;
}
hash_value = this->stream_->read<uint32_t>();
hash_value = this->stream_->read_conv<uint32_t>();
nsyms++;
} while ((hash_value & 1) == 0); // "It is set to 1 when a symbol is the last symbol in a given hash bucket"
@ -837,7 +838,7 @@ void Parser::parse_sections(void) {
break;
}
const Elf_Shdr& shdr = this->stream_->read<Elf_Shdr>();
const Elf_Shdr shdr = this->stream_->read_conv<Elf_Shdr>();
std::unique_ptr<Section> section{new Section{&shdr}};
section->datahandler_ = this->binary_->datahandler_;
@ -899,7 +900,7 @@ void Parser::parse_segments(void) {
LOG(ERROR) << "Can't parse segment #" << std::dec << i;
break;
}
const Elf_Phdr& segment_headers = this->stream_->read<Elf_Phdr>();
const Elf_Phdr segment_headers = this->stream_->read_conv<Elf_Phdr>();
std::unique_ptr<Segment> segment{new Segment{&segment_headers}};
segment->datahandler_ = this->binary_->datahandler_;
@ -957,7 +958,7 @@ void Parser::parse_dynamic_relocations(uint64_t relocations_offset, uint64_t siz
if (not this->stream_->can_read<REL_T>()) {
break;
}
const REL_T& raw_reloc = this->stream_->read<REL_T>();
const REL_T raw_reloc = this->stream_->read_conv<REL_T>();
std::unique_ptr<Relocation> reloc{new Relocation{&raw_reloc}};
reloc->purpose(RELOCATION_PURPOSES::RELOC_PURPOSE_DYNAMIC);
reloc->architecture_ = this->binary_->header().machine_type();
@ -989,7 +990,7 @@ void Parser::parse_static_symbols(uint64_t offset, uint32_t nbSymbols, const Sec
if (not this->stream_->can_read<Elf_Sym>()) {
break;
}
const Elf_Sym& raw_sym = this->stream_->read<Elf_Sym>();
const Elf_Sym raw_sym = this->stream_->read_conv<Elf_Sym>();
std::unique_ptr<Symbol> symbol{new Symbol{&raw_sym}};
std::string symbol_name = this->stream_->peek_string_at(string_section->file_offset() + raw_sym.st_name);
@ -1026,7 +1027,7 @@ void Parser::parse_dynamic_symbols(uint64_t offset) {
return;
}
const Elf_Sym& symbol_header = this->stream_->read<Elf_Sym>();
const Elf_Sym symbol_header = this->stream_->read_conv<Elf_Sym>();
std::unique_ptr<Symbol> symbol{new Symbol{&symbol_header}};
if (symbol_header.st_name > 0) {
@ -1073,7 +1074,7 @@ void Parser::parse_dynamic_entries(uint64_t offset, uint64_t size) {
if (not this->stream_->can_read<Elf_Dyn>()) {
break;
}
const Elf_Dyn& entry = this->stream_->read<Elf_Dyn>();
const Elf_Dyn entry = this->stream_->read_conv<Elf_Dyn>();
std::unique_ptr<DynamicEntry> dynamic_entry;
@ -1193,7 +1194,7 @@ void Parser::parse_dynamic_entries(uint64_t offset, uint64_t size) {
if (not this->stream_->can_read<Elf_Addr>()) {
break;
}
array.push_back(this->stream_->read<Elf_Addr>());
array.push_back(this->stream_->read_conv<Elf_Addr>());
}
} else {
@ -1235,7 +1236,7 @@ void Parser::parse_dynamic_entries(uint64_t offset, uint64_t size) {
if (not this->stream_->can_read<Elf_Addr>()) {
break;
}
array.push_back(this->stream_->read<Elf_Addr>());
array.push_back(this->stream_->read_conv<Elf_Addr>());
}
} else {
//TODO
@ -1278,7 +1279,7 @@ void Parser::parse_dynamic_entries(uint64_t offset, uint64_t size) {
break;
}
array.push_back(this->stream_->read<Elf_Addr>());
array.push_back(this->stream_->read_conv<Elf_Addr>());
}
} else {
//TODO: has DT_FINI but not DT_FINISZ
@ -1310,7 +1311,7 @@ void Parser::parse_pltgot_relocations(uint64_t offset, uint64_t size) {
if (not this->stream_->can_read<REL_T>()) {
break;
}
const REL_T& rel_hdr = this->stream_->read<REL_T>();
const REL_T rel_hdr = this->stream_->read_conv<REL_T>();
std::unique_ptr<Relocation> reloc{new Relocation{&rel_hdr}};
reloc->architecture_ = this->binary_->header_.machine_type();
reloc->purpose(RELOCATION_PURPOSES::RELOC_PURPOSE_PLTGOT);
@ -1343,7 +1344,7 @@ void Parser::parse_section_relocations(uint64_t offset, uint64_t size, Section *
if (not this->stream_->can_read<REL_T>()) {
break;
}
const REL_T& rel_hdr = this->stream_->read<REL_T>();
const REL_T rel_hdr = this->stream_->read_conv<REL_T>();
std::unique_ptr<Relocation> reloc{new Relocation{&rel_hdr}};
reloc->architecture_ = this->binary_->header_.machine_type();
@ -1394,7 +1395,7 @@ void Parser::parse_symbol_version_requirement(uint64_t offset, uint32_t nb_entri
if (not this->stream_->can_read<Elf_Verneed>(svr_offset + next_symbol_offset)) {
break;
}
const Elf_Verneed& header = this->stream_->peek<Elf_Verneed>(svr_offset + next_symbol_offset);
const Elf_Verneed header = this->stream_->peek_conv<Elf_Verneed>(svr_offset + next_symbol_offset);
std::unique_ptr<SymbolVersionRequirement> symbol_version_requirement{new SymbolVersionRequirement{&header}};
if (string_offset != 0) {
@ -1410,7 +1411,7 @@ void Parser::parse_symbol_version_requirement(uint64_t offset, uint32_t nb_entri
if (not this->stream_->can_read<Elf_Vernaux>(svr_offset + next_symbol_offset + header.vn_aux + next_aux_offset)) {
break;
}
const Elf_Vernaux& aux_header = this->stream_->peek<Elf_Vernaux>(svr_offset + next_symbol_offset + header.vn_aux + next_aux_offset);
const Elf_Vernaux aux_header = this->stream_->peek_conv<Elf_Vernaux>(svr_offset + next_symbol_offset + header.vn_aux + next_aux_offset);
std::unique_ptr<SymbolVersionAuxRequirement> svar{new SymbolVersionAuxRequirement{&aux_header}};
if (string_offset != 0) {
@ -1465,7 +1466,7 @@ void Parser::parse_symbol_version_definition(uint64_t offset, uint32_t nb_entrie
if (not this->stream_->can_read<Elf_Verdef>(offset + next_symbol_offset)) {
break;
}
const Elf_Verdef& svd_header = this->stream_->peek<Elf_Verdef>(offset + next_symbol_offset);
const Elf_Verdef svd_header = this->stream_->peek_conv<Elf_Verdef>(offset + next_symbol_offset);
std::unique_ptr<SymbolVersionDefinition> symbol_version_definition{new SymbolVersionDefinition{&svd_header}};
uint32_t nb_aux_symbols = svd_header.vd_cnt;
@ -1475,7 +1476,7 @@ void Parser::parse_symbol_version_definition(uint64_t offset, uint32_t nb_entrie
break;
}
const Elf_Verdaux& svda_header = this->stream_->peek<Elf_Verdaux>(offset + next_symbol_offset + svd_header.vd_aux + next_aux_offset);
const Elf_Verdaux svda_header = this->stream_->peek_conv<Elf_Verdaux>(offset + next_symbol_offset + svd_header.vd_aux + next_aux_offset);
if (string_offset != 0) {
std::string name = this->stream_->peek_string_at(string_offset + svda_header.vda_name);
@ -1531,7 +1532,7 @@ void Parser::parse_symbol_gnu_hash(uint64_t offset) {
this->stream_->setpos(offset);
const uint32_t* header = this->stream_->read_array<uint32_t>(4, /* check */false);
std::unique_ptr<uint32_t[]> header = this->stream_->read_conv_array<uint32_t>(4, /* check */false);
if (header == nullptr) {
LOG(ERROR) << "Can't read GNU Hash header";
@ -1558,7 +1559,7 @@ void Parser::parse_symbol_gnu_hash(uint64_t offset) {
LOG(ERROR) << "Can't read maskwords #" << std::dec << i;
break;
}
bloom_filters[i] = this->stream_->read<uint__>();
bloom_filters[i] = this->stream_->read_conv<uint__>();
}
gnuhash.bloom_filters_ = std::move(bloom_filters);
@ -1574,10 +1575,10 @@ void Parser::parse_symbol_gnu_hash(uint64_t offset) {
std::vector<uint32_t> buckets;
buckets.reserve(nbuckets);
const uint32_t* hash_buckets = this->stream_->read_array<uint32_t>(nbuckets, /* check */false);
std::unique_ptr<uint32_t[]> hash_buckets = this->stream_->read_conv_array<uint32_t>(nbuckets, false);
if (hash_buckets != nullptr) {
buckets = {hash_buckets, hash_buckets + nbuckets};
buckets = {hash_buckets.get(), hash_buckets.get() + nbuckets};
} else {
LOG(ERROR) << "GNU Hash, hash_buckets corrupted";
}
@ -1593,11 +1594,11 @@ void Parser::parse_symbol_gnu_hash(uint64_t offset) {
if (nb_hash < MAX_NB_HASH) {
std::vector<uint32_t> hashvalues;
hashvalues.reserve(nb_hash);
const uint32_t* hash_values = this->stream_->read_array<uint32_t>(nb_hash, /* check */false);
std::unique_ptr<uint32_t[]> hash_values = this->stream_->read_conv_array<uint32_t>(nb_hash, /* check */ false);
if (hash_values == nullptr) {
LOG(ERROR) << "Can't read hash table";
} else {
hashvalues = {hash_values, hash_values + nb_hash};
hashvalues = {hash_values.get(), hash_values.get() + nb_hash};
gnuhash.hash_values_ = std::move(hashvalues);
}
} else {