Skip to content

Instantly share code, notes, and snippets.

@ilhooq
Last active March 19, 2022 19:02
Show Gist options
  • Save ilhooq/5baa0a6b9fd442efb517a58e37cd8121 to your computer and use it in GitHub Desktop.
Save ilhooq/5baa0a6b9fd442efb517a58e37cd8121 to your computer and use it in GitHub Desktop.
Build a binary Hello World executable on Linux with Python using hexadecimal X86 machine instructions
"""
This script create a hello word 64bits binary executable in ELF format.
It's goal is to describe how work a binary program on Linux at the lowest system level.
To build the binary run :
python hello.py
chmod +x hello.py
Then run the program :
./hello
"""
data=[
# ---------- ELF HEADER -------------------
# ELF Identification
0x7F, # Char ASCII 127 (delete)
0x45, # Char ASCII 69 (E)
0x4C, # Char ASCII 76 (L)
0x46, # Char ASCII 70 (F)
0x02, # Exec type (1: 32bits, 2: 64bits)
0x01, # Data encoding (1: LSB, 2: MSB) // LSB : Least Significant Bit (little-endian)
0x01, # Version (1: Original version of ELF format, 0: Invalid version)
0x00, # Reserved byte for future usage
0x00, # Reserved byte for future usage
0x00, # Reserved byte for future usage
0x00, # Reserved byte for future usage
0x00, # Reserved byte for future usage
0x00, # Reserved byte for future usage
0x00, # Reserved byte for future usage
0x00, # Reserved byte for future usage
0x00, # Reserved byte for future usage
0x02, # Object type [half-word] (2: executable, 1:relocatable, 3:shared, 4:core)
0x00,
0x3E, # e_machine [half-word] AMD64
0x00,
0x01, # e_version [word] Current version
0x00,
0x00,
0x00,
0xB0, # e_entry [word] 64 bit address corresponding to the program entry point (here 0x4000b0)
0x00,
0x40,
0x00,
0x00,
0x00,
0x00,
0x00,
0x40, # e_phoff - The program header table's file offset in bytes. (here 0x40)
0x00, # If the file has no program header table, this member holds zero.
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, # e_shoff - the program section table's file offset in bytes. (here 0x100)
0x01, # If the file has no program header table, this member holds zero.
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, # e_flags - This member holds processor-specific flags associated with the file.
0x00,
0x00,
0x00,
0x40, # e_ehsize - Size of this header. Holds the ELF header's size in bytes. (64 bytes)
0x00,
0x38, # e_phentsize - Size of program headers (56 bytes)
0x00, # Holds the size in bytes of one entry in the file's program header table; all entries are the same size.
0x02, # e_phnum - Number of program headers (2)
0x00, # This member holds the number of entries in the program header table. Thus the product of e_phentsize and
# e_phnum gives the table's size in bytes. If a filehas no program header table, e_phnum holds the value zero.
0x40, # e_shentsize - Size of section headers (64 byts) .
0x00, # This member holds a section header's size in bytes.
# A section header is one entry in the section header table; all entries are the same size.
0x04, # e_shnum - Number of section headers (4)
0x00, # This member holds the number of entries in the section header table.
# Thus the product of e_shentsize and e_shnum gives the section header table's size in bytes.
# If a file has no section header table, e_shnum holds the value zero.
0x03, # e_shstrndx Section header string table index (3)
0x00, # - This member holds the section header table index of the entry associated with the
# section name string table. If the file has no section name string table, this member
# holds the value SHN_UNDEF. See "Sections" and "String Table" below for more
# information.
# 64 bytes
# ----------- PROGRAM HEADER TABLE'S ----------
# ----------- Segment 1 description-------
0x01, # p_type - identifies the type of segment.
0x00, # (1: Loadable segment, 2: Dynamic linking tables, 3: Program interpreter path name, 4: Note sections)
0x00,
0x00,
0x05, # p_flags - contains the segment attributes. 5: Read, Execute
0x00,
0x00,
0x00,
0x00, # p_offset - contains the offset, in bytes, of the segment from the beginning of the file.
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, # p_vaddr - contains the virtual address of the segment in memory.
0x00,
0x40,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, # p_paddr - is reserved for systems with physical addressing.
0x00,
0x40,
0x00,
0x00,
0x00,
0x00,
0x00,
0xD2, # p_filesz - contains the size, in bytes, of the file image of the segment.
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0xD2, # p_memsz - contains the size, in bytes, of the memory image of the segment.
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, # p_align - specifies the alignment constraint for the segment. Must be a
0x00, # power of two. The values of p_offset and p_vaddr must be congruent modulo the alignment.
0x20,
0x00,
0x00,
0x00,
0x00,
0x00,
# 120 octets
# ----------- Segment 2 description-------
0x01, # p_type
0x00,
0x00,
0x00,
0x06, # p_flags (6: Read, Write)
0x00,
0x00,
0x00,
0xD4, # p_offset
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0xD4, # p_vaddr
0x00,
0x60,
0x00,
0x00,
0x00,
0x00,
0x00,
0xD4, # p_paddr
0x00,
0x60,
0x00,
0x00,
0x00,
0x00,
0x00,
0x0E, # p_filesz
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x0E, # p_memsz
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, # p_align
0x00,
0x20,
0x00,
0x00,
0x00,
0x00,
0x00,
# 176 bytes
#----------- PROGRAM ENTRY address 0x4000b0---------------------------
# Message length
0xBA, # mov edx
0x0E, # 0xe
0x00,
0x00,
0x00,
# Message to write
0xB9, # mov ecx
0xD4, # 0x6000d4
0x00,
0x60,
0x00,
# File descriptor (stdout)
0xBB, # mov ebx
0x01, # 0x1
0x00,
0x00,
0x00,
# System call number (sys_write)
0xB8, # mov eax
0x04, # 0x4
0x00,
0x00,
0x00,
# System call
0xCD, # int 0x80
0x80,
0xBB, # mov ebx
0x00, # 0x0
0x00,
0x00,
0x00,
# System call number (sys_exit)
0xB8, # mov eax
0x01, # 0x1
0x00,
0x00,
0x00,
# System call
0xCD, # int 0x80
0x80,
0x00,
0x00,
0x48, # ASCII - H
0x65, # ASCII - e
0x6C, # ASCII - l
0x6C, # ASCII - l
0x6F, # ASCII - o
0x2C, # ASCII - ,
0x20, # ASCII - espace
0x77, # ASCII - w
0x6F, # ASCII - o
0x72, # ASCII - r
0x6C, # ASCII - l
0x64, # ASCII - d
0x21, # ASCII - !
0x0A, # ASCII - LF (new line)
0x00, # ASCII - NUL (null)
0x2E,
0x73, # ASCII - S
0x68, # ASCII - h
0x73, # ASCII - s
0x74, # ASCII - t
0x72, # ASCII - r
0x74, # ASCII - t
0x61, # ASCII - a
0x62, # ASCII - b
0x00, # ASCII - NUL (null)
0x2E,
0x74, # ASCII - t
0x65, # ASCII - e
0x78, # ASCII - x
0x74, # ASCII - t
0x00, # ASCII - NUL (null)
0x2E,
0x64, # ASCII - d
0x61, # ASCII - a
0x74, # ASCII - t
0x61, # ASCII - a
0x00, # ASCII - NUL (null)
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
# 256 bytes (offset 0x100)
# ----------- program Section table's ----------
# The first entry in the section header table (with an index of 0) is reserved, and
# must contain all zeroes.
0x00, # sh_name - contains the offset, in bytes, to the section name, relative to the start of the section name string table.
0x00,
0x00,
0x00,
0x00, # sh_type identifies the section type.
0x00,
0x00,
0x00,
0x00, # sh_flags - identifies the attributes of the section.
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, # sh_addr - contains the virtual address of the beginning of the section in memory.
0x00, # If the section is not allocated to the memory image of the program, this field should be zero.
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, # sh_offset contains the offset, in bytes, of the beginning of the section contents in the file.
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, # sh_size contains the size, in bytes, of the section. Except for SHT_NOBITS
0x00, # sections, this is the amount of space occupied in the file.
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, # sh_link contains the section index of an associated section. This field is
0x00, # used for several purposes, depending on the type of section
0x00,
0x00,
0x00, # sh_info contains extra information about the section. This field is used for
0x00, # several purposes, depending on the type of section
0x00,
0x00,
0x00, # sh_addralign contains the required alignment of the section.
0x00, # This field must be a power of two.
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, # sh_entsize contains the size, in bytes, of each entry, for sections that
0x00, # contain fixed-size entries. Otherwise, this field contains zero.
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
# ----- SECTION 2 ----
0x0B, # sh_name - contains the offset, in bytes, to the section name,
0x00, # (.text)
0x00,
0x00,
0x01, # sh_type identifies the section type.
0x00, # 1 : SHT_PROGBITS (Contains information defined by the program)
0x00,
0x00,
0x06, # sh_flags - identifies the attributes of the section.
0x00, # (6: SHF_ALLOC + SHF_EXECINSTR : Section is allocated in memory image of
0x00, # program and contains executable instructions )
0x00,
0x00,
0x00,
0x00,
0x00,
0xB0, # sh_addr - contains the virtual address of the beginning of the section in memory.
0x00, # (adresse 0x400B0) // Program entry
0x40,
0x00,
0x00,
0x00,
0x00,
0x00,
0xB0, # sh_offset contains the offset, in bytes, of the beginning of the section contents in the file.
0x00, # octet 176
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x22, # sh_size contains the size, in bytes, of the section.
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, # sh_link contains the section index of an associated section.
0x00,
0x00,
0x00,
0x00, # sh_info contains extra information about the section.
0x00,
0x00,
0x00,
0x04, # sh_addralign contains the required alignment of the section.
0x00, # This field must be a power of two.
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, # sh_entsize contains the size, in bytes, of each entry, for sections that
0x00, # contain fixed-size entries. Otherwise, this field contains zero.
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
# ----- SECTION 3 ----
0x11, # sh_name - contains the offset, in bytes, to the section name,
0x00, # (.data)
0x00,
0x00,
0x01, # sh_type identifies the section type.
0x00, # 1 : SHT_PROGBITS (Contains information defined by the program)
0x00,
0x00,
0x03, # sh_flags - identifies the attributes of the section.
0x00, # (3: SHF_WRITE + SHF_ALLOC : Section is allocated in memory image of
0x00, # program and contains contains writable data)
0x00,
0x00,
0x00,
0x00,
0x00,
0xD4, # sh_addr - contains the virtual address of the beginning of the section in memory.
0x00,
0x60,
0x00,
0x00,
0x00,
0x00,
0x00,
0xD4, # sh_offset contains the offset, in bytes, of the beginning of the section contents in the file.
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x0E, # sh_size contains the size, in bytes, of the section.
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, # sh_link contains the section index of an associated section.
0x00,
0x00,
0x00,
0x00, # sh_info contains extra information about the section.
0x00,
0x00,
0x00,
0x04, # sh_addralign contains the required alignment of the section.
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, # sh_entsize
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
# ----- SECTION 4 ----
0x01, # sh_name - contains the offset, in bytes, to the section name,
0x00, # (.shstrtab)
0x00,
0x00,
0x03, # sh_type identifies the section type.
0x00, # 3 : SHT_STRTAB (Contains a string table)
0x00,
0x00,
0x00, # sh_flags - identifies the attributes of the section.
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, # sh_addr - contains the virtual address of the beginning of the section in memory.
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0xE2, # sh_offset contains the offset, in bytes, of the beginning of the section contents in the file.
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x17, # sh_size contains the size, in bytes, of the section.
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, # sh_link contains the section index of an associated section.
0x00,
0x00,
0x00,
0x00, # sh_info contains extra information about the section.
0x00,
0x00,
0x00,
0x01, # sh_addralign contains the required alignment of the section.
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00, # sh_entsize
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00
]
f = file('hello', 'wb')
for octet in data:
f.write('%c' % octet)
f.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment