NAME
ELF::Writer - Encode elf files with pure-perl
VERSION
version 0.011
SYNOPSIS
my $elf= ELF::Writer::Linux_x86_64->new(
type => 'executable',
segments => [{
virt_addr => 0x10000,
data => $my_machine_code,
}],
entry_point => 0x10000,
);
$elf->write_file($binary_name);
# Example above wastes almost 4K to align the first segment.
# We can overlap the first segment with the elf header, so that the entire
# file gets paged into RAM, but then the entry point needs adjusted by the
# size of the ELF headers.
my $prog_offset= $elf->elf_header_len + $elf->segment_header_elem_len;
$elf->segments->[0]->offset(0);
$elf->segments->[0]->data_start( $prog_offset );
$elf->entry_point( $elf->segments->[0]->virt_addr + $prog_offset );
MODULE STATUS
I wrote this module while learning the ELF format, so this is not the work of an expert. But, since there wasn't anything on CPAN yet, I decided to implement as complete an API as I could and release it. Bug reports are very welcome.
DESCRPTION
This module lets you define the attributes, segments, and sections of the ELF specification, and then serialize it to a file. All data must reside in memory before writing, so this module is really just a very elaborate call to 'pack'. This module also assumes you know how an ELF file is structured, and the purpose of Segments and Sections. Patches welcome for adding user-friendly features and sanity checks.
ATTRIBUTES
Note on enumerated values: The ELF format has enumerations for many of its fields which are left open-ended to be extended in the future. Also, the symbolic names seem to differ between various sources, so it was difficult to determine what the official names should be. My solution was to store the attribute as the numeric value, but auto-convert symbolic names, and allow access to the symbolic name by a second attribute accessor with suffix "_sym".
class, class_sym
8-bit integer, or one of: "32bit"
or "64bit"
. Must be set before writing.
data, data_sym
8-bit integer, or one of: "2LSB"
or "2MSB"
. (2's complement least/most significant byte first) i.e. little-endian or big-endian
Must be set before writing.
header_version
8-bit integer; defaults to '1' for original version of ELF.
osabi, osabi_sym
8-bit integer, or one of: "SystemV"
, "HP-UX"
, "NetBSD"
, "Linux"
, "Solaris"
, "AIX"
, "IRIX"
, "FreeBSD"
, "OpenBSD"
, "OpenVMS"
. Must be set before writing.
osabi_version
Depends on osabi. Not used for Linux. Defaults to 0.
type, type_sym
16-bit integer, or one of: "relocatable"
, "executable"
, "shared"
, "core"
. Must be set before writing.
machine, machine_sym
16-bit integer, or one of: "Sparc"
, "x86"
, "MIPS"
, "PowerPC"
, "ARM"
, "SuperH"
, "IA-64"
, "x86-64"
, "AArch64"
.
version
32-bit integer; defaults to 1
for original version of ELF.
entry_point
32-bit or 64-bit pointer to address where process starts executing. Defaults to 0
unless type is "executable"
, then you must specify it before writing.
flags
32 bit flags, defined per-machine.
elf_header_len
Read-only, determined from "class". (52 or 64 bytes)
segment_header_elem_len
Read-only, determined from "class". (32 or 56 bytes)
section_header_elem_len
Read-only, determined from "class". (40 or 64 bytes)
segments
Arrayref of ELF::Writer::Segment objects. You can also pass hashrefs to the constructor which will be coerced automatically.
segment_count
Handy alias for $#{ $elf->segments }
segment_list
Handy alias for @{ $elf->segments }
sections
Arrayref of ELF::Writer::Section objects. You can also pass hashrefs to the constructor which will be coerced automatically.
section_count
Handy alias for $#{ $elf->sections }
section_list
Handy alias for @{ $elf->sections }
section_name_string_table_idx
Index into the section array of a string-table section where the names of the sections are stored.
METHODS
serialize
Return a string of the composed ELF file. Throws exceptions if required attributes are missing.
write_file
$elf->write_file( $filename [, $mode]);
Convenience method for writing to a file. Writes with mode 0755 by default.
SEE ALSO
Brian Raiter has a nice write-up of how to hack around on ELF files, which I found very educational:
http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html
AUTHOR
Michael Conrad <mike@nrdvana.net>
COPYRIGHT AND LICENSE
This software is copyright (c) 2017 by Michael Conrad.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.