Skip to content
Permalink
Browse files
Add support for endianness
  • Loading branch information
yd0b0N authored and romainthomas committed May 15, 2018
1 parent 9e3b5b4 commit e794ac1
Show file tree
Hide file tree
Showing 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"

0 comments on commit e794ac1

Please sign in to comment.