To get a basic understanding of the ELF format, I'm writing a basic program to generate a valid elf file from the most basic assembly output. I'm going step-by-step so I'll probably ask a few questions here as I make my way through it. I've generated the first 16-bytes of the header and verified that it's the same from a gcc-compiled program on my machine (nothing special, since those first 16-bytes are almost always the same). Here is what I have so far (using python):
# https://refspecs.linuxfoundation.org/elf/elf.pdf
b = bytearray()
# (1) magic header
b.append(0x7F) # starting number
b.extend([ord('E'), ord('L'), ord('F')])
# (2) ei-class ('capacity') -- 1 for 32-bit, 2 for 64-bit
# uname -m # x86_64
BITS_32 = 1
BITS_64 = 2
b.append(BITS_64)
# (3) ei-data ('data-encoding') -- 1 for little-endian (standard), 2 for big-endian
LITTLE_ENDIAN = 1
BIG_ENDIAN = 2
b.append(LITTLE_ENDIAN)
# (4) ei-version -- always will be 1 --
EV_CURRENT = 1
b.append(EV_CURRENT)
# (5) ei-pad -- padding --> pad 0's up to 16 bytes
b.extend([0,] * (16-len(b)))
print('%s\nLength: %s' % (b, len(b)))
And I get:
bytearray(b'\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00')
Length: 16
I have a few questions about this:
- What is the most common way to get whether a machine is
32
or64
bits? Is doinguname -m
or one of theuname
variants the suggested way? - How do you determine if the machine is little- or big-endian?
platform
module?