Last active
March 19, 2022 19:02
-
-
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 file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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