Skip to content

Commit

Permalink
Use the span interface
Browse files Browse the repository at this point in the history
  • Loading branch information
romainthomas committed Mar 11, 2023
1 parent e9d1116 commit 6357c63
Show file tree
Hide file tree
Showing 12 changed files with 87 additions and 51 deletions.
21 changes: 12 additions & 9 deletions api/python/src/Abstract/objects/pyBinary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,15 +172,18 @@ void create<Binary>(py::module& m) {


.def("get_content_from_virtual_address",
&Binary::get_content_from_virtual_address,
R"delim(
Return the content located at the provided virtual address.
The virtual address is specified in the first argument and size to read (in bytes) in the second.
If the underlying binary is a PE, one can specify if the virtual address is a :attr:`~lief.Binary.VA_TYPES.RVA` or
a :attr:`~lief.Binary.VA_TYPES.VA`. By default, it is set to :attr:`~lief.Binary.VA_TYPES.AUTO`.
)delim",
"virtual_address"_a, "size"_a, "va_type"_a = Binary::VA_TYPES::AUTO)
[] (const Binary& self, uint64_t va, size_t size, Binary::VA_TYPES type) {
span<const uint8_t> content = self.get_content_from_virtual_address(va, size, type);
return py::memoryview::from_memory(content.data(), content.size());
},
R"delim(
Return the content located at the provided virtual address.
The virtual address is specified in the first argument and size to read (in bytes) in the second.
If the underlying binary is a PE, one can specify if the virtual address is a :attr:`~lief.Binary.VA_TYPES.RVA` or
a :attr:`~lief.Binary.VA_TYPES.VA`. By default, it is set to :attr:`~lief.Binary.VA_TYPES.AUTO`.
)delim",
"virtual_address"_a, "size"_a, "va_type"_a = Binary::VA_TYPES::AUTO)

