Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes to support LIEF v0.15.1. #11

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/intmem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@
#include <cstring>
#include <type_traits>

#ifdef _MSC_VER
#include <stdlib.h>
#endif

namespace intmem {

// bswap functions. Uses GCC/clang/MSVC intrinsics.
#ifdef _MSC_VER
#include <stdlib.h>
static uint8_t bswap(uint8_t V) { return V; }
static uint16_t bswap(unsigned short V) { return _byteswap_ushort(V); }
static_assert(sizeof(uint32_t) == sizeof(unsigned long),
Expand Down
61 changes: 31 additions & 30 deletions src/loaders/ELF.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#include "logging.hpp"
#include <LIEF/ELF.hpp>
#include <QBDL/Engine.hpp>
#include <QBDL/arch.hpp>
#include <QBDL/loaders/ELF.hpp>
#include <QBDL/utils.hpp>

#include "logging.hpp"

using namespace LIEF::ELF;

namespace QBDL::Loaders {
Expand All @@ -22,8 +23,8 @@ uintptr_t ELF::dl_resolve(void *loader, uintptr_t hint) {

const ARCH arch = ldr.get_binary().header().machine_type();
uintptr_t plt_sym_idx = hint;
if (arch == ARCH::EM_AARCH64) {
const uintptr_t got_base = bin.get(DYNAMIC_TAGS::DT_PLTGOT).value();
if (arch == ARCH::AARCH64) {
const uintptr_t got_base = bin.get(DynamicEntry::TAG::PLTGOT)->value();
plt_sym_idx =
(plt_sym_idx - ldr.base_address_ - got_base) / sizeof(uintptr_t);
// We need to remove the first reserved entries to get the index
Expand All @@ -38,7 +39,7 @@ uintptr_t ELF::dl_resolve(void *loader, uintptr_t hint) {
}

const Relocation &plt_reloc = pltgot[plt_sym_idx];
const Symbol &sym = plt_reloc.symbol();
const Symbol &sym = *plt_reloc.symbol();
const uintptr_t sym_addr = ldr.engine_->symlink(ldr, sym);
const uintptr_t addr_target = ldr.get_address(plt_reloc.address());

Expand Down Expand Up @@ -87,7 +88,7 @@ uint64_t ELF::get_address(const std::string &sym) const {
const Binary &binary = get_binary();
const LIEF::Symbol *symbol = nullptr;
if (binary.has_symbol(sym)) {
symbol = &binary.get_symbol(sym);
symbol = binary.get_symbol(sym);
}
if (symbol == nullptr) {
return 0;
Expand Down Expand Up @@ -127,13 +128,13 @@ void ELF::load(BIND binding) {
// Map segments
// =======================================================
for (const Segment &segment : binary.segments()) {
if (segment.type() != SEGMENT_TYPES::PT_LOAD) {
if (segment.type() != Segment::TYPE::LOAD) {
continue;
}
const uint64_t rva = get_rva(binary, segment.virtual_address());

Logger::debug("Mapping {} - 0x{:x}", to_string(segment.type()), rva);
const std::vector<uint8_t> &content = segment.content();
const auto &content = segment.content();
if (content.size() > 0) {
engine_->mem().write(base_address + rva, content.data(), content.size());
}
Expand All @@ -143,12 +144,12 @@ void ELF::load(BIND binding) {
relocation_fcn_t relocator = nullptr;
const LIEF::ELF::ARCH arch = get_binary().header().machine_type();
switch (arch) {
case LIEF::ELF::ARCH::EM_AARCH64: {
case LIEF::ELF::ARCH::AARCH64: {
relocator = &ELF::reloc_aarch64;
break;
}

case LIEF::ELF::ARCH::EM_X86_64: {
case LIEF::ELF::ARCH::X86_64: {
relocator = &ELF::reloc_x86_64;
break;
}
Expand Down Expand Up @@ -211,32 +212,32 @@ uintptr_t ELF::resolve_or_symlink(const LIEF::ELF::Symbol &sym) {

void ELF::reloc_x86_64(const LIEF::ELF::Relocation &reloc) {
const Arch binarch = arch();
const auto type = static_cast<RELOC_x86_64>(reloc.type());
const auto type = reloc.type();
const uintptr_t addr_target = base_address_ + reloc.address();
switch (type) {
case RELOC_x86_64::R_X86_64_64: {
const uintptr_t sym_addr = resolve_or_symlink(reloc.symbol());
case LIEF::ELF::Relocation::TYPE::X86_64_64: {
const uintptr_t sym_addr = resolve_or_symlink(*reloc.symbol());
engine_->mem().write_ptr(binarch, addr_target, sym_addr + reloc.addend());
break;
}

case RELOC_x86_64::R_X86_64_RELATIVE: {
case LIEF::ELF::Relocation::TYPE::X86_64_RELATIVE: {
engine_->mem().write_ptr(binarch, addr_target,
base_address_ + reloc.addend());
break;
}

case RELOC_x86_64::R_X86_64_GLOB_DAT:
case RELOC_x86_64::R_X86_64_JUMP_SLOT: {
const uintptr_t sym_addr = resolve_or_symlink(reloc.symbol());
case LIEF::ELF::Relocation::TYPE::X86_64_GLOB_DAT:
case LIEF::ELF::Relocation::TYPE::X86_64_JUMP_SLOT: {
const uintptr_t sym_addr = resolve_or_symlink(*reloc.symbol());
engine_->mem().write_ptr(binarch, addr_target, sym_addr);
break;
}

case RELOC_x86_64::R_X86_64_COPY: {
const uintptr_t sym_addr = engine_->symlink(*this, reloc.symbol());
case LIEF::ELF::Relocation::TYPE::X86_64_COPY: {
const uintptr_t sym_addr = engine_->symlink(*this, *reloc.symbol());
engine_->mem().write(addr_target, reinterpret_cast<const void *>(sym_addr),
reloc.symbol().size());
reloc.symbol()->size());
break;
}

Expand All @@ -250,35 +251,35 @@ Arch ELF::arch() const { return Arch::from_bin(get_binary()); }

void ELF::reloc_aarch64(const LIEF::ELF::Relocation &reloc) {
const Arch binarch = arch();
const auto type = static_cast<RELOC_AARCH64>(reloc.type());
const auto type = reloc.type();
const uintptr_t addr_target = base_address_ + reloc.address();
switch (type) {
case RELOC_AARCH64::R_AARCH64_RELATIVE: {
case LIEF::ELF::Relocation::TYPE::AARCH64_RELATIVE: {
engine_->mem().write_ptr(binarch, addr_target,
base_address_ + reloc.addend());
break;
}

case RELOC_AARCH64::R_AARCH64_JUMP_SLOT: {
const uintptr_t sym_addr = resolve_or_symlink(reloc.symbol());
case LIEF::ELF::Relocation::TYPE::AARCH64_JUMP_SLOT: {
const uintptr_t sym_addr = resolve_or_symlink(*reloc.symbol());
engine_->mem().write_ptr(binarch, addr_target, sym_addr + reloc.addend());
break;
}
case RELOC_AARCH64::R_AARCH64_GLOB_DAT: {
const uintptr_t sym_addr = resolve_or_symlink(reloc.symbol());
case LIEF::ELF::Relocation::TYPE::AARCH64_GLOB_DAT: {
const uintptr_t sym_addr = resolve_or_symlink(*reloc.symbol());
engine_->mem().write_ptr(binarch, addr_target, sym_addr + reloc.addend());
break;
}

case RELOC_AARCH64::R_AARCH64_COPY: {
const uintptr_t sym_addr = engine_->symlink(*this, reloc.symbol());
case LIEF::ELF::Relocation::TYPE::AARCH64_COPY: {
const uintptr_t sym_addr = engine_->symlink(*this, *reloc.symbol());
engine_->mem().write(addr_target, reinterpret_cast<const void *>(sym_addr),
reloc.symbol().size());
reloc.symbol()->size());
break;
}

case RELOC_AARCH64::R_AARCH64_ABS64: {
const uintptr_t sym_addr = resolve_or_symlink(reloc.symbol());
case LIEF::ELF::Relocation::TYPE::AARCH64_ABS64: {
const uintptr_t sym_addr = resolve_or_symlink(*reloc.symbol());
engine_->mem().write_ptr(binarch, addr_target, sym_addr + reloc.addend());
break;
}
Expand Down
21 changes: 10 additions & 11 deletions src/loaders/MachO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ MachO::from_binary(std::unique_ptr<LIEF::MachO::Binary> bin,
std::unique_ptr<LIEF::MachO::Binary>
MachO::take_arch_binary(LIEF::MachO::FatBinary &fatbin, Arch const &arch) {
for (size_t i = 0; i < fatbin.size(); ++i) {
auto &bin = fatbin[i];
auto &bin = *fatbin[i];
if (Arch::from_bin(bin) == arch) {
return fatbin.take(i);
}
Expand Down Expand Up @@ -112,7 +112,7 @@ bool MachO::load(BIND binding) {
const uint64_t rva = get_rva(binary, segment.virtual_address());

Logger::debug("Mapping {} - 0x{:x}", segment.name(), rva);
const std::vector<uint8_t> &content = segment.content();
const auto &content = segment.content();

if (content.size() > 0) {
engine_->mem().write(base_address + rva, content.data(), content.size());
Expand All @@ -123,15 +123,15 @@ bool MachO::load(BIND binding) {
// =======================================================
for (const LIEF::MachO::Relocation &relocation : binary.relocations()) {
if (relocation.origin() ==
LIEF::MachO::RELOCATION_ORIGINS::ORIGIN_RELOC_TABLE) {
LIEF::MachO::Relocation::ORIGIN::RELOC_TABLE) {
Logger::warn("Relocation not handled!");
continue;
}

const auto rtype =
static_cast<LIEF::MachO::REBASE_TYPES>(relocation.type());
static_cast<LIEF::MachO::DyldInfo::REBASE_TYPE>(relocation.type());
switch (rtype) {
case LIEF::MachO::REBASE_TYPES::REBASE_TYPE_POINTER: {
case LIEF::MachO::DyldInfo::REBASE_TYPE::POINTER: {
const uint64_t rva = get_rva(binary, relocation.address());
const uint64_t rel_ptr = base_address + rva;
uint64_t rel_ptr_val = engine_->mem().read_ptr(binarch, rel_ptr);
Expand Down Expand Up @@ -168,18 +168,17 @@ bool MachO::load(BIND binding) {
void MachO::bind_now() {
const LIEF::MachO::Binary &binary = get_binary();
const Arch binarch = arch();
for (const LIEF::MachO::BindingInfo &info : binary.dyld_info().bindings()) {
// TODO(romain): Add BIND_CLASS_THREADED when moving to LIEF 0.12.0
if (info.binding_class() != LIEF::MachO::BINDING_CLASS::BIND_CLASS_LAZY &&
info.binding_class() !=
LIEF::MachO::BINDING_CLASS::BIND_CLASS_STANDARD) {
for (const LIEF::MachO::DyldBindingInfo &info : binary.dyld_info()->bindings()) {
if (info.binding_class() != LIEF::MachO::DyldBindingInfo::CLASS::LAZY &&
info.binding_class() != LIEF::MachO::DyldBindingInfo::CLASS::STANDARD &&
info.binding_class() != LIEF::MachO::DyldBindingInfo::CLASS::THREADED) {
continue;
}
if (!info.has_symbol()) {
Logger::warn("Lazy bindings isn't linked to a symbol!");
continue;
}
const auto &sym = info.symbol();
const auto &sym = *info.symbol();
const uint64_t ptrRVA = get_rva(binary, info.address());
const uint64_t ptrAddr = base_address_ + ptrRVA;
const uint64_t symAddr = engine_->symlink(*this, sym);
Expand Down
6 changes: 3 additions & 3 deletions src/loaders/PE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ uint64_t PE::get_address(const std::string &sym) const {
const Binary &binary = get_binary();
const LIEF::Symbol *symbol = nullptr;
if (binary.has_symbol(sym)) {
symbol = &binary.get_symbol(sym);
symbol = binary.get_symbol(sym);
}
if (symbol == nullptr) {
return 0;
Expand Down Expand Up @@ -86,7 +86,7 @@ void PE::load(BIND binding) {
section.virtual_address(),
section.virtual_address() + section.virtual_size());
const uint64_t rva = section.virtual_address();
const std::vector<uint8_t> &content = section.content();
const auto &content = section.content();
if (!content.empty()) {
engine_->mem().write(base_address_ + rva, content.data(), content.size());
}
Expand All @@ -101,7 +101,7 @@ void PE::load(BIND binding) {
const uint64_t rva = relocation.virtual_address();
for (const RelocationEntry &entry : relocation.entries()) {
switch (entry.type()) {
case RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_DIR64: {
case RelocationEntry::BASE_TYPES::DIR64: {
const uint64_t relocation_addr =
base_address_ + rva + entry.position();
const uint64_t value =
Expand Down