Squashed 'external/ELFIO/' content from commit 94f7706
git-subtree-dir: external/ELFIO git-subtree-split: 94f7706b5325b2ad9872e4481278278592cf86c9
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
add_subdirectory(add_section)
|
||||
add_subdirectory(anonymizer)
|
||||
add_subdirectory(elfdump)
|
||||
add_subdirectory(elfio_ldd)
|
||||
add_subdirectory(proc_mem)
|
||||
add_subdirectory(tutorial)
|
||||
add_subdirectory(write_obj)
|
||||
add_subdirectory(writer)
|
||||
#add_subdirectory(c_wrapper)
|
||||
add_subdirectory(arion)
|
||||
add_subdirectory(arioso)
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
add_executable(add_section add_section.cpp)
|
||||
target_link_libraries(add_section PRIVATE elfio::elfio)
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright (C) 2001-present by Serge Lamikhov-Center
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <elfio/elfio.hpp>
|
||||
|
||||
using namespace ELFIO;
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
if ( argc != 2 ) {
|
||||
std::cout << "Usage: add_section <elf_file>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create an elfio reader
|
||||
elfio reader;
|
||||
|
||||
// Load ELF data
|
||||
if ( !reader.load( argv[1] ) ) {
|
||||
std::cout << "Can't find or process ELF file " << argv[1] << std::endl;
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Create additional section at the end of the file
|
||||
section* note_sec = reader.sections.add( ".note.ELFIO" );
|
||||
note_sec->set_type( SHT_NOTE );
|
||||
note_section_accessor note_writer( reader, note_sec );
|
||||
note_writer.add_note( 0x01, "Created by ELFIO", "My data", 8 );
|
||||
|
||||
reader.save( "./result.elf" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
add_executable(anonymizer anonymizer.cpp)
|
||||
target_link_libraries(anonymizer PRIVATE elfio::elfio)
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
anonymizer.cpp - Overwrites string table for a function name.
|
||||
|
||||
Copyright (C) 2017 by Martin Bickel
|
||||
Copyright (C) 2020 by Serge Lamikhov-Center
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
To run the example, you may use the following script:
|
||||
|
||||
#!/usr/bin/bash
|
||||
|
||||
make
|
||||
cp anonymizer temp.elf
|
||||
readelf -a temp.elf > before.txt
|
||||
./anonymizer temp.elf
|
||||
readelf -a temp.elf > after.txt
|
||||
diff before.txt after.txt
|
||||
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define ELFIO_NO_INTTYPES
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <elfio/elfio.hpp>
|
||||
|
||||
using namespace ELFIO;
|
||||
|
||||
void overwrite_data( const std::string& filename,
|
||||
Elf64_Off offset,
|
||||
const std::string& str )
|
||||
{
|
||||
std::ofstream file( filename,
|
||||
std::ios::in | std::ios::out | std::ios::binary );
|
||||
if ( !file )
|
||||
throw "Error opening file" + filename;
|
||||
std::string data( str.length(), '-' );
|
||||
file.seekp( (std::streampos)offset );
|
||||
file.write( data.c_str(), data.length() + 1 );
|
||||
}
|
||||
|
||||
void process_string_table( const section* s, const std::string& filename )
|
||||
{
|
||||
std::cout << "Info: processing string table section" << std::endl;
|
||||
size_t index = 1;
|
||||
while ( index < s->get_size() ) {
|
||||
auto str = std::string( s->get_data() + index );
|
||||
// For the example purpose, we rename main function name only
|
||||
if ( str == "main" )
|
||||
overwrite_data( filename, s->get_offset() + index, str );
|
||||
index += str.length() + 1;
|
||||
}
|
||||
}
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
if ( argc != 2 ) {
|
||||
std::cout << "Usage: anonymizer <file_name>\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string filename = argv[1];
|
||||
|
||||
elfio reader;
|
||||
|
||||
if ( !reader.load( filename ) ) {
|
||||
std::cerr << "File " << filename
|
||||
<< " is not found or it is not an ELF file\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
for ( const auto& section : reader.sections ) {
|
||||
if ( section->get_type() == SHT_STRTAB &&
|
||||
std::string( section->get_name() ) == std::string( ".strtab" ) ) {
|
||||
process_string_table( section.get(), filename );
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
add_executable(arion arion.cpp)
|
||||
target_link_libraries(arion PRIVATE ario::ario)
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright (C) 2025-present by Serge Lamikhov-Center
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// arion.cpp
|
||||
//
|
||||
// This example demonstrates how to use the ARIO library to inspect and list the
|
||||
// contents of a UNIX archive (.ar) file. It provides a simple command-line tool
|
||||
// that displays information about each member of the archive, including its name,
|
||||
// size, file mode, and any associated symbols.
|
||||
//
|
||||
// Purpose:
|
||||
// - Showcase ARIO’s API for reading and iterating over archive members.
|
||||
// - Provide a minimal example for archive inspection and symbol listing.
|
||||
//
|
||||
// Abilities:
|
||||
// - Loads and parses a specified archive file.
|
||||
// - Lists all members with their names, sizes, and file modes.
|
||||
// - Displays symbols associated with each member, if available.
|
||||
// - Command-line interface: Accepts the archive file name as an argument.
|
||||
//
|
||||
// This example serves as a reference for basic ARIO usage and as a foundation
|
||||
// for building custom archive inspection tools.
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <iostream>
|
||||
#include <ario/ario.hpp>
|
||||
|
||||
using namespace ARIO;
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
if ( argc != 2 ) {
|
||||
std::cout << "Usage: arion <file_name>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
ario archive;
|
||||
|
||||
const auto result = archive.load( argv[1] );
|
||||
if ( !result.ok() ) {
|
||||
std::cerr << "Error loading archive: " << result.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
for ( const auto& member : archive.members ) {
|
||||
std::cout << "Member: " << std::setw( 40 ) << std::left << member.name
|
||||
<< " Size: " << std::setw( 8 ) << std::right << member.size
|
||||
<< " Mode: " << std::setw( 3 ) << std::oct << member.mode
|
||||
<< std::dec << std::endl;
|
||||
std::vector<std::string> symbols;
|
||||
if ( archive.get_symbols_for_member( member, symbols ).ok() ) {
|
||||
auto first_time = true;
|
||||
for ( const auto& symbol : symbols ) {
|
||||
if ( first_time ) {
|
||||
std::cout << " ";
|
||||
first_time = false;
|
||||
}
|
||||
else {
|
||||
std::cout << ", ";
|
||||
}
|
||||
std::cout << symbol;
|
||||
}
|
||||
if ( !first_time ) {
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
add_executable(arioso arioso.cpp)
|
||||
target_link_libraries(arioso PRIVATE ario::ario elfio::elfio)
|
||||
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
Copyright (C) 2025-present by Serge Lamikhov-Center
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// arioso.cpp
|
||||
//
|
||||
// This example demonstrates how to use the ARIO library (with optional ELFIO integration)
|
||||
// to manage UNIX archive (.ar) files from the command line. It provides a practical tool
|
||||
// for extracting, deleting, and adding files to an archive, similar to the standard 'ar' utility.
|
||||
//
|
||||
// Purpose:
|
||||
// - Showcase ARIO’s API for reading, modifying, and writing UNIX archive files.
|
||||
// - Illustrate integration with ELFIO for symbol extraction from ELF object files.
|
||||
//
|
||||
// Abilities:
|
||||
// - Extraction: Extracts specified files from the archive to the current directory.
|
||||
// - Deletion: Removes specified files from the archive.
|
||||
// - Addition: Adds new files to the archive, collecting and storing global symbols if the file is an ELF object.
|
||||
// - Archive update: Safely writes changes to the archive using a temporary file for atomic updates.
|
||||
// - Command-line interface: Accepts commands in the form:
|
||||
// arioso <archive> [-e <files...>] [-d <files...>] [-a <files...>]
|
||||
//
|
||||
// This example serves as both a reference for ARIO/ELFIO usage and a foundation for building custom archive management tools.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
|
||||
#include <ario/ario.hpp>
|
||||
#include <elfio/elfio.hpp>
|
||||
|
||||
using namespace ARIO;
|
||||
using namespace ELFIO;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Simple command line parser for:
|
||||
// arioso -e <files...> -d <files...> -a <files...>
|
||||
struct CommandLineOptions
|
||||
{
|
||||
std::string archive_name; ///< Name of the archive file
|
||||
std::vector<std::string> extract_files; ///< List of files to extract
|
||||
std::vector<std::string> delete_files; ///< List of files to delete
|
||||
std::vector<std::string> add_files; ///< List of files to add
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static CommandLineOptions parse_args( int argc, char** argv )
|
||||
{
|
||||
if ( argc < 2 ) {
|
||||
std::cerr
|
||||
<< "Usage: " << argv[0]
|
||||
<< " <archive> [-e <files...>] [-d <files...>] [-a <files...>]"
|
||||
<< std::endl;
|
||||
return {};
|
||||
}
|
||||
|
||||
CommandLineOptions opts;
|
||||
|
||||
opts.archive_name = argv[1];
|
||||
|
||||
std::vector<std::string>* current = nullptr;
|
||||
for ( int i = 2; i < argc; ++i ) {
|
||||
std::string arg = argv[i];
|
||||
if ( arg == "-e" ) {
|
||||
current = &opts.extract_files;
|
||||
}
|
||||
else if ( arg == "-d" ) {
|
||||
current = &opts.delete_files;
|
||||
}
|
||||
else if ( arg == "-a" ) {
|
||||
current = &opts.add_files;
|
||||
}
|
||||
else if ( current ) {
|
||||
current->emplace_back( arg );
|
||||
}
|
||||
else {
|
||||
std::cerr << "Unknown argument or missing option: " << arg
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
return opts;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// This function would contain the logic to extract the member data to a file
|
||||
static ario::Result extract_member( const ario::Member& member )
|
||||
{
|
||||
std::cout << "Extracting member: " << member << ", Size: " << member.size
|
||||
<< " bytes" << std::endl;
|
||||
|
||||
std::filesystem::path output_path =
|
||||
std::filesystem::current_path() / member.name;
|
||||
std::ofstream output_file( output_path, std::ios::binary );
|
||||
if ( !output_file ) {
|
||||
return { " Failed to create output file : " + output_path.string() };
|
||||
}
|
||||
output_file.write( member.data().c_str(), member.size );
|
||||
if ( output_file.fail() ) {
|
||||
return { "Failed to write member data to file: " +
|
||||
output_path.string() };
|
||||
}
|
||||
|
||||
return {}; // Return success
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Extract all members from the command line extraction list.
|
||||
// The search should be done by member's name. Exact match is expected
|
||||
static int extract_members( const CommandLineOptions& opts,
|
||||
const ARIO::ario& archive )
|
||||
{
|
||||
for ( const auto& file_name : opts.extract_files ) {
|
||||
const auto& pmember = std::find( archive.members.begin(),
|
||||
archive.members.end(), file_name );
|
||||
if ( pmember != archive.members.end() ) {
|
||||
auto result = extract_member( *pmember );
|
||||
if ( !result.ok() ) {
|
||||
std::cerr << "Error extracting member '" << file_name
|
||||
<< "': " << result.what() << std::endl;
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cerr << "Member '" << file_name << "' not found in the library"
|
||||
<< std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Copy members from the source archive to the target archive
|
||||
static int copy_members( const CommandLineOptions& opts,
|
||||
const ARIO::ario& archive,
|
||||
ARIO::ario& target_archive )
|
||||
{
|
||||
for ( const auto& member : archive.members ) {
|
||||
if ( std::find( opts.delete_files.begin(), opts.delete_files.end(),
|
||||
member.name ) != opts.delete_files.end() ) {
|
||||
std::cout << "Removing member: " << member << std::endl;
|
||||
continue; // Skip this member
|
||||
}
|
||||
|
||||
auto result = target_archive.add_member( member, member.data() );
|
||||
if ( !result.ok() ) {
|
||||
std::cerr << "Error adding member '" << member.name
|
||||
<< "': " << result.what() << std::endl;
|
||||
return 3;
|
||||
}
|
||||
|
||||
// Copy member symbols
|
||||
std::vector<std::string> symbols;
|
||||
archive.get_symbols_for_member( member, symbols );
|
||||
target_archive.add_symbols_for_member( target_archive.members.back(),
|
||||
symbols );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Collect global symbols from an ELF file
|
||||
static void
|
||||
collect_elf_global_symbols( const ELFIO::elfio& elf,
|
||||
std::vector<std::string>& gathered_symbols )
|
||||
{
|
||||
for ( const auto& sec : elf.sections ) {
|
||||
// Look for the symbol table section
|
||||
if ( sec->get_type() == SHT_SYMTAB ) {
|
||||
// Access the symbols in the symbol table
|
||||
symbol_section_accessor symbols( elf, sec.get() );
|
||||
|
||||
std::string name;
|
||||
Elf64_Addr value;
|
||||
Elf_Xword size;
|
||||
unsigned char bind = 0, type = 0;
|
||||
Elf_Half section_index;
|
||||
unsigned char other;
|
||||
|
||||
// Iterate over all sections in the ELF file and gather all symbols
|
||||
// that are functions or objects, and have global binding
|
||||
for ( Elf_Xword i = 0; i < symbols.get_symbols_num(); ++i ) {
|
||||
// Extract symbol properties
|
||||
symbols.get_symbol( i, name, value, size, bind, type,
|
||||
section_index, other );
|
||||
// For each global function or object symbol, check that the archive symbol table can find it
|
||||
if ( ( type == STT_FUNC || type == STT_OBJECT ||
|
||||
type == STT_TLS || type == STT_COMMON ) &&
|
||||
bind == STB_GLOBAL ) {
|
||||
gathered_symbols.emplace_back( name );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Add a new member to the archive
|
||||
static ario::Result add_new_member( ario& archive,
|
||||
const std::string_view& file_name )
|
||||
{
|
||||
std::filesystem::path full_file_path = file_name;
|
||||
if ( !std::filesystem::exists( full_file_path ) ) {
|
||||
return { "File does not exist: " + full_file_path.string() };
|
||||
}
|
||||
ario::Member new_member;
|
||||
new_member.name = full_file_path.filename().string();
|
||||
new_member.uid = 0;
|
||||
new_member.gid = 0;
|
||||
new_member.mode = 0644;
|
||||
|
||||
std::ifstream input( full_file_path, std::ios::binary );
|
||||
if ( !input ) {
|
||||
return { "Failed to open file: " + full_file_path.string() };
|
||||
}
|
||||
const std::string data( ( std::istreambuf_iterator<char>( input ) ),
|
||||
std::istreambuf_iterator<char>() );
|
||||
|
||||
const auto result = archive.add_member( new_member, data );
|
||||
if ( !result.ok() ) {
|
||||
return result;
|
||||
}
|
||||
|
||||
elfio elf;
|
||||
if ( elf.load( full_file_path.string() ) ) {
|
||||
std::vector<std::string> gathered_symbols;
|
||||
collect_elf_global_symbols( elf, gathered_symbols );
|
||||
archive.add_symbols_for_member( archive.members.back(),
|
||||
gathered_symbols );
|
||||
}
|
||||
|
||||
return {}; // Return success
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Add members from the command line addition list
|
||||
static int add_new_members( const CommandLineOptions& opts,
|
||||
ARIO::ario& target_archive )
|
||||
{
|
||||
for ( const auto& file_name : opts.add_files ) {
|
||||
std::cout << "Adding member: " << file_name << std::endl;
|
||||
auto result = add_new_member( target_archive, file_name );
|
||||
if ( !result.ok() ) {
|
||||
std::cerr << "Error adding member '" << file_name
|
||||
<< "': " << result.what() << std::endl;
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Save the new archive to a file
|
||||
static int save_new_archive( ARIO::ario& target_archive,
|
||||
const std::string& archive_name )
|
||||
{
|
||||
// Create a temporary filename for the archive
|
||||
auto temp_dir = std::filesystem::temp_directory_path();
|
||||
std::string temp_filename;
|
||||
do {
|
||||
// Generate a random filename
|
||||
temp_filename = "ario_tmp_" + std::to_string( std::rand() ) + ".ar";
|
||||
} while ( std::filesystem::exists( temp_dir / temp_filename ) );
|
||||
std::filesystem::path temp_path = temp_dir / temp_filename;
|
||||
|
||||
target_archive.save( temp_path.string() );
|
||||
|
||||
// Move temporary file to the original one
|
||||
std::error_code ec;
|
||||
std::filesystem::rename( temp_path, archive_name, ec );
|
||||
if ( ec ) {
|
||||
std::cerr << "Error renaming temporary file: " << ec.message()
|
||||
<< std::endl;
|
||||
return 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
auto opts = parse_args( argc, argv );
|
||||
|
||||
// Open existing library or create a new one. In the last case, the library will be empty.
|
||||
ario archive;
|
||||
const auto result = archive.load( opts.archive_name );
|
||||
if ( !result.ok() ) {
|
||||
std::cerr << "Error loading archive: " << result.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Extract members from the archive
|
||||
int retVal = extract_members( opts, archive );
|
||||
if ( retVal != 0 )
|
||||
return retVal;
|
||||
|
||||
// Check if there are no files to delete or add
|
||||
if ( opts.delete_files.empty() && opts.add_files.empty() ) {
|
||||
// No files to delete or add. Exiting
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Create a new (empty) target archive
|
||||
ario target_archive;
|
||||
|
||||
// Copy members not included to the command line deletion list
|
||||
retVal = copy_members( opts, archive, target_archive );
|
||||
if ( retVal != 0 )
|
||||
return retVal;
|
||||
|
||||
// Add new members from the command line addition list
|
||||
retVal = add_new_members( opts, target_archive );
|
||||
if ( retVal != 0 )
|
||||
return retVal;
|
||||
|
||||
// Save the new archive
|
||||
retVal = save_new_archive( target_archive, opts.archive_name );
|
||||
if ( retVal != 0 )
|
||||
return retVal;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
add_executable(c_example c_example.c elfio_c_wrapper.cpp elfio_c_wrapper.h)
|
||||
target_link_libraries(c_example PRIVATE elfio::elfio)
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
Copyright (C) 2001-present by Serge Lamikhov-Center
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <elfio/elf_types.hpp>
|
||||
#include "elfio_c_wrapper.h"
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
pelfio_t pelfio = elfio_new();
|
||||
bool ret;
|
||||
|
||||
if ( argc == 1 )
|
||||
ret = elfio_load( pelfio, argv[0] );
|
||||
else
|
||||
ret = elfio_load( pelfio, argv[1] );
|
||||
|
||||
if ( !ret ) {
|
||||
printf( "Can't load ELF file\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
char msg[128];
|
||||
ret = elfio_validate( pelfio, msg, 128 );
|
||||
|
||||
if ( !ret ) {
|
||||
printf( "Validation errors:\n" );
|
||||
printf( "%s\n", msg );
|
||||
return 2;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// elfio
|
||||
//-----------------------------------------------------------------------------
|
||||
printf( "Header size : %d\n", elfio_get_header_size( pelfio ) );
|
||||
printf( "Version : %d\n", elfio_get_version( pelfio ) );
|
||||
printf( "Section Entry : %d\n", elfio_get_section_entry_size( pelfio ) );
|
||||
printf( "Segment Entry : %d\n", elfio_get_segment_entry_size( pelfio ) );
|
||||
|
||||
/* Uncomment a printf block of the interest */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// section
|
||||
//-----------------------------------------------------------------------------
|
||||
int secno = elfio_get_sections_num( pelfio );
|
||||
printf( "Sections No : %d\n", secno );
|
||||
|
||||
for ( int i = 0; i < secno; i++ ) {
|
||||
psection_t psection = elfio_get_section_by_index( pelfio, i );
|
||||
char buff[128];
|
||||
elfio_section_get_name( psection, buff, 100 );
|
||||
// printf( " [%02d] %s\n", i, buff );
|
||||
// printf( " %08lx : %08lx\n",
|
||||
// elfio_section_get_address( psection ),
|
||||
// elfio_section_get_size( psection ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// segment
|
||||
//-----------------------------------------------------------------------------
|
||||
int segno = elfio_get_segments_num( pelfio );
|
||||
printf( "Segments No : %d\n", segno );
|
||||
|
||||
for ( int i = 0; i < segno; i++ ) {
|
||||
psegment_t psegment = elfio_get_segment_by_index( pelfio, i );
|
||||
elfio_segment_get_file_size( psegment );
|
||||
// printf( " [%02d] %08lx : %08lx : %08lx\n", i,
|
||||
// elfio_segment_get_virtual_address( psegment ),
|
||||
// elfio_segment_get_memory_size( psegment ),
|
||||
// elfio_segment_get_file_size( psegment ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// symbol
|
||||
//-----------------------------------------------------------------------------
|
||||
psection_t psection = elfio_get_section_by_name( pelfio, ".symtab" );
|
||||
psymbol_t psymbols = elfio_symbol_section_accessor_new( pelfio, psection );
|
||||
Elf_Xword symno = elfio_symbol_get_symbols_num( psymbols );
|
||||
for ( int i = 0; i < symno; i++ ) {
|
||||
char name[128];
|
||||
Elf64_Addr value;
|
||||
Elf_Xword size;
|
||||
unsigned char bind;
|
||||
unsigned char type;
|
||||
Elf_Half section_index;
|
||||
unsigned char other;
|
||||
elfio_symbol_get_symbol( psymbols, i, name, 128, &value, &size, &bind,
|
||||
&type, §ion_index, &other );
|
||||
// printf( "[%4d] %10lu, %4lu %s\n", i, value, size, name );
|
||||
}
|
||||
elfio_symbol_section_accessor_delete( psymbols );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// relocation
|
||||
//-----------------------------------------------------------------------------
|
||||
psection = elfio_get_section_by_name( pelfio, ".rela.dyn" );
|
||||
prelocation_t preloc =
|
||||
elfio_relocation_section_accessor_new( pelfio, psection );
|
||||
Elf_Xword relno = elfio_relocation_get_entries_num( preloc );
|
||||
for ( int i = 0; i < relno; i++ ) {
|
||||
Elf64_Addr offset;
|
||||
Elf_Word symbol;
|
||||
Elf_Word type;
|
||||
Elf_Sxword addend;
|
||||
elfio_relocation_get_entry( preloc, i, &offset, &symbol, &type,
|
||||
&addend );
|
||||
// printf( "[%4d] %16lx, %08x %08x %16lx\n", i, offset, symbol, type, addend );
|
||||
}
|
||||
elfio_relocation_section_accessor_delete( preloc );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// string
|
||||
//-----------------------------------------------------------------------------
|
||||
psection = elfio_get_section_by_name( pelfio, ".strtab" );
|
||||
pstring_t pstring = elfio_string_section_accessor_new( psection );
|
||||
Elf_Word pos = 0;
|
||||
const char* str = elfio_string_get_string( pstring, pos );
|
||||
while ( str ) {
|
||||
pos += (Elf_Word)strlen( str ) + 1;
|
||||
str = elfio_string_get_string( pstring, pos );
|
||||
// printf( "%s\n", str );
|
||||
}
|
||||
elfio_string_section_accessor_delete( pstring );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// note
|
||||
//-----------------------------------------------------------------------------
|
||||
psection = elfio_get_section_by_name( pelfio, ".note.gnu.build-id" );
|
||||
pnote_t pnote = elfio_note_section_accessor_new( pelfio, psection );
|
||||
int noteno = elfio_note_get_notes_num( pnote );
|
||||
for ( int i = 0; i < noteno; i++ ) {
|
||||
Elf_Word type;
|
||||
char name[128];
|
||||
int name_len = 128;
|
||||
char* desc;
|
||||
Elf_Word descSize = 128;
|
||||
elfio_note_get_note( pnote, i, &type, name, name_len, (void**)&desc,
|
||||
&descSize );
|
||||
// printf( "[%4d] %s %08x\n", i, name, descSize );
|
||||
}
|
||||
elfio_note_section_accessor_delete( pnote );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// dynamic
|
||||
//-----------------------------------------------------------------------------
|
||||
psection = elfio_get_section_by_name( pelfio, ".dynamic" );
|
||||
pdynamic_t pdynamic =
|
||||
elfio_dynamic_section_accessor_new( pelfio, psection );
|
||||
Elf_Xword dynno = elfio_dynamic_get_entries_num( pdynamic );
|
||||
for ( int i = 0; i < dynno; i++ ) {
|
||||
Elf_Xword tag;
|
||||
Elf_Xword value;
|
||||
char str[128];
|
||||
elfio_dynamic_get_entry( pdynamic, i, &tag, &value, str, 128 );
|
||||
// printf( "[%4d] %16lx %16lx %s\n", i, tag, value, str );
|
||||
}
|
||||
elfio_dynamic_section_accessor_delete( pdynamic );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// array
|
||||
//-----------------------------------------------------------------------------
|
||||
psection = elfio_get_section_by_name( pelfio, ".init_array" );
|
||||
if ( psection != 0 ) {
|
||||
parray_t parray = elfio_array_section_accessor_new( pelfio, psection );
|
||||
Elf_Xword arrno = elfio_array_get_entries_num( parray );
|
||||
for ( int i = 0; i < arrno; i++ ) {
|
||||
Elf64_Addr addr;
|
||||
elfio_array_get_entry( parray, i, &addr );
|
||||
// printf( "[%4d] %16lx\n", i, addr );
|
||||
}
|
||||
elfio_array_section_accessor_delete( parray );
|
||||
}
|
||||
|
||||
elfio_delete( pelfio );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,500 @@
|
||||
/*
|
||||
Copyright (C) 2001-present by Serge Lamikhov-Center
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include <elfio/elfio.hpp>
|
||||
#include <cstring>
|
||||
|
||||
using namespace ELFIO;
|
||||
|
||||
#include "elfio_c_wrapper.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// elfio
|
||||
//-----------------------------------------------------------------------------
|
||||
pelfio_t elfio_new() { return new ( std::nothrow ) elfio; }
|
||||
|
||||
void elfio_delete( pelfio_t pelfio ) { delete (elfio*)pelfio; }
|
||||
|
||||
void elfio_create( pelfio_t pelfio,
|
||||
unsigned char file_class,
|
||||
unsigned char encoding )
|
||||
{
|
||||
pelfio->create( file_class, encoding );
|
||||
}
|
||||
|
||||
bool elfio_load( pelfio_t pelfio, const char* file_name )
|
||||
{
|
||||
return pelfio->load( file_name );
|
||||
}
|
||||
|
||||
bool elfio_save( pelfio_t pelfio, const char* file_name )
|
||||
{
|
||||
return pelfio->save( file_name );
|
||||
}
|
||||
|
||||
ELFIO_C_HEADER_ACCESS_GET_IMPL( unsigned char, class );
|
||||
ELFIO_C_HEADER_ACCESS_GET_IMPL( unsigned char, elf_version );
|
||||
ELFIO_C_HEADER_ACCESS_GET_IMPL( unsigned char, encoding );
|
||||
ELFIO_C_HEADER_ACCESS_GET_IMPL( Elf_Word, version );
|
||||
ELFIO_C_HEADER_ACCESS_GET_IMPL( Elf_Half, header_size );
|
||||
ELFIO_C_HEADER_ACCESS_GET_IMPL( Elf_Half, section_entry_size );
|
||||
ELFIO_C_HEADER_ACCESS_GET_IMPL( Elf_Half, segment_entry_size );
|
||||
|
||||
ELFIO_C_HEADER_ACCESS_GET_SET_IMPL( unsigned char, os_abi );
|
||||
ELFIO_C_HEADER_ACCESS_GET_SET_IMPL( unsigned char, abi_version );
|
||||
ELFIO_C_HEADER_ACCESS_GET_SET_IMPL( Elf_Half, type );
|
||||
ELFIO_C_HEADER_ACCESS_GET_SET_IMPL( Elf_Half, machine );
|
||||
ELFIO_C_HEADER_ACCESS_GET_SET_IMPL( Elf_Word, flags );
|
||||
ELFIO_C_HEADER_ACCESS_GET_SET_IMPL( Elf64_Addr, entry );
|
||||
ELFIO_C_HEADER_ACCESS_GET_SET_IMPL( Elf64_Off, sections_offset );
|
||||
ELFIO_C_HEADER_ACCESS_GET_SET_IMPL( Elf64_Off, segments_offset );
|
||||
ELFIO_C_HEADER_ACCESS_GET_SET_IMPL( Elf_Half, section_name_str_index );
|
||||
|
||||
Elf_Half elfio_get_sections_num( pelfio_t pelfio )
|
||||
{
|
||||
return pelfio->sections.size();
|
||||
}
|
||||
|
||||
psection_t elfio_get_section_by_index( pelfio_t pelfio, int index )
|
||||
{
|
||||
return pelfio->sections[index];
|
||||
}
|
||||
|
||||
psection_t elfio_get_section_by_name( pelfio_t pelfio, char* name )
|
||||
{
|
||||
return pelfio->sections[name];
|
||||
}
|
||||
|
||||
psection_t elfio_add_section( pelfio_t pelfio, char* name )
|
||||
{
|
||||
return pelfio->sections.add( name );
|
||||
}
|
||||
|
||||
Elf_Half elfio_get_segments_num( pelfio_t pelfio )
|
||||
{
|
||||
return pelfio->segments.size();
|
||||
}
|
||||
|
||||
psegment_t elfio_get_segment_by_index( pelfio_t pelfio, int index )
|
||||
{
|
||||
return pelfio->segments[index];
|
||||
}
|
||||
|
||||
psegment_t elfio_add_segment( pelfio_t pelfio )
|
||||
{
|
||||
return pelfio->segments.add();
|
||||
}
|
||||
|
||||
bool elfio_validate( pelfio_t pelfio, char* msg, int msg_len )
|
||||
{
|
||||
std::string error = pelfio->validate();
|
||||
|
||||
if ( msg != nullptr && msg_len > 0 ) {
|
||||
strncpy( msg, error.c_str(), (size_t)msg_len - 1 );
|
||||
}
|
||||
|
||||
return error.empty();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// section
|
||||
//-----------------------------------------------------------------------------
|
||||
ELFIO_C_GET_ACCESS_IMPL( section, Elf_Half, index );
|
||||
ELFIO_C_GET_SET_ACCESS_IMPL( section, Elf_Word, type );
|
||||
ELFIO_C_GET_SET_ACCESS_IMPL( section, Elf_Xword, flags );
|
||||
ELFIO_C_GET_SET_ACCESS_IMPL( section, Elf_Word, info );
|
||||
ELFIO_C_GET_SET_ACCESS_IMPL( section, Elf_Word, link );
|
||||
ELFIO_C_GET_SET_ACCESS_IMPL( section, Elf_Xword, addr_align );
|
||||
ELFIO_C_GET_SET_ACCESS_IMPL( section, Elf_Xword, entry_size );
|
||||
ELFIO_C_GET_SET_ACCESS_IMPL( section, Elf64_Addr, address );
|
||||
ELFIO_C_GET_SET_ACCESS_IMPL( section, Elf_Xword, size );
|
||||
ELFIO_C_GET_SET_ACCESS_IMPL( section, Elf_Word, name_string_offset );
|
||||
ELFIO_C_GET_ACCESS_IMPL( section, Elf64_Off, offset );
|
||||
|
||||
void elfio_section_get_name( psection_t psection, char* buffer, int len )
|
||||
{
|
||||
strncpy( buffer, psection->get_name().c_str(), (size_t)len - 1 );
|
||||
}
|
||||
|
||||
void elfio_section_set_name( psection_t psection, char* buffer )
|
||||
{
|
||||
psection->set_name( buffer );
|
||||
}
|
||||
|
||||
char* elfio_section_get_data( psection_t psection )
|
||||
{
|
||||
return (char*)psection->get_data();
|
||||
}
|
||||
|
||||
void elfio_section_set_data( psection_t psection,
|
||||
const char* pData,
|
||||
Elf_Word size )
|
||||
{
|
||||
psection->set_data( pData, size );
|
||||
}
|
||||
|
||||
void elfio_section_append_data( psection_t psection,
|
||||
const char* pData,
|
||||
Elf_Word size )
|
||||
{
|
||||
psection->append_data( pData, size );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// segment
|
||||
//-----------------------------------------------------------------------------
|
||||
ELFIO_C_GET_ACCESS_IMPL( segment, Elf_Half, index );
|
||||
ELFIO_C_GET_SET_ACCESS_IMPL( segment, Elf_Word, type );
|
||||
ELFIO_C_GET_SET_ACCESS_IMPL( segment, Elf_Word, flags );
|
||||
ELFIO_C_GET_SET_ACCESS_IMPL( segment, Elf_Xword, align );
|
||||
ELFIO_C_GET_SET_ACCESS_IMPL( segment, Elf_Xword, memory_size );
|
||||
ELFIO_C_GET_SET_ACCESS_IMPL( segment, Elf64_Addr, virtual_address );
|
||||
ELFIO_C_GET_SET_ACCESS_IMPL( segment, Elf64_Addr, physical_address );
|
||||
ELFIO_C_GET_SET_ACCESS_IMPL( segment, Elf_Xword, file_size );
|
||||
ELFIO_C_GET_ACCESS_IMPL( segment, Elf64_Off, offset );
|
||||
|
||||
char* elfio_segment_get_data( psegment_t psegment )
|
||||
{
|
||||
return (char*)psegment->get_data();
|
||||
}
|
||||
|
||||
Elf_Half elfio_segment_add_section_index( psegment_t psegment,
|
||||
Elf_Half index,
|
||||
Elf_Xword addr_align )
|
||||
{
|
||||
return psegment->add_section_index( index, addr_align );
|
||||
}
|
||||
|
||||
Elf_Half elfio_segment_get_sections_num( psegment_t psegment )
|
||||
{
|
||||
return psegment->get_sections_num();
|
||||
}
|
||||
|
||||
Elf_Half elfio_segment_get_section_index_at( psegment_t psegment, Elf_Half num )
|
||||
{
|
||||
return psegment->get_section_index_at( num );
|
||||
}
|
||||
|
||||
bool elfio_segment_is_offset_initialized( psegment_t psegment )
|
||||
{
|
||||
return psegment->is_offset_initialized();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// symbol
|
||||
//-----------------------------------------------------------------------------
|
||||
psymbol_t elfio_symbol_section_accessor_new( pelfio_t pelfio,
|
||||
psection_t psection )
|
||||
{
|
||||
return new ( std::nothrow ) symbol_section_accessor( *pelfio, psection );
|
||||
}
|
||||
|
||||
void elfio_symbol_section_accessor_delete( psymbol_t psymbol )
|
||||
{
|
||||
delete psymbol;
|
||||
}
|
||||
|
||||
Elf_Xword elfio_symbol_get_symbols_num( psymbol_t psymbol )
|
||||
{
|
||||
return psymbol->get_symbols_num();
|
||||
}
|
||||
|
||||
bool elfio_symbol_get_symbol( psymbol_t psymbol,
|
||||
Elf_Xword index,
|
||||
char* name,
|
||||
int name_len,
|
||||
Elf64_Addr* value,
|
||||
Elf_Xword* size,
|
||||
unsigned char* bind,
|
||||
unsigned char* type,
|
||||
Elf_Half* section_index,
|
||||
unsigned char* other )
|
||||
{
|
||||
std::string name_param;
|
||||
bool ret = psymbol->get_symbol( index, name_param, *value, *size, *bind,
|
||||
*type, *section_index, *other );
|
||||
strncpy( name, name_param.c_str(), (size_t)name_len - 1 );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Elf_Word elfio_symbol_add_symbol( psymbol_t psymbol,
|
||||
Elf_Word name,
|
||||
Elf64_Addr value,
|
||||
Elf_Xword size,
|
||||
unsigned char info,
|
||||
unsigned char other,
|
||||
Elf_Half shndx )
|
||||
{
|
||||
return psymbol->add_symbol( name, value, size, info, other, shndx );
|
||||
}
|
||||
|
||||
Elf_Xword elfio_symbol_arrange_local_symbols(
|
||||
psymbol_t psymbol, void ( *func )( Elf_Xword first, Elf_Xword second ) )
|
||||
{
|
||||
return psymbol->arrange_local_symbols( func );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// relocation
|
||||
//-----------------------------------------------------------------------------
|
||||
prelocation_t elfio_relocation_section_accessor_new( pelfio_t pelfio,
|
||||
psection_t psection )
|
||||
{
|
||||
return new ( std::nothrow )
|
||||
relocation_section_accessor( *pelfio, psection );
|
||||
}
|
||||
|
||||
void elfio_relocation_section_accessor_delete( prelocation_t prelocation )
|
||||
{
|
||||
delete prelocation;
|
||||
}
|
||||
|
||||
Elf_Xword elfio_relocation_get_entries_num( prelocation_t prelocation )
|
||||
{
|
||||
return prelocation->get_entries_num();
|
||||
}
|
||||
|
||||
bool elfio_relocation_get_entry( prelocation_t prelocation,
|
||||
Elf_Xword index,
|
||||
Elf64_Addr* offset,
|
||||
Elf_Word* symbol,
|
||||
Elf_Word* type,
|
||||
Elf_Sxword* addend )
|
||||
{
|
||||
return prelocation->get_entry( index, *offset, *symbol, *type, *addend );
|
||||
}
|
||||
|
||||
bool elfio_relocation_set_entry( prelocation_t prelocation,
|
||||
Elf_Xword index,
|
||||
Elf64_Addr offset,
|
||||
Elf_Word symbol,
|
||||
Elf_Word type,
|
||||
Elf_Sxword addend )
|
||||
{
|
||||
return prelocation->set_entry( index, offset, symbol, type, addend );
|
||||
}
|
||||
|
||||
void elfio_relocation_add_entry( prelocation_t prelocation,
|
||||
Elf64_Addr offset,
|
||||
Elf_Word symbol,
|
||||
unsigned char type,
|
||||
Elf_Sxword addend )
|
||||
{
|
||||
return prelocation->add_entry( offset, symbol, type, addend );
|
||||
}
|
||||
|
||||
void elfio_relocation_swap_symbols( prelocation_t prelocation,
|
||||
Elf_Xword first,
|
||||
Elf_Xword second )
|
||||
{
|
||||
prelocation->swap_symbols( first, second );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// string
|
||||
//-----------------------------------------------------------------------------
|
||||
pstring_t elfio_string_section_accessor_new( psection_t psection )
|
||||
{
|
||||
return new ( std::nothrow ) string_section_accessor( psection );
|
||||
}
|
||||
|
||||
void elfio_string_section_accessor_delete( pstring_t pstring )
|
||||
{
|
||||
delete pstring;
|
||||
}
|
||||
|
||||
const char* elfio_string_get_string( pstring_t pstring, Elf_Word index )
|
||||
{
|
||||
return pstring->get_string( index );
|
||||
}
|
||||
|
||||
Elf_Word elfio_string_add_string( pstring_t pstring, char* str )
|
||||
{
|
||||
return pstring->add_string( str );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// note
|
||||
//-----------------------------------------------------------------------------
|
||||
pnote_t elfio_note_section_accessor_new( pelfio_t pelfio, psection_t psection )
|
||||
{
|
||||
return new ( std::nothrow ) note_section_accessor( *pelfio, psection );
|
||||
}
|
||||
|
||||
void elfio_note_section_accessor_delete( pnote_t pnote ) { delete pnote; }
|
||||
|
||||
Elf_Word elfio_note_get_notes_num( pnote_t pnote )
|
||||
{
|
||||
return pnote->get_notes_num();
|
||||
}
|
||||
|
||||
bool elfio_note_get_note( pnote_t pnote,
|
||||
Elf_Word index,
|
||||
Elf_Word* type,
|
||||
char* name,
|
||||
int name_len,
|
||||
void** desc,
|
||||
Elf_Word* descSize )
|
||||
{
|
||||
std::string name_str;
|
||||
bool ret = pnote->get_note( index, *type, name_str, *desc, *descSize );
|
||||
strncpy( name, name_str.c_str(), (size_t)name_len - 1 );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void elfio_note_add_note( pnote_t pnote,
|
||||
Elf_Word type,
|
||||
const char* name,
|
||||
const void* desc,
|
||||
Elf_Word descSize )
|
||||
{
|
||||
pnote->add_note( type, name, desc, descSize );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// modinfo
|
||||
//-----------------------------------------------------------------------------
|
||||
pmodinfo_t elfio_modinfo_section_accessor_new( psection_t psection )
|
||||
{
|
||||
return new ( std::nothrow ) modinfo_section_accessor( psection );
|
||||
}
|
||||
|
||||
void elfio_modinfo_section_accessor_delete( pmodinfo_t pmodinfo )
|
||||
{
|
||||
delete pmodinfo;
|
||||
}
|
||||
|
||||
Elf_Word elfio_modinfo_get_attribute_num( pmodinfo_t pmodinfo )
|
||||
{
|
||||
return pmodinfo->get_attribute_num();
|
||||
}
|
||||
|
||||
bool elfio_modinfo_get_attribute( pmodinfo_t pmodinfo,
|
||||
Elf_Word no,
|
||||
char* field,
|
||||
int field_len,
|
||||
char* value,
|
||||
int value_len )
|
||||
{
|
||||
std::string field_str;
|
||||
std::string value_str;
|
||||
bool ret = pmodinfo->get_attribute( no, field_str, value_str );
|
||||
strncpy( field, field_str.c_str(), (size_t)field_len - 1 );
|
||||
strncpy( value, value_str.c_str(), (size_t)value_len - 1 );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool elfio_modinfo_get_attribute_by_name( pmodinfo_t pmodinfo,
|
||||
char* field_name,
|
||||
char* value,
|
||||
int value_len )
|
||||
{
|
||||
std::string value_str;
|
||||
bool ret = pmodinfo->get_attribute( value_str, value_str );
|
||||
strncpy( value, value_str.c_str(), (size_t)value_len - 1 );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Elf_Word
|
||||
elfio_modinfo_add_attribute( pmodinfo_t pmodinfo, char* field, char* value )
|
||||
{
|
||||
return pmodinfo->add_attribute( field, value );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// dynamic
|
||||
//-----------------------------------------------------------------------------
|
||||
pdynamic_t elfio_dynamic_section_accessor_new( pelfio_t pelfio,
|
||||
psection_t psection )
|
||||
{
|
||||
return new ( std::nothrow ) dynamic_section_accessor( *pelfio, psection );
|
||||
}
|
||||
|
||||
void elfio_dynamic_section_accessor_delete( pdynamic_t pdynamic )
|
||||
{
|
||||
delete pdynamic;
|
||||
}
|
||||
|
||||
Elf_Xword elfio_dynamic_get_entries_num( pdynamic_t pdynamic )
|
||||
{
|
||||
return pdynamic->get_entries_num();
|
||||
}
|
||||
|
||||
bool elfio_dynamic_get_entry( pdynamic_t pdynamic,
|
||||
Elf_Xword index,
|
||||
Elf_Xword* tag,
|
||||
Elf_Xword* value,
|
||||
char* str,
|
||||
int str_len )
|
||||
{
|
||||
std::string str_str;
|
||||
bool ret = pdynamic->get_entry( index, *tag, *value, str_str );
|
||||
strncpy( str, str_str.c_str(), (size_t)str_len - 1 );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void elfio_dynamic_add_entry( pdynamic_t pdynamic,
|
||||
Elf_Xword tag,
|
||||
Elf_Xword value )
|
||||
{
|
||||
pdynamic->add_entry( tag, value );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// array
|
||||
//-----------------------------------------------------------------------------
|
||||
parray_t elfio_array_section_accessor_new( pelfio_t pelfio,
|
||||
psection_t psection )
|
||||
{
|
||||
return new ( std::nothrow )
|
||||
array_section_accessor<Elf64_Word>( *pelfio, psection );
|
||||
}
|
||||
|
||||
void elfio_array_section_accessor_delete( parray_t parray ) { delete parray; }
|
||||
|
||||
Elf_Xword elfio_array_get_entries_num( parray_t parray )
|
||||
{
|
||||
return parray->get_entries_num();
|
||||
}
|
||||
|
||||
bool elfio_array_get_entry( parray_t parray,
|
||||
Elf_Xword index,
|
||||
Elf64_Addr* paddress )
|
||||
{
|
||||
bool ret = parray->get_entry( index, *paddress );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void elfio_array_add_entry( parray_t parray, Elf64_Addr address )
|
||||
{
|
||||
parray->add_entry( address );
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
Copyright (C) 2001-present by Serge Lamikhov-Center
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef ELFIO_C_WRAPPER_H
|
||||
#define ELFIO_C_WRAPPER_H
|
||||
|
||||
#define ELFIO_C_HEADER_ACCESS_GET( TYPE, FNAME ) \
|
||||
TYPE elfio_get_##FNAME( pelfio_t pelfio );
|
||||
|
||||
#define ELFIO_C_HEADER_ACCESS_GET_SET( TYPE, FNAME ) \
|
||||
TYPE elfio_get_##FNAME( pelfio_t pelfio ); \
|
||||
void elfio_set_##FNAME( pelfio_t pelfio, TYPE val );
|
||||
|
||||
#define ELFIO_C_HEADER_ACCESS_GET_IMPL( TYPE, FNAME ) \
|
||||
TYPE elfio_get_##FNAME( pelfio_t pelfio ) { return pelfio->get_##FNAME(); }
|
||||
|
||||
#define ELFIO_C_HEADER_ACCESS_GET_SET_IMPL( TYPE, FNAME ) \
|
||||
TYPE elfio_get_##FNAME( pelfio_t pelfio ) \
|
||||
{ \
|
||||
return pelfio->get_##FNAME(); \
|
||||
} \
|
||||
void elfio_set_##FNAME( pelfio_t pelfio, TYPE val ) \
|
||||
{ \
|
||||
pelfio->set_##FNAME( val ); \
|
||||
}
|
||||
|
||||
#define ELFIO_C_GET_ACCESS_IMPL( CLASS, TYPE, NAME ) \
|
||||
TYPE elfio_##CLASS##_get_##NAME( p##CLASS##_t p##CLASS ) \
|
||||
{ \
|
||||
return p##CLASS->get_##NAME(); \
|
||||
}
|
||||
|
||||
#define ELFIO_C_SET_ACCESS_IMPL( CLASS, TYPE, NAME ) \
|
||||
void elfio_##CLASS##_set_##NAME( p##CLASS##_t p##CLASS, TYPE value ) \
|
||||
{ \
|
||||
p##CLASS->set_##NAME( value ); \
|
||||
}
|
||||
|
||||
#define ELFIO_C_GET_SET_ACCESS_IMPL( CLASS, TYPE, NAME ) \
|
||||
TYPE elfio_##CLASS##_get_##NAME( p##CLASS##_t p##CLASS ) \
|
||||
{ \
|
||||
return p##CLASS->get_##NAME(); \
|
||||
} \
|
||||
void elfio_##CLASS##_set_##NAME( p##CLASS##_t p##CLASS, TYPE value ) \
|
||||
{ \
|
||||
p##CLASS->set_##NAME( value ); \
|
||||
}
|
||||
|
||||
#define ELFIO_C_GET_ACCESS( CLASS, TYPE, NAME ) \
|
||||
TYPE elfio_##CLASS##_get_##NAME( p##CLASS##_t p##CLASS );
|
||||
|
||||
#define ELFIO_C_SET_ACCESS( CLASS, TYPE, NAME ) \
|
||||
void elfio_##CLASS##_set_##NAME( p##CLASS##_t p##CLASS, TYPE value );
|
||||
|
||||
#define ELFIO_C_GET_SET_ACCESS( CLASS, TYPE, NAME ) \
|
||||
TYPE elfio_##CLASS##_get_##NAME( p##CLASS##_t p##CLASS ); \
|
||||
void elfio_##CLASS##_set_##NAME( p##CLASS##_t p##CLASS, TYPE value )
|
||||
|
||||
#ifdef __cplusplus
|
||||
typedef ELFIO::elfio* pelfio_t;
|
||||
typedef ELFIO::section* psection_t;
|
||||
typedef ELFIO::segment* psegment_t;
|
||||
typedef ELFIO::symbol_section_accessor* psymbol_t;
|
||||
typedef ELFIO::relocation_section_accessor* prelocation_t;
|
||||
typedef ELFIO::string_section_accessor* pstring_t;
|
||||
typedef ELFIO::note_section_accessor* pnote_t;
|
||||
typedef ELFIO::modinfo_section_accessor* pmodinfo_t;
|
||||
typedef ELFIO::dynamic_section_accessor* pdynamic_t;
|
||||
typedef ELFIO::array_section_accessor<Elf64_Word>* parray_t;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
typedef void* pelfio_t;
|
||||
typedef void* psection_t;
|
||||
typedef void* psegment_t;
|
||||
typedef void* psymbol_t;
|
||||
typedef void* prelocation_t;
|
||||
typedef void* pstring_t;
|
||||
typedef void* pnote_t;
|
||||
typedef void* pmodinfo_t;
|
||||
typedef void* pdynamic_t;
|
||||
typedef void* parray_t;
|
||||
typedef int bool;
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// elfio
|
||||
//-----------------------------------------------------------------------------
|
||||
pelfio_t elfio_new();
|
||||
void elfio_delete( pelfio_t pelfio );
|
||||
void elfio_create( pelfio_t pelfio,
|
||||
unsigned char file_class,
|
||||
unsigned char encoding );
|
||||
bool elfio_load( pelfio_t pelfio, const char* file_name );
|
||||
bool elfio_save( pelfio_t pelfio, const char* file_name );
|
||||
ELFIO_C_HEADER_ACCESS_GET( unsigned char, class );
|
||||
ELFIO_C_HEADER_ACCESS_GET( unsigned char, elf_version );
|
||||
ELFIO_C_HEADER_ACCESS_GET( unsigned char, encoding );
|
||||
ELFIO_C_HEADER_ACCESS_GET( Elf_Word, version );
|
||||
ELFIO_C_HEADER_ACCESS_GET( Elf_Half, header_size );
|
||||
ELFIO_C_HEADER_ACCESS_GET( Elf_Half, section_entry_size );
|
||||
ELFIO_C_HEADER_ACCESS_GET( Elf_Half, segment_entry_size );
|
||||
ELFIO_C_HEADER_ACCESS_GET_SET( unsigned char, os_abi );
|
||||
ELFIO_C_HEADER_ACCESS_GET_SET( unsigned char, abi_version );
|
||||
ELFIO_C_HEADER_ACCESS_GET_SET( Elf_Half, type );
|
||||
ELFIO_C_HEADER_ACCESS_GET_SET( Elf_Half, machine );
|
||||
ELFIO_C_HEADER_ACCESS_GET_SET( Elf_Word, flags );
|
||||
ELFIO_C_HEADER_ACCESS_GET_SET( Elf64_Addr, entry );
|
||||
ELFIO_C_HEADER_ACCESS_GET_SET( Elf64_Off, sections_offset );
|
||||
ELFIO_C_HEADER_ACCESS_GET_SET( Elf64_Off, segments_offset );
|
||||
ELFIO_C_HEADER_ACCESS_GET_SET( Elf_Half, section_name_str_index );
|
||||
Elf_Half elfio_get_sections_num( pelfio_t pelfio );
|
||||
psection_t elfio_get_section_by_index( pelfio_t pelfio, int index );
|
||||
psection_t elfio_get_section_by_name( pelfio_t pelfio, char* name );
|
||||
psection_t elfio_add_section( pelfio_t pelfio, char* name );
|
||||
Elf_Half elfio_get_segments_num( pelfio_t pelfio );
|
||||
psegment_t elfio_get_segment_by_index( pelfio_t pelfio, int index );
|
||||
psegment_t elfio_add_segment( pelfio_t pelfio );
|
||||
bool elfio_validate( pelfio_t pelfio, char* msg, int msg_len );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// section
|
||||
//-----------------------------------------------------------------------------
|
||||
ELFIO_C_GET_ACCESS( section, Elf_Half, index );
|
||||
ELFIO_C_GET_SET_ACCESS( section, Elf_Word, type );
|
||||
ELFIO_C_GET_SET_ACCESS( section, Elf_Xword, flags );
|
||||
ELFIO_C_GET_SET_ACCESS( section, Elf_Word, info );
|
||||
ELFIO_C_GET_SET_ACCESS( section, Elf_Word, link );
|
||||
ELFIO_C_GET_SET_ACCESS( section, Elf_Xword, addr_align );
|
||||
ELFIO_C_GET_SET_ACCESS( section, Elf_Xword, entry_size );
|
||||
ELFIO_C_GET_SET_ACCESS( section, Elf64_Addr, address );
|
||||
ELFIO_C_GET_SET_ACCESS( section, Elf_Xword, size );
|
||||
ELFIO_C_GET_SET_ACCESS( section, Elf_Word, name_string_offset );
|
||||
ELFIO_C_GET_ACCESS( section, Elf64_Off, offset );
|
||||
void elfio_section_get_name( psection_t psection, char* buffer, int len );
|
||||
void elfio_section_set_name( psection_t psection, char* buffer );
|
||||
char* elfio_section_get_data( psection_t psection );
|
||||
void elfio_section_set_data( psection_t psection,
|
||||
const char* pData,
|
||||
Elf_Word size );
|
||||
void elfio_section_append_data( psection_t psection,
|
||||
const char* pData,
|
||||
Elf_Word size );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// segment
|
||||
//-----------------------------------------------------------------------------
|
||||
ELFIO_C_GET_ACCESS( segment, Elf_Half, index );
|
||||
ELFIO_C_GET_SET_ACCESS( segment, Elf_Word, type );
|
||||
ELFIO_C_GET_SET_ACCESS( segment, Elf_Word, flags );
|
||||
ELFIO_C_GET_SET_ACCESS( segment, Elf_Xword, align );
|
||||
ELFIO_C_GET_SET_ACCESS( segment, Elf_Xword, memory_size );
|
||||
ELFIO_C_GET_SET_ACCESS( segment, Elf64_Addr, virtual_address );
|
||||
ELFIO_C_GET_SET_ACCESS( segment, Elf64_Addr, physical_address );
|
||||
ELFIO_C_GET_SET_ACCESS( segment, Elf_Xword, file_size );
|
||||
ELFIO_C_GET_ACCESS( segment, Elf64_Off, offset );
|
||||
char* elfio_segment_get_data( psegment_t psegment );
|
||||
Elf_Half elfio_segment_add_section_index( psegment_t psegment,
|
||||
Elf_Half index,
|
||||
Elf_Xword addr_align );
|
||||
Elf_Half elfio_segment_get_sections_num( psegment_t psegment );
|
||||
Elf_Half elfio_segment_get_section_index_at( psegment_t psegment,
|
||||
Elf_Half num );
|
||||
bool elfio_segment_is_offset_initialized( psegment_t psegment );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// symbol
|
||||
//-----------------------------------------------------------------------------
|
||||
psymbol_t elfio_symbol_section_accessor_new( pelfio_t pelfio,
|
||||
psection_t psection );
|
||||
void elfio_symbol_section_accessor_delete( psymbol_t psymbol );
|
||||
Elf_Xword elfio_symbol_get_symbols_num( psymbol_t psymbol );
|
||||
bool elfio_symbol_get_symbol( psymbol_t psymbol,
|
||||
Elf_Xword index,
|
||||
char* name,
|
||||
int name_len,
|
||||
Elf64_Addr* value,
|
||||
Elf_Xword* size,
|
||||
unsigned char* bind,
|
||||
unsigned char* type,
|
||||
Elf_Half* section_index,
|
||||
unsigned char* other );
|
||||
Elf_Word elfio_symbol_add_symbol( psymbol_t psymbol,
|
||||
Elf_Word name,
|
||||
Elf64_Addr value,
|
||||
Elf_Xword size,
|
||||
unsigned char info,
|
||||
unsigned char other,
|
||||
Elf_Half shndx );
|
||||
Elf_Xword elfio_symbol_arrange_local_symbols(
|
||||
psymbol_t psymbol,
|
||||
void ( *func )( Elf_Xword first, Elf_Xword second ) );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// relocation
|
||||
//-----------------------------------------------------------------------------
|
||||
prelocation_t elfio_relocation_section_accessor_new( pelfio_t pelfio,
|
||||
psection_t psection );
|
||||
void elfio_relocation_section_accessor_delete( prelocation_t prelocation );
|
||||
Elf_Xword elfio_relocation_get_entries_num( prelocation_t prelocation );
|
||||
bool elfio_relocation_get_entry( prelocation_t prelocation,
|
||||
Elf_Xword index,
|
||||
Elf64_Addr* offset,
|
||||
Elf_Word* symbol,
|
||||
Elf_Word* type,
|
||||
Elf_Sxword* addend );
|
||||
bool elfio_relocation_set_entry( prelocation_t prelocation,
|
||||
Elf_Xword index,
|
||||
Elf64_Addr offset,
|
||||
Elf_Word symbol,
|
||||
Elf_Word type,
|
||||
Elf_Sxword addend );
|
||||
void elfio_relocation_add_entry( prelocation_t prelocation,
|
||||
Elf64_Addr offset,
|
||||
Elf_Word symbol,
|
||||
unsigned char type,
|
||||
Elf_Sxword addend );
|
||||
void elfio_relocation_swap_symbols( prelocation_t prelocation,
|
||||
Elf_Xword first,
|
||||
Elf_Xword second );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// string
|
||||
//-----------------------------------------------------------------------------
|
||||
pstring_t elfio_string_section_accessor_new( psection_t psection );
|
||||
void elfio_string_section_accessor_delete( pstring_t pstring );
|
||||
const char* elfio_string_get_string( pstring_t pstring, Elf_Word index );
|
||||
Elf_Word elfio_string_add_string( pstring_t pstring, char* str );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// note
|
||||
//-----------------------------------------------------------------------------
|
||||
pnote_t elfio_note_section_accessor_new( pelfio_t pelfio,
|
||||
psection_t psection );
|
||||
void elfio_note_section_accessor_delete( pnote_t pstring );
|
||||
Elf_Word elfio_note_get_notes_num( pnote_t pnote );
|
||||
bool elfio_note_get_note( pnote_t pnote,
|
||||
Elf_Word index,
|
||||
Elf_Word* type,
|
||||
char* name,
|
||||
int name_len,
|
||||
void** desc,
|
||||
Elf_Word* descSize );
|
||||
void elfio_note_add_note( pnote_t pnote,
|
||||
Elf_Word type,
|
||||
const char* name,
|
||||
const void* desc,
|
||||
Elf_Word descSize );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// modinfo
|
||||
//-----------------------------------------------------------------------------
|
||||
pmodinfo_t elfio_modinfo_section_accessor_new( psection_t psection );
|
||||
void elfio_modinfo_section_accessor_delete( pmodinfo_t pmodinfo );
|
||||
Elf_Word elfio_modinfo_get_attribute_num( pmodinfo_t pmodinfo );
|
||||
bool elfio_modinfo_get_attribute( pmodinfo_t pmodinfo,
|
||||
Elf_Word no,
|
||||
char* field,
|
||||
int field_len,
|
||||
char* value,
|
||||
int value_len );
|
||||
bool elfio_modinfo_get_attribute_by_name( pmodinfo_t pmodinfo,
|
||||
char* field_name,
|
||||
char* value,
|
||||
int value_len );
|
||||
Elf_Word elfio_modinfo_add_attribute( pmodinfo_t pmodinfo,
|
||||
char* field,
|
||||
char* value );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// dynamic
|
||||
//-----------------------------------------------------------------------------
|
||||
pdynamic_t elfio_dynamic_section_accessor_new( pelfio_t pelfio,
|
||||
psection_t psection );
|
||||
void elfio_dynamic_section_accessor_delete( pdynamic_t pdynamic );
|
||||
Elf_Xword elfio_dynamic_get_entries_num( pdynamic_t pdynamic );
|
||||
bool elfio_dynamic_get_entry( pdynamic_t pdynamic,
|
||||
Elf_Xword index,
|
||||
Elf_Xword* tag,
|
||||
Elf_Xword* value,
|
||||
char* str,
|
||||
int str_len );
|
||||
void elfio_dynamic_add_entry( pdynamic_t pdynamic,
|
||||
Elf_Xword tag,
|
||||
Elf_Xword value );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// array
|
||||
//-----------------------------------------------------------------------------
|
||||
parray_t elfio_array_section_accessor_new( pelfio_t pelfio,
|
||||
psection_t psection );
|
||||
void elfio_array_section_accessor_delete( parray_t parray );
|
||||
Elf_Xword elfio_array_get_entries_num( parray_t parray );
|
||||
bool elfio_array_get_entry( parray_t parray,
|
||||
Elf_Xword index,
|
||||
Elf64_Addr* paddress );
|
||||
void elfio_array_add_entry( parray_t parray, Elf64_Addr address );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ELFIO_C_WRAPPER_H
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
add_executable(elfdump elfdump.cpp)
|
||||
target_link_libraries(elfdump PRIVATE elfio::elfio)
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
elfdump.cpp - Dump ELF file using ELFIO library.
|
||||
|
||||
Copyright (C) 2001-present by Serge Lamikhov-Center
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define ELFIO_NO_INTTYPES
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <elfio/elfio_dump.hpp>
|
||||
|
||||
using namespace ELFIO;
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
if ( argc != 2 ) {
|
||||
printf( "Usage: elfdump <file_name>\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
elfio reader;
|
||||
|
||||
if ( !reader.load( argv[1] ) ) {
|
||||
printf( "File %s is not found or it is not an ELF file\n", argv[1] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
dump::header( std::cout, reader );
|
||||
dump::section_headers( std::cout, reader );
|
||||
dump::segment_headers( std::cout, reader );
|
||||
dump::symbol_tables( std::cout, reader );
|
||||
dump::notes( std::cout, reader );
|
||||
dump::modinfo( std::cout, reader );
|
||||
dump::dynamic_tags( std::cout, reader );
|
||||
dump::section_datas( std::cout, reader );
|
||||
dump::segment_datas( std::cout, reader );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
add_executable(elfio-ldd elfio_ldd.cpp)
|
||||
target_link_libraries(elfio-ldd PRIVATE elfio::elfio)
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
elfio_ldd.cpp - Use ELFIO library to list dynamic libraries required by ELF file.
|
||||
|
||||
2025 Pasha-From-Russia
|
||||
|
||||
ELFIO Copyright (C) 2001-present by Serge Lamikhov-Center
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define ELFIO_NO_INTTYPES
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <elfio/elfio_dump.hpp>
|
||||
|
||||
using namespace ELFIO;
|
||||
|
||||
static const bool kPrintNamesOnly = true;
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
if ( argc != 2 ) {
|
||||
printf( "Usage: elfio_ldd <file_name>\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
elfio reader;
|
||||
|
||||
if ( !reader.load( argv[1] ) ) {
|
||||
printf( "File %s is not found or it is not an ELF file\n", argv[1] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
dump::dynamic_tags( std::cout, reader, kPrintNamesOnly );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
add_executable(proc_mem proc_mem.cpp)
|
||||
target_link_libraries(proc_mem PRIVATE elfio::elfio)
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
Copyright (C) 2001-present by Serge Lamikhov-Center
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <regex>
|
||||
|
||||
#include <elfio/elfio.hpp>
|
||||
#include <elfio/elfio_dump.hpp>
|
||||
|
||||
using namespace ELFIO;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void get_translation_ranges( std::ifstream& proc_maps,
|
||||
const std::string& file_name,
|
||||
std::vector<address_translation>& result )
|
||||
{
|
||||
result.clear();
|
||||
|
||||
const std::regex rexpr(
|
||||
"([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r]...) ([0-9A-Fa-f]+) (.....) "
|
||||
"([0-9]+)([[:blank:]]*)([[:graph:]]*)" );
|
||||
std::smatch match;
|
||||
while ( proc_maps ) {
|
||||
std::string line;
|
||||
std::getline( proc_maps, line );
|
||||
|
||||
if ( std::regex_match( line, match, rexpr ) ) {
|
||||
if ( match.size() == 9 && match[8].str() == file_name ) {
|
||||
unsigned long start = std::stoul( match[1].str(), 0, 16 );
|
||||
unsigned long end = std::stoul( match[2].str(), 0, 16 );
|
||||
unsigned long actual = std::stoul( match[4].str(), 0, 16 );
|
||||
result.emplace_back( actual, end - start, start );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
if ( argc != 3 ) {
|
||||
std::cout << "Usage: proc_mem <pid> <full_file_path>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Process file translation regions for the ELF file from /proc/pid/maps
|
||||
std::ifstream proc_maps( std::string( "/proc/" ) + argv[1] + "/maps" );
|
||||
if ( !proc_maps ) {
|
||||
std::cout << "Can't open "
|
||||
<< std::string( "/proc/" ) + argv[1] + "/maps" << " file"
|
||||
<< std::endl;
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Retrieve memory address translation ranges
|
||||
std::vector<address_translation> ranges;
|
||||
get_translation_ranges( proc_maps, argv[2], ranges );
|
||||
|
||||
// Set address translation ranges prior loading ELF file
|
||||
elfio elffile;
|
||||
elffile.set_address_translation( ranges );
|
||||
|
||||
// The 'load' will use the provided address translation now
|
||||
if ( elffile.load( std::string( "/proc/" ) + argv[1] + "/mem", true ) ) {
|
||||
dump::header( std::cout, elffile );
|
||||
dump::segment_headers( std::cout, elffile );
|
||||
dump::segment_datas( std::cout, elffile );
|
||||
}
|
||||
else {
|
||||
std::cout << "Can't open " << std::string( "/proc/" ) + argv[1] + "/mem"
|
||||
<< " file" << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
# The file is used for VSCode debugging with sudo. Use it as following:
|
||||
# "miDebuggerPath": "/home/user/ELFIO/examples/sudo_gdb.sh"
|
||||
sudo /usr/bin/gdb "$@"
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
add_executable(tutorial tutorial.cpp)
|
||||
target_link_libraries(tutorial PRIVATE elfio::elfio)
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
Copyright (C) 2001-present by Serge Lamikhov-Center
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <elfio/elfio.hpp>
|
||||
|
||||
using namespace ELFIO;
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
if ( argc != 2 ) {
|
||||
std::cout << "Usage: tutorial <elf_file>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create an elfio reader
|
||||
elfio reader;
|
||||
|
||||
// Load ELF data
|
||||
if ( !reader.load( argv[1] ) ) {
|
||||
std::cout << "Can't find or process ELF file " << argv[1] << std::endl;
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Print ELF file properties
|
||||
std::cout << "ELF file class : ";
|
||||
if ( reader.get_class() == ELFCLASS32 )
|
||||
std::cout << "ELF32" << std::endl;
|
||||
else
|
||||
std::cout << "ELF64" << std::endl;
|
||||
|
||||
std::cout << "ELF file encoding : ";
|
||||
if ( reader.get_encoding() == ELFDATA2LSB )
|
||||
std::cout << "Little endian" << std::endl;
|
||||
else
|
||||
std::cout << "Big endian" << std::endl;
|
||||
|
||||
// Print ELF file sections info
|
||||
Elf_Half sec_num = reader.sections.size();
|
||||
std::cout << "Number of sections: " << sec_num << std::endl;
|
||||
for ( int i = 0; i < sec_num; ++i ) {
|
||||
section* psec = reader.sections[i];
|
||||
std::cout << " [" << i << "] " << psec->get_name() << "\t"
|
||||
<< psec->get_size() << std::endl;
|
||||
// Access to section's data
|
||||
// const char* p = reader.sections[i]->get_data()
|
||||
}
|
||||
|
||||
// Print ELF file segments info
|
||||
Elf_Half seg_num = reader.segments.size();
|
||||
std::cout << "Number of segments: " << seg_num << std::endl;
|
||||
for ( int i = 0; i < seg_num; ++i ) {
|
||||
const segment* pseg = reader.segments[i];
|
||||
std::cout << " [" << i << "] 0x" << std::hex << pseg->get_flags()
|
||||
<< "\t0x" << pseg->get_virtual_address() << "\t0x"
|
||||
<< pseg->get_file_size() << "\t0x" << pseg->get_memory_size()
|
||||
<< std::endl;
|
||||
// Access to segments's data
|
||||
// const char* p = reader.segments[i]->get_data()
|
||||
}
|
||||
|
||||
for ( int i = 0; i < sec_num; ++i ) {
|
||||
section* psec = reader.sections[i];
|
||||
// Check section type
|
||||
if ( psec->get_type() == SHT_SYMTAB ) {
|
||||
const symbol_section_accessor symbols( reader, psec );
|
||||
for ( unsigned int j = 0; j < symbols.get_symbols_num(); ++j ) {
|
||||
std::string name;
|
||||
Elf64_Addr value;
|
||||
Elf_Xword size;
|
||||
unsigned char bind;
|
||||
unsigned char type;
|
||||
Elf_Half section_index;
|
||||
unsigned char other;
|
||||
|
||||
// Read symbol properties
|
||||
symbols.get_symbol( j, name, value, size, bind, type,
|
||||
section_index, other );
|
||||
std::cout << j << " " << name << " " << value << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
add_executable(write_obj write_obj.cpp)
|
||||
target_link_libraries(write_obj PRIVATE elfio::elfio)
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
Copyright (C) 2001-present by Serge Lamikhov-Center
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This example shows how to create ELF object file for Linux on x86
|
||||
*
|
||||
* Instructions:
|
||||
* 1. Compile and link this file with ELFIO library
|
||||
* g++ write_obj.cpp -o writer_obj
|
||||
* 2. Execute result file write_obj
|
||||
* ./write_obj
|
||||
* 3. Link output file hello.o:
|
||||
* ld -o hello hello.o
|
||||
* 4. Run the result file:
|
||||
* ./hello
|
||||
*/
|
||||
|
||||
#include <elfio/elfio.hpp>
|
||||
|
||||
using namespace ELFIO;
|
||||
|
||||
int main( void )
|
||||
{
|
||||
elfio writer;
|
||||
|
||||
// You can't proceed before this function call!
|
||||
writer.create( ELFCLASS64, ELFDATA2LSB );
|
||||
|
||||
writer.set_os_abi( ELFOSABI_LINUX );
|
||||
writer.set_type( ET_REL );
|
||||
writer.set_machine( EM_X86_64 );
|
||||
|
||||
// This is our code
|
||||
char text[] = {
|
||||
'\xB8', '\x04', '\x00', '\x00', '\x00', // mov eax, 4
|
||||
'\xBB', '\x01', '\x00', '\x00', '\x00', // mov ebx, 1
|
||||
'\xB9', '\x00', '\x00', '\x00', '\x00', // mov ecx, msg
|
||||
'\xBA', '\x0E', '\x00', '\x00', '\x00', // mov edx, 14
|
||||
'\xCD', '\x80', // int 0x80
|
||||
'\xB8', '\x01', '\x00', '\x00', '\x00', // mov eax, 1
|
||||
'\xCD', '\x80', // int 0x80
|
||||
'\x48', '\x65', '\x6C', '\x6C', '\x6F', // msg: db 'Hello, World!', 10
|
||||
'\x2C', '\x20', '\x57', '\x6F', '\x72',
|
||||
'\x6C', '\x64', '\x21', '\x0A' };
|
||||
Elf64_Addr place_to_adjust = 11;
|
||||
|
||||
// Create code section
|
||||
section* text_sec = writer.sections.add( ".text" );
|
||||
text_sec->set_type( SHT_PROGBITS );
|
||||
text_sec->set_flags( SHF_ALLOC | SHF_EXECINSTR );
|
||||
text_sec->set_addr_align( 0x10 );
|
||||
text_sec->set_data( text, sizeof( text ) );
|
||||
|
||||
// Create string table section
|
||||
section* str_sec = writer.sections.add( ".strtab" );
|
||||
str_sec->set_type( SHT_STRTAB );
|
||||
|
||||
// Create string table writer
|
||||
string_section_accessor stra( str_sec );
|
||||
// Add label name
|
||||
Elf32_Word str_index = stra.add_string( "msg" );
|
||||
|
||||
// Create symbol table section
|
||||
section* sym_sec = writer.sections.add( ".symtab" );
|
||||
sym_sec->set_type( SHT_SYMTAB );
|
||||
sym_sec->set_info( 1 );
|
||||
sym_sec->set_addr_align( 0x4 );
|
||||
sym_sec->set_entry_size( writer.get_default_entry_size( SHT_SYMTAB ) );
|
||||
sym_sec->set_link( str_sec->get_index() );
|
||||
|
||||
// Create symbol table writer
|
||||
symbol_section_accessor syma( writer, sym_sec );
|
||||
// Add symbol entry (msg has offset == 29)
|
||||
Elf_Word sym_to_adjust = syma.add_symbol(
|
||||
str_index, 29, 0, STB_GLOBAL, STT_OBJECT, 0, text_sec->get_index() );
|
||||
// Another way to add symbol
|
||||
syma.add_symbol( stra, "_start", 0x00000000, 0, STB_WEAK, STT_FUNC, 0,
|
||||
text_sec->get_index() );
|
||||
|
||||
// Create relocation table section
|
||||
section* rel_sec = writer.sections.add( ".rel.text" );
|
||||
rel_sec->set_type( SHT_REL );
|
||||
rel_sec->set_info( text_sec->get_index() );
|
||||
rel_sec->set_addr_align( 0x4 );
|
||||
rel_sec->set_entry_size( writer.get_default_entry_size( SHT_REL ) );
|
||||
rel_sec->set_link( sym_sec->get_index() );
|
||||
|
||||
// Create relocation table writer
|
||||
relocation_section_accessor rela( writer, rel_sec );
|
||||
// Add relocation entry (adjust address at offset 11)
|
||||
rela.add_entry( place_to_adjust, sym_to_adjust,
|
||||
(unsigned char)R_X86_64_32 );
|
||||
|
||||
// Another method to add the same relocation entry at one step is:
|
||||
// rela.add_entry( stra, "msg",
|
||||
// syma, 29, 0,
|
||||
// ELF_ST_INFO( STB_GLOBAL, STT_OBJECT ), 0,
|
||||
// text_sec->get_index(),
|
||||
// place_to_adjust, (unsigned char)R_386_RELATIVE );
|
||||
|
||||
// Create note section
|
||||
section* note_sec = writer.sections.add( ".note" );
|
||||
note_sec->set_type( SHT_NOTE );
|
||||
|
||||
note_section_accessor note_writer( writer, note_sec );
|
||||
note_writer.add_note( 0x01, "Created by ELFIO", 0, 0 );
|
||||
char descr[6] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36 };
|
||||
note_writer.add_note( 0x01, "Never easier!", descr, sizeof( descr ) );
|
||||
|
||||
// We don't use local symbols here. There is no need to rearrange them.
|
||||
// But, for the completeness, we do this just prior 'save'
|
||||
syma.arrange_local_symbols( [&]( Elf_Xword first, Elf_Xword second ) {
|
||||
rela.swap_symbols( first, second );
|
||||
} );
|
||||
|
||||
// Create ELF object file
|
||||
writer.save( "hello.o" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
add_executable(writer writer.cpp)
|
||||
target_link_libraries(writer PRIVATE elfio::elfio)
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
Copyright (C) 2001-present by Serge Lamikhov-Center
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This example shows how to create ELF executable file for Linux on x86-64
|
||||
*
|
||||
* Instructions:
|
||||
* 1. Compile and link this file with ELFIO library
|
||||
* g++ writer.cpp -o writer
|
||||
* 2. Execute result file writer
|
||||
* ./writer
|
||||
* 3. Add executable flag for the output file
|
||||
* chmod +x hello_x86_64
|
||||
* 4. Run the result file:
|
||||
* ./hello_x86_64
|
||||
*/
|
||||
|
||||
#include <elfio/elfio.hpp>
|
||||
|
||||
using namespace ELFIO;
|
||||
|
||||
const Elf64_Addr CODE_ADDR = 0x00401000;
|
||||
const Elf_Xword PAGE_SIZE = 0x1000;
|
||||
const Elf64_Addr DATA_ADDR = CODE_ADDR + PAGE_SIZE;
|
||||
|
||||
int main( void )
|
||||
{
|
||||
elfio writer;
|
||||
|
||||
// You can't proceed without this function call!
|
||||
writer.create( ELFCLASS64, ELFDATA2LSB );
|
||||
|
||||
writer.set_os_abi( ELFOSABI_LINUX );
|
||||
writer.set_type( ET_EXEC );
|
||||
writer.set_machine( EM_X86_64 );
|
||||
|
||||
// Create code section
|
||||
section* text_sec = writer.sections.add( ".text" );
|
||||
text_sec->set_type( SHT_PROGBITS );
|
||||
text_sec->set_flags( SHF_ALLOC | SHF_EXECINSTR );
|
||||
text_sec->set_addr_align( 0x10 );
|
||||
|
||||
// Add data into it
|
||||
char text[] = {
|
||||
'\xB8', '\x04', '\x00', '\x00', '\x00', // mov eax, 4
|
||||
'\xBB', '\x01', '\x00', '\x00', '\x00', // mov ebx, 1
|
||||
'\xB9', '\x00', '\x00', '\x00', '\x00', // mov ecx, msg
|
||||
'\xBA', '\x0E', '\x00', '\x00', '\x00', // mov edx, 14
|
||||
'\xCD', '\x80', // int 0x80
|
||||
'\xB8', '\x01', '\x00', '\x00', '\x00', // mov eax, 1
|
||||
'\xCD', '\x80' // int 0x80
|
||||
};
|
||||
// Adjust data address for 'msg'
|
||||
*(std::uint32_t*)( text + 11 ) = DATA_ADDR;
|
||||
|
||||
text_sec->set_data( text, sizeof( text ) );
|
||||
|
||||
// Create a loadable segment
|
||||
segment* text_seg = writer.segments.add();
|
||||
text_seg->set_type( PT_LOAD );
|
||||
text_seg->set_virtual_address( CODE_ADDR );
|
||||
text_seg->set_physical_address( CODE_ADDR );
|
||||
text_seg->set_flags( PF_X | PF_R );
|
||||
text_seg->set_align( PAGE_SIZE );
|
||||
|
||||
// Add code section into program segment
|
||||
text_seg->add_section( text_sec, text_sec->get_addr_align() );
|
||||
|
||||
// Create data section
|
||||
section* data_sec = writer.sections.add( ".data" );
|
||||
data_sec->set_type( SHT_PROGBITS );
|
||||
data_sec->set_flags( SHF_ALLOC | SHF_WRITE );
|
||||
data_sec->set_addr_align( 0x4 );
|
||||
|
||||
char data[] = {
|
||||
'\x48', '\x65', '\x6C', '\x6C', '\x6F', // msg: db 'Hello, World!', 10
|
||||
'\x2C', '\x20', '\x57', '\x6F', '\x72',
|
||||
'\x6C', '\x64', '\x21', '\x0A' };
|
||||
data_sec->set_data( data, sizeof( data ) );
|
||||
|
||||
// Create a read/write segment
|
||||
segment* data_seg = writer.segments.add();
|
||||
data_seg->set_type( PT_LOAD );
|
||||
data_seg->set_virtual_address( DATA_ADDR );
|
||||
data_seg->set_physical_address( DATA_ADDR );
|
||||
data_seg->set_flags( PF_W | PF_R );
|
||||
data_seg->set_align( PAGE_SIZE );
|
||||
|
||||
// Add code section into program segment
|
||||
data_seg->add_section( data_sec, data_sec->get_addr_align() );
|
||||
|
||||
// Add optional signature for the file producer
|
||||
section* note_sec = writer.sections.add( ".note" );
|
||||
note_sec->set_type( SHT_NOTE );
|
||||
note_sec->set_addr_align( 1 );
|
||||
|
||||
note_section_accessor note_writer( writer, note_sec );
|
||||
note_writer.add_note( 0x01, "Created by ELFIO", 0, 0 );
|
||||
char descr[6] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36 };
|
||||
note_writer.add_note( 0x01, "Never easier!", descr, sizeof( descr ) );
|
||||
|
||||
// Setup entry point. Usually, a linker sets this address on base of
|
||||
// ‘_start’ label.
|
||||
// In this example, the code starts at the first address of the
|
||||
// 'text_seg' segment. Therefore, the start address is set
|
||||
// to be equal to the segment location
|
||||
writer.set_entry( text_seg->get_virtual_address() );
|
||||
|
||||
// Create ELF file
|
||||
writer.save( "hello_x86_64" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user