Compare commits

...
Author SHA1 Message Date
Romain 12cf390bc8 Merge pull request #298 from wisk/missing_defines_undef
Add missing defines in ELF undef.h
2019-05-17 22:47:31 +02:00
wisk 764a40f9f4 Add missing defines in ELF undef.hundef.h 2019-05-17 09:05:37 -07:00
Romain Thomas 337f9bf585 First experimentation to create an ELF from scratch 2019-05-14 21:10:16 +02:00
15 changed files with 592 additions and 30 deletions
+3 -1
View File
@@ -137,6 +137,8 @@ endif()
ADD_FLAG_IF_SUPPORTED("-Wno-macro-redefined" NO_MACRO_REDEFINED)
ADD_FLAG_IF_SUPPORTED("-fdiagnostics-color=always" DIAGNOSTICS_COLOR)
ADD_FLAG_IF_SUPPORTED("-fcolor-diagnostics" COLOR_DIAGNOSTICS)
ADD_FLAG_IF_SUPPORTED("-Wno-deprecated-declarations" NO_DEPRECATED_DECLARATIONS)
set_target_properties(pyLIEF PROPERTIES PREFIX "" OUTPUT_NAME "lief")
@@ -144,7 +146,7 @@ add_dependencies(pyLIEF lief_pybind11)
if(APPLE)
set_target_properties(pyLIEF PROPERTIES MACOSX_RPATH ".")
set_target_properties(pyLIEF PROPERTIES LINK_FLAGS "-undefined dynamic_lookup ")
set_target_properties(pyLIEF PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
endif()
set_target_properties(pyLIEF PROPERTIES PREFIX "")
+9 -1
View File
@@ -42,7 +42,15 @@ void create<Binary>(py::module& m) {
// Binary object
py::class_<Binary, LIEF::Binary>(m, "Binary", "ELF binary representation")
.def(py::init<const std::string&, ELF_CLASS>())
//.def(py::init<const std::string&, ELF_CLASS>())
.def("create_lief_core",
&Binary::create_lief_core,
py::return_value_policy::take_ownership)
.def("create_lief_dyn",
&Binary::create_lief_dyn,
py::return_value_policy::take_ownership)
.def_property_readonly("type",
&Binary::type,
+7
View File
@@ -69,6 +69,13 @@ void init_enums(py::module& m) {
.value(PY_ENUM(E_TYPE::ET_EXEC))
.value(PY_ENUM(E_TYPE::ET_DYN))
.value(PY_ENUM(E_TYPE::ET_CORE))
.value(PY_ENUM(E_TYPE::ET_PSPEXEC))
.value(PY_ENUM(E_TYPE::ET_LIEF))
.value(PY_ENUM(E_TYPE::ET_LIEF_CORE))
.value(PY_ENUM(E_TYPE::ET_HIOS))
.value(PY_ENUM(E_TYPE::ET_LOPROC))
.value(PY_ENUM(E_TYPE::ET_HIPROC));
+33
View File
@@ -0,0 +1,33 @@
import lief
from lief import Logger
Logger.set_level(lief.LOGGING_LEVEL.DEBUG)
b = lief.ELF.Binary.create_lief_dyn(lief.ELF.ARCH.x86_64)
print(b)
for i in range(3):
s = lief.ELF.Section(f".foo{i}")
s.content = [i & 0xFF for x in range(0x1000)]
b.add(s, True)
print(b)
b.write("/tmp/out")
b = lief.ELF.Binary.create_lief_dyn(lief.ELF.ARCH.x86_64)
print(b)
for i in range(3):
s = lief.ELF.Segment()
s.type = lief.ELF.SEGMENT_TYPES.LOAD
s.content = [i & 0xFF for x in range(0x1000)]
b.add(s)
for i in range(10):
s = lief.ELF.Section(f".foo{i}")
b.add(s, False)
print(b)
b.write("/tmp/out2")
+1
View File
@@ -5,6 +5,7 @@ set(LIEF_ELF_CPP_EXAMPLES
elf_section_rename.cpp
elf_strip.cpp
elf_symbols.cpp
coredump.cpp
)
set(LIEF_PE_CPP_EXAMPLES
+44
View File
@@ -0,0 +1,44 @@
#include <link.h>
#include <LIEF/ELF.hpp>
#include <iostream>
#include <sstream>
using namespace LIEF::ELF;
void dump(void) {
std::unique_ptr<Binary> core = Binary::create_lief_core(LIEF::ELF::ARCH::EM_X86_64);
dl_iterate_phdr([] (dl_phdr_info* info, size_t size, void* data) {
Binary* core = reinterpret_cast<Binary*>(data);
if (info->dlpi_name == nullptr) {
return 0;
}
for (size_t i = 0; i < info->dlpi_phnum; ++i) {
std::ostringstream oss;
oss << "." << info->dlpi_name << "." << std::dec << i;
Section section{oss.str()};
const uint8_t* start = reinterpret_cast<uint8_t*>(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
const uint8_t* stop = start + info->dlpi_phdr[i].p_memsz;
//std::cout << std::showbase << std::hex << info->dlpi_addr + info->dlpi_phdr[i].p_vaddr << std::endl;
section.content({start, stop});
Section& added = core->add(section, true);
added.virtual_address(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
}
std::cout << info->dlpi_name << std::endl;
return 0;
}, core.get());
core->write("/tmp/bar");
}
int main(int argc, char** argv) {
dump();
return 0;
}
+10 -1
View File
@@ -62,8 +62,11 @@ class LIEF_API Binary : public LIEF::Binary {
using string_list_t = std::vector<std::string>;
using overlay_t = std::vector<uint8_t>;
static std::unique_ptr<Binary> create_lief_core(ARCH arch);
static std::unique_ptr<Binary> create_lief_dyn(ARCH arch);
public:
Binary(const std::string& name, ELF_CLASS type);
//Binary(const std::string& name, ELF_CLASS type);
Binary& operator=(const Binary& ) = delete;
Binary(const Binary& copy) = delete;
@@ -566,6 +569,12 @@ class LIEF_API Binary : public LIEF::Binary {
Section& add_section(const Section& section);
symbols_t static_dyn_symbols(void) const;
template<class T>
LIEF_LOCAL static std::unique_ptr<Binary> create_lief_core_impl(ARCH arch, ELF_CLASS clazz);
template<class T>
LIEF_LOCAL static std::unique_ptr<Binary> create_lief_dyn_impl(ARCH arch, ELF_CLASS clazz);
std::string shstrtab_name(void) const;
LIEF::Binary::functions_t tor_functions(DYNAMIC_TAGS tag) const;
+11 -2
View File
@@ -22,8 +22,17 @@ enum _LIEF_EN(E_TYPE) {
_LIEF_EI(ET_EXEC) = 2, /**< Executable file */
_LIEF_EI(ET_DYN) = 3, /**< Shared object file */
_LIEF_EI(ET_CORE) = 4, /**< Core file */
_LIEF_EI(ET_LOPROC) = 0xff00, /**< Beginning of processor-specific codes */
_LIEF_EI(ET_HIPROC) = 0xffff /**< Processor-specific */
_LIEF_EI(ET_PSPEXEC) = 0xFFA0, /**< Sony PSP executable file */
_LIEF_EI(ET_LIEF) = 0xFF10, /**< Custom LIEF format */
_LIEF_EI(ET_LIEF_CORE) = 0xFF11, /**< Custom LIEF Core file */
_LIEF_EI(ET_LIEF_EXEC) = 0xFF12, /**< Custom LIEF Executable file */
_LIEF_EI(ET_LIEF_DYN) = 0xFF13, /**< Custom LIEF Dynamic file */
_LIEF_EI(ET_HIOS) = 0xFEFF, /**< Operating system-specific */
_LIEF_EI(ET_LOPROC) = 0xFF00, /**< Beginning of processor-specific codes */
_LIEF_EI(ET_HIPROC) = 0xFFFF, /**< Processor-specific */
};
+10
View File
@@ -42,6 +42,7 @@
#undef ET_CORE
#undef ET_LOPROC
#undef ET_HIPROC
#undef ET_HIOS
#undef EV_NONE
@@ -674,6 +675,15 @@
#undef NT_SIGINFO
#undef NT_FILE
#undef NT_PRXFPREG
#undef NT_ARM_VFP
#undef NT_ARM_TLS
#undef NT_ARM_HW_BREAK
#undef NT_ARM_HW_WATCH
#undef NT_ARM_SYSTEM_CALL
#undef NT_ARM_SVE
#undef NT_386_TLS
#undef NT_386_IOPERM
#undef NT_386_XSTATE
#undef ELF_NOTE_UNKNOWN
#undef ELF_NOTE_OS_LINUX
+71 -5
View File
@@ -41,21 +41,75 @@
#include "LIEF/ELF/hash.hpp"
#include "Binary.tcc"
#include "BinaryDyn.tcc"
#include "Object.tcc"
namespace LIEF {
namespace ELF {
Binary::Binary(void) = default;
Binary::Binary(const std::string& name, ELF_CLASS type) : type_{type} {
this->name_ = name;
if (type_ == ELF_CLASS::ELFCLASS32) {
}
else if (type_ == ELF_CLASS::ELFCLASS32) {
std::unique_ptr<Binary> Binary::create_lief_core(ARCH arch) {
switch (arch) {
case ARCH::EM_X86_64:
{
return create_lief_core_impl<ELF64>(arch, ELF_CLASS::ELFCLASS64);
}
case ARCH::EM_386:
{
return create_lief_core_impl<ELF32>(arch, ELF_CLASS::ELFCLASS32);
}
case ARCH::EM_ARM:
{
return create_lief_core_impl<ELF32>(arch, ELF_CLASS::ELFCLASS32);
}
case ARCH::EM_AARCH64:
{
return create_lief_core_impl<ELF64>(arch, ELF_CLASS::ELFCLASS64);
}
default:
{
return nullptr;
}
}
}
std::unique_ptr<Binary> Binary::create_lief_dyn(ARCH arch) {
switch (arch) {
case ARCH::EM_X86_64:
{
return create_lief_dyn_impl<ELF64>(arch, ELF_CLASS::ELFCLASS64);
}
case ARCH::EM_386:
{
return create_lief_dyn_impl<ELF32>(arch, ELF_CLASS::ELFCLASS32);
}
case ARCH::EM_ARM:
{
return create_lief_dyn_impl<ELF32>(arch, ELF_CLASS::ELFCLASS32);
}
case ARCH::EM_AARCH64:
{
return create_lief_dyn_impl<ELF64>(arch, ELF_CLASS::ELFCLASS64);
}
default:
{
return nullptr;
}
}
}
Header& Binary::header(void) {
return const_cast<Header&>(static_cast<const Binary*>(this)->header());
}
@@ -1187,6 +1241,18 @@ Segment& Binary::add(const Segment& segment, uint64_t base) {
break;
}
case E_TYPE::ET_LIEF_CORE:
{
return this->add_segment<E_TYPE::ET_LIEF_CORE>(segment, new_base);
break;
}
case E_TYPE::ET_LIEF_DYN:
{
return this->add_segment<E_TYPE::ET_LIEF_DYN>(segment, new_base);
break;
}
default:
{
throw not_implemented(std::string("Adding segment for ") + to_string(this->header().file_type()) + " is not implemented");
+177 -11
View File
@@ -268,7 +268,6 @@ Segment& Binary::add_segment<E_TYPE::ET_EXEC>(const Segment& segment, uint64_t b
// ------------------------------------------
// Part 1: Move PHDR at the end of the binary
// ------------------------------------------
header.numberof_segments(header.numberof_segments() + 1);
auto&& it_text_segment = std::find_if(
@@ -279,11 +278,12 @@ Segment& Binary::add_segment<E_TYPE::ET_EXEC>(const Segment& segment, uint64_t b
s->has(ELF_SEGMENT_FLAGS::PF_X) and s->has(ELF_SEGMENT_FLAGS::PF_R);
});
if (it_text_segment == std::end(this->segments_)) {
throw not_found("Unable to find a LOAD segment with 'r-x' permissions");
Segment* text_segment = nullptr;
if (it_text_segment != std::end(this->segments_)) {
//throw not_found("Unable to find a LOAD segment with 'r-x' permissions");
text_segment = *it_text_segment;
}
Segment* text_segment = *it_text_segment;
uint64_t last_offset_sections = std::accumulate(
std::begin(this->sections_),
@@ -329,19 +329,19 @@ Segment& Binary::add_segment<E_TYPE::ET_EXEC>(const Segment& segment, uint64_t b
VLOG(VDEBUG) << "New PHDR size 0x" << std::hex << new_phdr_size;
phdr_segment->file_offset(new_phdr_offset);
phdr_segment->virtual_address(text_segment->virtual_address() - text_segment->file_offset() + phdr_segment->file_offset());
//phdr_segment->file_offset(new_phdr_offset);
//phdr_segment->virtual_address(text_segment->virtual_address() - text_segment->file_offset() + phdr_segment->file_offset());
phdr_segment->physical_address(phdr_segment->virtual_address());
//phdr_segment->physical_address(phdr_segment->virtual_address());
phdr_segment->physical_size(new_phdr_size);
phdr_segment->virtual_size(phdr_segment->virtual_size() + phdr_size);
uint64_t gap = phdr_segment->file_offset() + phdr_segment->physical_size();
gap -= text_segment->file_offset() + text_segment->physical_size();
//uint64_t gap = phdr_segment->file_offset() + phdr_segment->physical_size();
// gap -= text_segment->file_offset() + text_segment->physical_size();
text_segment->physical_size(text_segment->physical_size() + gap);
text_segment->virtual_size(text_segment->virtual_size() + gap);
//text_segment->physical_size(text_segment->physical_size() + gap);
//text_segment->virtual_size(text_segment->virtual_size() + gap);
// Clear PHDR segment
phdr_segment->content(std::vector<uint8_t>(phdr_segment->physical_size(), 0));
@@ -644,6 +644,7 @@ Section& Binary::add_section<true>(const Section& section) {
new_section->size(segment_added.physical_size());
new_section->offset(segment_added.file_offset());
new_section->original_size_ = segment_added.physical_size();
new_section->segments_.push_back(&segment_added);
this->header().numberof_sections(this->header().numberof_sections() + 1);
@@ -686,5 +687,170 @@ Section& Binary::add_section<false>(const Section& section) {
return *(this->sections_.back());
}
// ============
// ET_LIEF_CORE
// ============
template<>
Segment& Binary::add_segment<E_TYPE::ET_LIEF_CORE>(const Segment& segment, uint64_t base) {
Header& header = this->header();
uint64_t last_offset_sections = std::accumulate(
std::begin(this->sections_),
std::end(this->sections_), 0,
[] (uint64_t offset, const Section* section) {
return std::max<uint64_t>(section->file_offset() + section->size(), offset);
});
uint64_t last_offset_segments = std::accumulate(
std::begin(this->segments_),
std::end(this->segments_), 0,
[] (uint64_t offset, const Segment* segment) {
return std::max<uint64_t>(segment->file_offset() + segment->physical_size(), offset);
});
uint64_t last_offset = std::max<uint64_t>(last_offset_sections, last_offset_segments);
uint64_t new_phdr_offset = last_offset;
header.numberof_segments(header.numberof_segments() + 1);
uint64_t phdr_size = 0;
if (this->type() == ELF_CLASS::ELFCLASS32) {
phdr_size = sizeof(ELF32::Elf_Phdr);
}
if (this->type() == ELF_CLASS::ELFCLASS64) {
phdr_size = sizeof(ELF64::Elf_Phdr);
}
std::vector<uint8_t> content = segment.content();
Segment* new_segment = new Segment{segment};
new_segment->datahandler_ = this->datahandler_;
DataHandler::Node new_node{
new_segment->file_offset(),
new_segment->physical_size(),
DataHandler::Node::SEGMENT};
this->datahandler_->add(new_node);
const uint64_t psize = static_cast<uint64_t>(getpagesize());
const uint64_t last_offset_aligned = align(last_offset, psize);
new_segment->file_offset(last_offset_aligned);
if (segment.virtual_address() == 0) {
new_segment->virtual_address(base + last_offset_aligned);
}
new_segment->physical_address(new_segment->virtual_address());
uint64_t segmentsize = align(content.size(), psize);
content.resize(segmentsize, 0);
new_segment->physical_size(segmentsize);
new_segment->virtual_size(segmentsize);
if (new_segment->alignment() == 0) {
new_segment->alignment(psize);
}
this->datahandler_->make_hole(last_offset_aligned, new_segment->physical_size());
new_segment->content(content);
//if (header.section_headers_offset() <= new_segment->file_offset() + new_segment->physical_size()) {
//
//header.section_headers_offset(header.section_headers_offset() + new_phdr_offset + phdr_size * header.numberof_segments());
header.section_headers_offset(header.section_headers_offset() + new_segment->file_offset() + new_segment->physical_size() + phdr_size);
//}
//if (header.program_headers_offset() <= new_segment->file_offset() + new_segment->physical_size()) {
header.program_headers_offset(header.program_headers_offset() + new_segment->file_offset() + new_segment->physical_size());
//}
auto&& it_new_segment_place = std::find_if(
this->segments_.rbegin(),
this->segments_.rend(),
[&new_segment] (const Segment* s) {
return s->type() == new_segment->type();
});
if (it_new_segment_place == this->segments_.rend()) {
this->segments_.push_back(new_segment);
} else {
const size_t idx = std::distance(std::begin(this->segments_), it_new_segment_place.base());
this->segments_.insert(std::begin(this->segments_) + idx, new_segment);
}
return *new_segment;
}
template<class T>
std::unique_ptr<Binary> Binary::create_lief_core_impl(ARCH arch, ELF_CLASS clazz) {
using Elf_Phdr = typename T::Elf_Phdr;
using Elf_Ehdr = typename T::Elf_Ehdr;
using Elf_Shdr = typename T::Elf_Shdr;
std::unique_ptr<Binary> new_binary{new Binary{}};
new_binary->type_ = clazz;
// Set header
new_binary->header_.file_type(E_TYPE::ET_LIEF_CORE);
new_binary->header_.machine_type(arch);
new_binary->header_.object_file_version(VERSION::EV_CURRENT);
new_binary->header_.entrypoint(0);
new_binary->header_.processor_flag(0);
new_binary->header_.header_size(sizeof(Elf_Ehdr));
new_binary->header_.program_header_size(sizeof(Elf_Phdr));
new_binary->header_.section_header_size(sizeof(Elf_Shdr));
std::string ident = "\x7F";
new_binary->header_.identity(ident + "ELF");
new_binary->header_.identity_class(clazz);
new_binary->header_.identity_data(ELF_DATA::ELFDATA2LSB);
new_binary->header_.identity_version(VERSION::EV_CURRENT);
new_binary->header_.identity_os_abi(OS_ABI::ELFOSABI_SYSTEMV);
new_binary->datahandler_ = new DataHandler::Handler{std::vector<uint8_t>{}};
size_t cursor = sizeof(Elf_Ehdr);
// Add new null entry section
Section* null = new Section{"", ELF_SECTION_TYPES::SHT_NULL};
null->datahandler_ = new_binary->datahandler_;
new_binary->datahandler_->add({null->file_offset(), null->size(), DataHandler::Node::SECTION});
new_binary->sections_.push_back(null);
Section* shstrtab = new Section{".shstrtab", ELF_SECTION_TYPES::SHT_STRTAB};
shstrtab->offset(cursor);
shstrtab->datahandler_ = new_binary->datahandler_;
new_binary->datahandler_->add({shstrtab->file_offset(), 0, DataHandler::Node::SECTION});
shstrtab->size(100);
cursor += shstrtab->size();
new_binary->sections_.push_back(shstrtab);
new_binary->datahandler_->make_hole(shstrtab->file_offset(), shstrtab->size());
new_binary->header_.program_headers_offset(cursor);
cursor += 1;
new_binary->header_.section_headers_offset(cursor);
new_binary->header_.section_name_table_idx(new_binary->sections_.size() - 1);
const size_t shdr_sizes = (new_binary->sections_.size() + 1) * sizeof(Elf_Shdr);
cursor += shdr_sizes;
new_binary->header().numberof_sections(new_binary->sections_.size());
new_binary->header().numberof_segments(new_binary->segments_.size());
return new_binary;
}
}
}
+186
View File
@@ -0,0 +1,186 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LIEF/logging++.hpp"
#include "LIEF/ELF/enums.hpp"
namespace LIEF {
namespace ELF {
// ============
// ET_LIEF_DYN
// ============
template<>
Segment& Binary::add_segment<E_TYPE::ET_LIEF_DYN>(const Segment& segment, uint64_t base) {
Header& header = this->header();
uint64_t last_offset_sections = std::accumulate(
std::begin(this->sections_),
std::end(this->sections_), 0,
[] (uint64_t offset, const Section* section) {
return std::max<uint64_t>(section->file_offset() + section->size(), offset);
});
uint64_t last_offset_segments = std::accumulate(
std::begin(this->segments_),
std::end(this->segments_), 0,
[] (uint64_t offset, const Segment* segment) {
return std::max<uint64_t>(segment->file_offset() + segment->physical_size(), offset);
});
uint64_t last_offset = std::max<uint64_t>(last_offset_sections, last_offset_segments);
uint64_t new_phdr_offset = last_offset;
header.numberof_segments(header.numberof_segments() + 1);
uint64_t phdr_size = 0;
if (this->type() == ELF_CLASS::ELFCLASS32) {
phdr_size = sizeof(ELF32::Elf_Phdr);
}
if (this->type() == ELF_CLASS::ELFCLASS64) {
phdr_size = sizeof(ELF64::Elf_Phdr);
}
std::vector<uint8_t> content = segment.content();
Segment* new_segment = new Segment{segment};
new_segment->datahandler_ = this->datahandler_;
DataHandler::Node new_node{
new_segment->file_offset(),
new_segment->physical_size(),
DataHandler::Node::SEGMENT};
this->datahandler_->add(new_node);
const uint64_t psize = static_cast<uint64_t>(getpagesize());
const uint64_t last_offset_aligned = align(last_offset, psize);
new_segment->file_offset(last_offset_aligned);
if (segment.virtual_address() == 0) {
new_segment->virtual_address(base + last_offset_aligned);
}
new_segment->physical_address(new_segment->virtual_address());
uint64_t segmentsize = align(content.size(), psize);
content.resize(segmentsize, 0);
new_segment->physical_size(segmentsize);
new_segment->virtual_size(segmentsize);
if (new_segment->alignment() == 0) {
new_segment->alignment(psize);
}
this->datahandler_->make_hole(last_offset_aligned, new_segment->physical_size());
new_segment->content(content);
//if (header.section_headers_offset() <= new_segment->file_offset() + new_segment->physical_size()) {
//
//header.section_headers_offset(header.section_headers_offset() + new_phdr_offset + phdr_size * header.numberof_segments());
header.section_headers_offset(header.section_headers_offset() + new_segment->file_offset() + new_segment->physical_size() + phdr_size);
//}
//if (header.program_headers_offset() <= new_segment->file_offset() + new_segment->physical_size()) {
header.program_headers_offset(header.program_headers_offset() + new_segment->file_offset() + new_segment->physical_size());
//}
auto&& it_new_segment_place = std::find_if(
this->segments_.rbegin(),
this->segments_.rend(),
[&new_segment] (const Segment* s) {
return s->type() == new_segment->type();
});
if (it_new_segment_place == this->segments_.rend()) {
this->segments_.push_back(new_segment);
} else {
const size_t idx = std::distance(std::begin(this->segments_), it_new_segment_place.base());
this->segments_.insert(std::begin(this->segments_) + idx, new_segment);
}
return *new_segment;
}
template<class T>
std::unique_ptr<Binary> Binary::create_lief_dyn_impl(ARCH arch, ELF_CLASS clazz) {
using Elf_Phdr = typename T::Elf_Phdr;
using Elf_Ehdr = typename T::Elf_Ehdr;
using Elf_Shdr = typename T::Elf_Shdr;
std::unique_ptr<Binary> new_binary{new Binary{}};
new_binary->type_ = clazz;
// Set header
new_binary->header_.file_type(E_TYPE::ET_LIEF_DYN);
new_binary->header_.machine_type(arch);
new_binary->header_.object_file_version(VERSION::EV_CURRENT);
new_binary->header_.entrypoint(0);
new_binary->header_.processor_flag(0);
new_binary->header_.header_size(sizeof(Elf_Ehdr));
new_binary->header_.program_header_size(sizeof(Elf_Phdr));
new_binary->header_.section_header_size(sizeof(Elf_Shdr));
std::string ident = "\x7F";
new_binary->header_.identity(ident + "ELF");
new_binary->header_.identity_class(clazz);
new_binary->header_.identity_data(ELF_DATA::ELFDATA2LSB);
new_binary->header_.identity_version(VERSION::EV_CURRENT);
new_binary->header_.identity_os_abi(OS_ABI::ELFOSABI_SYSTEMV);
new_binary->datahandler_ = new DataHandler::Handler{std::vector<uint8_t>{}};
size_t cursor = sizeof(Elf_Ehdr);
// Add new null entry section
Section* null = new Section{"", ELF_SECTION_TYPES::SHT_NULL};
null->datahandler_ = new_binary->datahandler_;
new_binary->datahandler_->add({null->file_offset(), null->size(), DataHandler::Node::SECTION});
new_binary->sections_.push_back(null);
Section* shstrtab = new Section{".shstrtab", ELF_SECTION_TYPES::SHT_STRTAB};
shstrtab->offset(cursor);
shstrtab->datahandler_ = new_binary->datahandler_;
new_binary->datahandler_->add({shstrtab->file_offset(), 0, DataHandler::Node::SECTION});
shstrtab->size(100);
cursor += shstrtab->size();
new_binary->sections_.push_back(shstrtab);
new_binary->datahandler_->make_hole(shstrtab->file_offset(), shstrtab->size());
new_binary->header_.program_headers_offset(cursor);
cursor += 1;
new_binary->header_.section_headers_offset(cursor);
new_binary->header_.section_name_table_idx(new_binary->sections_.size() - 1);
const size_t shdr_sizes = (new_binary->sections_.size() + 1) * sizeof(Elf_Shdr);
cursor += shdr_sizes;
new_binary->header().numberof_sections(new_binary->sections_.size());
new_binary->header().numberof_segments(new_binary->segments_.size());
return new_binary;
}
}
}
+13 -2
View File
@@ -198,9 +198,20 @@ void Builder::build(const Header& header) {;
using Elf_Ehdr = typename ELF_T::Elf_Ehdr;
Elf_Ehdr ehdr;
static const std::map<E_TYPE, E_TYPE> lief_type2elf_type = {
{ E_TYPE::ET_LIEF_EXEC, E_TYPE::ET_EXEC },
{ E_TYPE::ET_LIEF_DYN , E_TYPE::ET_DYN },
};
ehdr.e_type = static_cast<Elf_Half>(header.file_type());
Elf_Ehdr ehdr;
E_TYPE ftype = header.file_type();
auto&& it_translate = lief_type2elf_type.find(ftype);
if (it_translate != std::end(lief_type2elf_type)) {
ftype = it_translate->second;
}
ehdr.e_type = static_cast<Elf_Half>(ftype);
ehdr.e_machine = static_cast<Elf_Half>(header.machine_type());
ehdr.e_version = static_cast<Elf_Word>(header.object_file_version());
ehdr.e_entry = static_cast<Elf_Addr>(header.entrypoint());
+1
View File
@@ -45,6 +45,7 @@ set(LIEF_ELF_SRC
"${CMAKE_CURRENT_LIST_DIR}/Builder.tcc"
"${CMAKE_CURRENT_LIST_DIR}/Parser.tcc"
"${CMAKE_CURRENT_LIST_DIR}/Binary.tcc"
"${CMAKE_CURRENT_LIST_DIR}/BinaryDyn.tcc"
"${CMAKE_CURRENT_LIST_DIR}/hash.cpp"
"${CMAKE_CURRENT_LIST_DIR}/Note.cpp"
"${CMAKE_CURRENT_LIST_DIR}/NoteDetails.cpp"
+16 -7
View File
@@ -39,14 +39,23 @@ const char* to_string(SYMBOL_BINDINGS e) {
const char* to_string(E_TYPE e) {
CONST_MAP(E_TYPE, const char*, 7) enumStrings {
CONST_MAP(E_TYPE, const char*, 13) enumStrings {
{ E_TYPE::ET_NONE, "NONE" },
{ E_TYPE::ET_REL, "RELOCATABLE" },
{ E_TYPE::ET_EXEC, "EXECUTABLE" },
{ E_TYPE::ET_DYN, "DYNAMIC" },
{ E_TYPE::ET_CORE, "CORE" },
{ E_TYPE::ET_LOPROC, "LOPROC" },
{ E_TYPE::ET_HIPROC, "HIPROC" }
{ E_TYPE::ET_REL, "RELOCATABLE" },
{ E_TYPE::ET_EXEC, "EXECUTABLE" },
{ E_TYPE::ET_DYN, "DYNAMIC" },
{ E_TYPE::ET_CORE, "CORE" },
{ E_TYPE::ET_PSPEXEC, "PSPEXEC" },
{ E_TYPE::ET_LIEF, "LIEF" },
{ E_TYPE::ET_LIEF_CORE, "LIEF_CORE" },
{ E_TYPE::ET_LIEF_EXEC, "LIEF_EXEC" },
{ E_TYPE::ET_LIEF_DYN, "LIEF_DYN" },
{ E_TYPE::ET_HIOS, "HIOS" },
{ E_TYPE::ET_LOPROC, "LOPROC" },
{ E_TYPE::ET_HIPROC, "HIPROC" }
};
auto it = enumStrings.find(e);
return it == enumStrings.end() ? "UNDEFINED" : it->second;