.def_property_readonly("abstract",
[m] (py::object& self) {
Expand Down
6 changes: 4 additions & 2 deletions include/LIEF/Abstract/Binary.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "LIEF/Object.hpp"
#include "LIEF/iterators.hpp"
#include "LIEF/errors.hpp"
#include "LIEF/span.hpp"

#include "LIEF/Abstract/Header.hpp"
#include "LIEF/Abstract/Function.hpp"
Expand Down Expand Up @@ -160,8 +161,9 @@ class LIEF_API Binary : public Object {
VA_TYPES addr_type = VA_TYPES::AUTO) = 0;

//! Return the content located at the given virtual address
virtual std::vector<uint8_t> get_content_from_virtual_address(uint64_t virtual_address,
uint64_t size, VA_TYPES addr_type = VA_TYPES::AUTO) const = 0;
virtual span<const uint8_t>
get_content_from_virtual_address(uint64_t virtual_address, uint64_t size,
VA_TYPES addr_type = VA_TYPES::AUTO) const = 0;

//! Change the binary's name
void name(const std::string& name);
Expand Down
4 changes: 2 additions & 2 deletions include/LIEF/ELF/Binary.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -662,8 +662,8 @@ class LIEF_API Binary : public LIEF::Binary {
bool has(ELF_SECTION_TYPES type) const;

//! Return the content located at virtual address
std::vector<uint8_t> get_content_from_virtual_address(uint64_t virtual_address, uint64_t size,
LIEF::Binary::VA_TYPES addr_type = LIEF::Binary::VA_TYPES::AUTO) const override;
span<const uint8_t> get_content_from_virtual_address(uint64_t virtual_address, uint64_t size,
Binary::VA_TYPES addr_type = Binary::VA_TYPES::AUTO) const override;

//! Method associated with the visitor pattern.
void accept(LIEF::Visitor& visitor) const override;
Expand Down
5 changes: 3 additions & 2 deletions include/LIEF/MachO/Binary.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,8 +430,9 @@ class LIEF_API Binary : public LIEF::Binary {
LIEF::Binary::VA_TYPES addr_type = LIEF::Binary::VA_TYPES::AUTO) override;

//! Return the content located at virtual address
std::vector<uint8_t> get_content_from_virtual_address(uint64_t virtual_address, uint64_t size,
LIEF::Binary::VA_TYPES addr_type = LIEF::Binary::VA_TYPES::AUTO) const override;
span<const uint8_t> get_content_from_virtual_address(
uint64_t virtual_address, uint64_t size,
Binary::VA_TYPES addr_type = Binary::VA_TYPES::AUTO) const override;

//! The binary entrypoint
uint64_t entrypoint() const override;
Expand Down
5 changes: 3 additions & 2 deletions include/LIEF/PE/Binary.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -478,8 +478,9 @@ class LIEF_API Binary : public LIEF::Binary {
//! @param[in] virtual_address Virtual address of the data to retrieve
//! @param[in] size Size in bytes of the data to retrieve
//! @param[in] addr_type Type of the Virtual address: VA or RVA. Default: Auto
std::vector<uint8_t> get_content_from_virtual_address(uint64_t virtual_address, uint64_t size,
LIEF::Binary::VA_TYPES addr_type = LIEF::Binary::VA_TYPES::AUTO) const override;
span<const uint8_t> get_content_from_virtual_address(
uint64_t virtual_address, uint64_t size,
Binary::VA_TYPES addr_type = Binary::VA_TYPES::AUTO) const override;

//! Return the binary's entrypoint (It is the same value as OptionalHeader::addressof_entrypoint
uint64_t entrypoint() const override;
Expand Down
4 changes: 2 additions & 2 deletions src/ELF/Binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1799,7 +1799,7 @@ Section* Binary::section_from_virtual_address(uint64_t address, bool skip_nobits
return const_cast<Section*>(static_cast<const Binary*>(this)->section_from_virtual_address(address, skip_nobits));
}

std::vector<uint8_t> Binary::get_content_from_virtual_address(uint64_t virtual_address, uint64_t size, LIEF::Binary::VA_TYPES) const {
span<const uint8_t> Binary::get_content_from_virtual_address(uint64_t virtual_address, uint64_t size, Binary::VA_TYPES) const {
const Segment* segment = segment_from_virtual_address(virtual_address);
if (segment == nullptr) {
return {};
Expand All @@ -1812,7 +1812,7 @@ std::vector<uint8_t> Binary::get_content_from_virtual_address(uint64_t virtual_a
checked_size = checked_size - (offset + checked_size - content.size());
}

return {content.data() + offset, content.data() + offset + checked_size};
return {content.data() + offset, checked_size};
}


Expand Down
7 changes: 4 additions & 3 deletions src/ELF/Binary.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -623,21 +623,22 @@ void Binary::fix_got_entries(uint64_t from, uint64_t shift) {
return;
}
const uint64_t addr = dt_pltgot->value();
std::vector<uint8_t> content = get_content_from_virtual_address(addr, 3 * sizeof(ptr_t));
span<const uint8_t> content = get_content_from_virtual_address(addr, 3 * sizeof(ptr_t));
std::vector<uint8_t> content_vec(content.begin(), content.end());
if (content.size() != 3 * sizeof(ptr_t)) {
LIEF_ERR("Cant't read got entries!");
return;
}

auto got = reinterpret_cast<ptr_t*>(content.data());
auto got = reinterpret_cast<ptr_t*>(content_vec.data());
if (got[0] > 0 && got[0] > from) { // Offset to the dynamic section
got[0] += shift;
}

if (got[1] > 0 && got[1] > from) { // Prelinked value (unlikely?)
got[1] += shift;
}
patch_address(addr, content);
patch_address(addr, content_vec);
}

}
Expand Down
6 changes: 4 additions & 2 deletions src/MachO/Binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,9 @@ void Binary::patch_address(uint64_t address, uint64_t patch_value, size_t size,

}

std::vector<uint8_t> Binary::get_content_from_virtual_address(uint64_t virtual_address, uint64_t size, LIEF::Binary::VA_TYPES) const {
span<const uint8_t> Binary::get_content_from_virtual_address(
uint64_t virtual_address, uint64_t size, LIEF::Binary::VA_TYPES) const
{
const SegmentCommand* segment = segment_from_virtual_address(virtual_address);

if (segment == nullptr) {
Expand All @@ -184,7 +186,7 @@ std::vector<uint8_t> Binary::get_content_from_virtual_address(uint64_t virtual_a
checked_size = checked_size - (offset + checked_size - content.size());
}

return {content.data() + offset, content.data() + offset + checked_size};
return {content.data() + offset, checked_size};
}


Expand Down
2 changes: 1 addition & 1 deletion src/MachO/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ ok_error_t Parser::undo_reloc_bindings(uintptr_t base_address) {
auto& fixup = static_cast<RelocationFixup&>(reloc);
}
else if (RelocationDyld::classof(reloc)) {
std::vector<uint8_t> content = bin->get_content_from_virtual_address(reloc.address(), sizeof(uintptr_t));
span<const uint8_t> content = bin->get_content_from_virtual_address(reloc.address(), sizeof(uintptr_t));
if (content.empty() || content.size() != sizeof(uintptr_t)) {
LIEF_WARN("Can't access relocation data @0x{:x}", reloc.address());
continue;
Expand Down
61 changes: 41 additions & 20 deletions src/OAT/Parser.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,11 @@ void Parser::parse_binary<details::OAT64_t>() {
if (oat_data != nullptr) {
raw_oat.reserve(oat_data->size());

const std::vector<uint8_t>& raw_data = oat.get_content_from_virtual_address(oat_data->value(), oat_data->size());
std::move(std::begin(raw_data), std::end(raw_data), std::back_inserter(raw_oat));
span<const uint8_t> raw_data =
oat.get_content_from_virtual_address(oat_data->value(), oat_data->size());

std::copy(std::begin(raw_data), std::end(raw_data),
std::back_inserter(raw_oat));

data_address_ = oat_data->value();
data_size_ = oat_data->size();
Expand All @@ -76,14 +79,16 @@ void Parser::parse_binary<details::OAT64_t>() {
exec_start_ = oat_exec->value();
exec_size_ = oat_exec->size();

const std::vector<uint8_t>& raw_oatexec = oat.get_content_from_virtual_address(oat_exec->value(), oat_exec->size());
span<const uint8_t> raw_oatexec =
oat.get_content_from_virtual_address(oat_exec->value(), oat_exec->size());

uint32_t padding = exec_start_ - (data_address_ + data_size_);

raw_oat.reserve(raw_oat.size() + oat_exec->size() + padding);
raw_oat.insert(std::end(raw_oat), padding, 0);

std::move(std::begin(raw_oatexec), std::end(raw_oatexec), std::back_inserter(raw_oat));
std::copy(std::begin(raw_oatexec), std::end(raw_oatexec),
std::back_inserter(raw_oat));
}

uint32_t padding = align(raw_oat.size(), sizeof(uint32_t) * 8) - raw_oat.size();
Expand All @@ -105,8 +110,10 @@ void Parser::parse_binary<details::OAT79_t>() {
if (oat_data != nullptr) {
raw_oat.reserve(oat_data->size());

const std::vector<uint8_t>& raw_data = oat.get_content_from_virtual_address(oat_data->value(), oat_data->size());
std::move(std::begin(raw_data), std::end(raw_data), std::back_inserter(raw_oat));
span<const uint8_t> raw_data =
oat.get_content_from_virtual_address(oat_data->value(), oat_data->size());
std::move(std::begin(raw_data), std::end(raw_data),
std::back_inserter(raw_oat));

data_address_ = oat_data->value();
data_size_ = oat_data->size();
Expand All @@ -118,14 +125,16 @@ void Parser::parse_binary<details::OAT79_t>() {
exec_start_ = oat_exec->value();
exec_size_ = oat_exec->size();

const std::vector<uint8_t>& raw_oatexec = oat.get_content_from_virtual_address(oat_exec->value(), oat_exec->size());
span<const uint8_t> raw_oatexec =
oat.get_content_from_virtual_address(oat_exec->value(), oat_exec->size());

uint32_t padding = exec_start_ - (data_address_ + data_size_);

raw_oat.reserve(raw_oat.size() + oat_exec->size() + padding);
raw_oat.insert(std::end(raw_oat), padding, 0);

std::move(std::begin(raw_oatexec), std::end(raw_oatexec), std::back_inserter(raw_oat));
std::copy(std::begin(raw_oatexec), std::end(raw_oatexec),
std::back_inserter(raw_oat));
}

uint32_t padding = align(raw_oat.size(), sizeof(uint32_t) * 8) - raw_oat.size();
Expand All @@ -149,8 +158,10 @@ void Parser::parse_binary<details::OAT88_t>() {
if (oat_data != nullptr) {
raw_oat.reserve(oat_data->size());

const std::vector<uint8_t>& raw_data = oat.get_content_from_virtual_address(oat_data->value(), oat_data->size());
std::move(std::begin(raw_data), std::end(raw_data), std::back_inserter(raw_oat));
span<const uint8_t> raw_data =
oat.get_content_from_virtual_address(oat_data->value(), oat_data->size());
std::copy(std::begin(raw_data), std::end(raw_data),
std::back_inserter(raw_oat));

data_address_ = oat_data->value();
data_size_ = oat_data->size();
Expand All @@ -161,14 +172,16 @@ void Parser::parse_binary<details::OAT88_t>() {
exec_start_ = oat_exec->value();
exec_size_ = oat_exec->size();

const std::vector<uint8_t>& raw_oatexec = oat.get_content_from_virtual_address(oat_exec->value(), oat_exec->size());
span<const uint8_t> raw_oatexec =
oat.get_content_from_virtual_address(oat_exec->value(), oat_exec->size());

uint32_t padding = exec_start_ - (data_address_ + data_size_);

raw_oat.reserve(raw_oat.size() + oat_exec->size() + padding);
raw_oat.insert(std::end(raw_oat), padding, 0);

std::move(std::begin(raw_oatexec), std::end(raw_oatexec), std::back_inserter(raw_oat));
std::copy(std::begin(raw_oatexec), std::end(raw_oatexec),
std::back_inserter(raw_oat));
}

uint32_t padding = align(raw_oat.size(), sizeof(uint32_t) * 8) - raw_oat.size();
Expand All @@ -192,8 +205,10 @@ void Parser::parse_binary<details::OAT124_t>() {
if (oat_data != nullptr) {
raw_oat.reserve(oat_data->size());

const std::vector<uint8_t>& raw_data = oat.get_content_from_virtual_address(oat_data->value(), oat_data->size());
std::move(std::begin(raw_data), std::end(raw_data), std::back_inserter(raw_oat));
span<const uint8_t> raw_data =
oat.get_content_from_virtual_address(oat_data->value(), oat_data->size());
std::copy(std::begin(raw_data), std::end(raw_data),
std::back_inserter(raw_oat));

data_address_ = oat_data->value();
data_size_ = oat_data->size();
Expand All @@ -204,14 +219,16 @@ void Parser::parse_binary<details::OAT124_t>() {
exec_start_ = oat_exec->value();
exec_size_ = oat_exec->size();

const std::vector<uint8_t>& raw_oatexec = oat.get_content_from_virtual_address(oat_exec->value(), oat_exec->size());
span<const uint8_t> raw_oatexec =
oat.get_content_from_virtual_address(oat_exec->value(), oat_exec->size());

uint32_t padding = exec_start_ - (data_address_ + data_size_);

raw_oat.reserve(raw_oat.size() + oat_exec->size() + padding);
raw_oat.insert(std::end(raw_oat), padding, 0);

std::move(std::begin(raw_oatexec), std::end(raw_oatexec), std::back_inserter(raw_oat));
std::copy(std::begin(raw_oatexec), std::end(raw_oatexec),
std::back_inserter(raw_oat));
}

uint32_t padding = align(raw_oat.size(), sizeof(uint32_t) * 8) - raw_oat.size();
Expand All @@ -235,8 +252,10 @@ void Parser::parse_binary<details::OAT131_t>() {
if (oat_data != nullptr) {
raw_oat.reserve(oat_data->size());

const std::vector<uint8_t>& raw_data = oat.get_content_from_virtual_address(oat_data->value(), oat_data->size());
std::move(std::begin(raw_data), std::end(raw_data), std::back_inserter(raw_oat));
span<const uint8_t> raw_data =
oat.get_content_from_virtual_address(oat_data->value(), oat_data->size());
std::copy(std::begin(raw_data), std::end(raw_data),
std::back_inserter(raw_oat));

data_address_ = oat_data->value();
data_size_ = oat_data->size();
Expand All @@ -247,14 +266,16 @@ void Parser::parse_binary<details::OAT131_t>() {
exec_start_ = oat_exec->value();
exec_size_ = oat_exec->size();

const std::vector<uint8_t>& raw_oatexec = oat.get_content_from_virtual_address(oat_exec->value(), oat_exec->size());
span<const uint8_t> raw_oatexec =
oat.get_content_from_virtual_address(oat_exec->value(), oat_exec->size());

uint32_t padding = exec_start_ - (data_address_ + data_size_);

raw_oat.reserve(raw_oat.size() + oat_exec->size() + padding);
raw_oat.insert(std::end(raw_oat), padding, 0);

std::move(std::begin(raw_oatexec), std::end(raw_oatexec), std::back_inserter(raw_oat));
std::copy(std::begin(raw_oatexec), std::end(raw_oatexec),
std::back_inserter(raw_oat));
}

uint32_t padding = align(raw_oat.size(), sizeof(uint32_t) * 8) - raw_oat.size();
Expand Down
8 changes: 6 additions & 2 deletions src/OAT/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ bool is_oat(const std::vector<uint8_t>& raw) {

bool is_oat(const ELF::Binary& elf) {
if (const auto* oatdata = elf.get_dynamic_symbol("oatdata")) {
const std::vector<uint8_t>& header = elf.get_content_from_virtual_address(oatdata->value(), sizeof(details::oat_magic));
span<const uint8_t> header =
elf.get_content_from_virtual_address(oatdata->value(), sizeof(details::oat_magic));
return std::equal(std::begin(header), std::end(header),
std::begin(details::oat_magic));

Expand Down Expand Up @@ -80,7 +81,10 @@ oat_version_t version(const std::vector<uint8_t>& raw) {

oat_version_t version(const ELF::Binary& elf) {
if (const auto* oatdata = elf.get_dynamic_symbol("oatdata")) {
const std::vector<uint8_t>& header = elf.get_content_from_virtual_address(oatdata->value() + sizeof(details::oat_magic), sizeof(details::oat_version));
span<const uint8_t> header =
elf.get_content_from_virtual_address(oatdata->value() + sizeof(details::oat_magic),
sizeof(details::oat_version));

if (header.size() != sizeof(details::oat_version)) {
return 0;
}
Expand Down
9 changes: 5 additions & 4 deletions src/PE/Binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include "LIEF/utils.hpp"
#include "LIEF/BinaryStream/VectorStream.hpp"
#include "LIEF/BinaryStream/SpanStream.hpp"
#include "LIEF/iostream.hpp"

#include "LIEF/Abstract/Relocation.hpp"
Expand Down Expand Up @@ -1420,7 +1421,7 @@ void Binary::patch_address(uint64_t address, uint64_t patch_value,
}
}

std::vector<uint8_t> Binary::get_content_from_virtual_address(uint64_t virtual_address,
span<const uint8_t> Binary::get_content_from_virtual_address(uint64_t virtual_address,
uint64_t size, LIEF::Binary::VA_TYPES addr_type) const {

uint64_t rva = virtual_address;
Expand Down Expand Up @@ -1449,7 +1450,7 @@ std::vector<uint8_t> Binary::get_content_from_virtual_address(uint64_t virtual_a
checked_size = checked_size - delta_off;
}

return {content.data() + offset, content.data() + offset + checked_size};
return {content.data() + offset, checked_size};

}

Expand Down Expand Up @@ -1559,8 +1560,8 @@ LIEF::Binary::functions_t Binary::exception_functions() const {


const DataDirectory& exception_dir = data_directory(DATA_DIRECTORY::EXCEPTION_TABLE);
std::vector<uint8_t> exception_data = get_content_from_virtual_address(exception_dir.RVA(), exception_dir.size());
VectorStream vs{std::move(exception_data)};
span<const uint8_t> exception_data = get_content_from_virtual_address(exception_dir.RVA(), exception_dir.size());
SpanStream vs{exception_data};
const size_t nb_entries = vs.size() / sizeof(details::pe_exception_entry_x64); // TODO: Handle other architectures

for (size_t i = 0; i < nb_entries; ++i) {
Expand Down

0 comments on commit 6357c63

Please sign in to comment.