Hello World Π½Π° машинном ΠΊΠΎΠ΄Π΅: ΠΎΡ‚ Π±Π°ΠΉΡ‚ΠΎΠ² ΠΊ исполняСмому Ρ„Π°ΠΉΠ»Ρƒ

ΠŸΠΎΠ³Ρ€ΡƒΠΆΠ΅Π½ΠΈΠ΅ Π² Π³Π»ΡƒΠ±ΠΈΠ½Ρ‹ программирования начинаСтся Π½Π΅ с высокоуровнСвых языков Π²Ρ€ΠΎΠ΄Π΅ Python ΠΈΠ»ΠΈ Java, Π° с чистого машинного ΠΊΠΎΠ΄Π°. Когда Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΏΠΈΡˆΠ΅Ρ‚ Hello World Π½Π° машинном ΠΊΠΎΠ΄Π΅, ΠΎΠ½ фактичСски общаСтся Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ с процСссором, минуя компиляторы ΠΈ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€Ρ‹. Π­Ρ‚ΠΎ ΡƒΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ дСмонстрируСт, ΠΊΠ°ΠΊ абстрактныС ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ ΠΏΡ€Π΅Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ΡΡ Π² элСктричСскиС сигналы, ΡƒΠΏΡ€Π°Π²Π»ΡΡŽΡ‰ΠΈΠ΅ Π²Ρ‹Ρ‡ΠΈΡΠ»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ машиной.

ΠœΠ°ΡˆΠΈΠ½Π½Ρ‹ΠΉ язык прСдставляСт собой ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ Π±Π°ΠΉΡ‚ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΡŒΠ½Ρ‹ΠΉ процСссор воспринимаСт ΠΊΠ°ΠΊ инструкции для выполнСния. Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ ассСмблСра, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ всС Π΅Ρ‰Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ мнСмоничСскиС обозначСния (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, MOV ΠΈΠ»ΠΈ INT), ΠΌΠ°ΡˆΠΈΠ½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ β€” это"сырыС" ΡˆΠ΅ΡΡ‚Π½Π°Π΄Ρ†Π°Ρ‚Π΅Ρ€ΠΈΡ‡Π½Ρ‹Π΅ значСния. Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π²Ρ‹Π²ΠΎΠ΄Π° тСкста Π½Π° этом ΡƒΡ€ΠΎΠ²Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Ρ‚ΠΎΡ‡Π½ΠΎΠ³ΠΎ понимания Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρ‹ процСссора ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмы.

Π’ Π΄Π°Π½Π½ΠΎΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌ процСсс создания ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠ΅ΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ для Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρ‹ x86-64 Π² ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмС Linux. Π’Ρ‹ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ скрываСтся Π·Π° ΠΏΡ€ΠΈΠ²Ρ‹Ρ‡Π½ΠΎΠΉ Ρ„Ρ€Π°Π·ΠΎΠΉ, ΠΈ ΠΏΠΎΠΉΠΌΠ΅Ρ‚Π΅, ΠΏΠΎΡ‡Π΅ΠΌΡƒ соврСмСнныС компиляторы Ρ‚Π°ΠΊ Π²Π°ΠΆΠ½Ρ‹, нСсмотря Π½Π° Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΊΠΎΠ΄ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ.

АрхитСктура x86 ΠΈ Π½Π°Π±ΠΎΡ€ инструкций

ΠŸΡ€ΠΎΡ†Π΅ΡΡΠΎΡ€Ρ‹ сСмСйства x86, Π΄ΠΎΠΌΠΈΠ½ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ Π² ΠΏΠ΅Ρ€ΡΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π°Ρ…, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ слоТный Π½Π°Π±ΠΎΡ€ инструкций CISC (Complex Instruction Set Computer). Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΎΠ΄Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π° ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΡΠ»ΠΎΠΆΠ½ΡƒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ, Π½ΠΎ Π΄Π»ΠΈΠ½Π° Ρ‚Π°ΠΊΠΈΡ… ΠΊΠΎΠΌΠ°Π½Π΄ Π²Π°Ρ€ΡŒΠΈΡ€ΡƒΠ΅Ρ‚ΡΡ. Для написания Hello World Π½Π°ΠΌ потрСбуСтся ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ спСцифичСскиС ΠΊΠΎΠ΄Ρ‹ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ, ΠΈΠ»ΠΈ opcodes, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ процСссор распознаСт ΠΊΠ°ΠΊ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ пСрСсылки Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ»ΠΈ прСрывания.

КаТдая инструкция Π² машинном ΠΊΠΎΠ΄Π΅ кодируСтся ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒΡŽ Π±Π°ΠΉΡ‚ΠΎΠ². НапримСр, ΠΊΠΎΠΌΠ°Π½Π΄Π° пСрСмСщСния Π΄Π°Π½Π½Ρ‹Ρ… ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°Π½ΠΈΠΌΠ°Ρ‚ΡŒ ΠΎΡ‚ Π΄Π²ΡƒΡ… Π΄ΠΎ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Π±Π°ΠΉΡ‚ Π² зависимости ΠΎΡ‚ ΠΎΠΏΠ΅Ρ€Π°Π½Π΄ΠΎΠ². Π’Π°ΠΆΠ½ΠΎ ΠΏΠΎΠ½ΠΈΠΌΠ°Ρ‚ΡŒ Ρ€Π°Π·Π½ΠΈΡ†Ρƒ ΠΌΠ΅ΠΆΠ΄Ρƒ 32-Π±ΠΈΡ‚Π½ΠΎΠΉ ΠΈ 64-Π±ΠΈΡ‚Π½ΠΎΠΉ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°ΠΌΠΈ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ систСмныС Π²Ρ‹Π·ΠΎΠ²Ρ‹ Π² Linux x86-64 ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ рСгистр RAX для Π½ΠΎΠΌΠ΅Ρ€Π° Π²Ρ‹Π·ΠΎΠ²Π°, Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ EAX Π² 32-Π±ΠΈΡ‚Π½ΠΎΠΉ вСрсии.

Π Π°Π±ΠΎΡ‚Π° с ΠΌΠ°ΡˆΠΈΠ½Π½Ρ‹ΠΌ ΠΊΠΎΠ΄ΠΎΠΌ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ внимания ΠΊ порядку Π±Π°ΠΉΡ‚ (Little Endian Π½Π° x86), Π³Π΄Π΅ младший Π±Π°ΠΉΡ‚ хранится ΠΏΠΎ ΠΌΠ΅Π½ΡŒΡˆΠ΅ΠΌΡƒ адрСсу. Ошибка Π² порядкС слСдования Π±Π°ΠΉΡ‚ΠΎΠ² ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ Ρ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ процСссор ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π΅Ρ‚ ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ Π½Π΅Π²Π΅Ρ€Π½ΠΎΠ΅ число ΠΈΠ»ΠΈ адрСс, Ρ‡Ρ‚ΠΎ Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ сбой ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹.

  • πŸ”Ή Opcode β€” числовой ΠΊΠΎΠ΄, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‰ΠΈΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, слоТСниС ΠΈΠ»ΠΈ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄).
  • πŸ”Ή Operand β€” Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ»ΠΈ адрСса, Π½Π°Π΄ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ выполняСтся опСрация.
  • πŸ”Ή Register β€” ячСйка памяти Π²Π½ΡƒΡ‚Ρ€ΠΈ процСссора для быстрых вычислСний.
πŸ“Š Π‘ ΠΊΠ°ΠΊΠΈΠΌ ΡƒΡ€ΠΎΠ²Π½Π΅ΠΌ программирования Π²Ρ‹ Π·Π½Π°ΠΊΠΎΠΌΡ‹?
АссСмблСр/ΠœΠ°ΡˆΠΈΠ½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄
C/C++
Python/Java
Волько Π²ΠΈΠ·ΡƒΠ°Π»ΡŒΠ½Ρ‹Π΅ языки

БистСмныС Π²Ρ‹Π·ΠΎΠ²Ρ‹ Π² Linux

ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Π°Ρ систСма Π½Π΅ позволяСт ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°ΠΌ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ ΠΎΠ±ΠΎΡ€ΡƒΠ΄ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ, Ρ‚Π°ΠΊΠΈΠΌ ΠΊΠ°ΠΊ экран ΠΈΠ»ΠΈ диск. Для Π²Ρ‹Π²ΠΎΠ΄Π° тСкста Π½Π° экран ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π΄ΠΎΠ»ΠΆΠ½Π° ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚ΡŒΡΡ ΠΊ ядру ОБ Ρ‡Π΅Ρ€Π΅Π· ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ систСмных Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² (system calls). Π’ Linux для Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρ‹ x86-64 основным ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠΎΠΌ Π²Ρ…ΠΎΠ΄Π° Π² ядро являСтся инструкция syscall.

Π§Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ ΡΠΈΡΡ‚Π΅ΠΌΠ½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ Π½ΠΎΠΌΠ΅Ρ€ Π²Ρ‹Π·ΠΎΠ²Π° Π² рСгистр RAX, Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ β€” Π² рСгистры RDI, RSI, RDX ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅. Для нашСй Π·Π°Π΄Π°Ρ‡ΠΈ Π²Ρ‹Π²ΠΎΠ΄Π° тСкста Π½Π°ΠΌ понадобится Π²Ρ‹Π·ΠΎΠ² sys_write, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ отправляСт Π΄Π°Π½Π½Ρ‹Π΅ Π² Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΉ дСскриптор. Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½Ρ‹ΠΉ Π²Ρ‹Π²ΠΎΠ΄ (экран) ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΈΠΌΠ΅Π΅Ρ‚ дСскриптор 1.

⚠️ Π’Π½ΠΈΠΌΠ°Π½ΠΈΠ΅: НомСра систСмных Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² ΠΎΡ‚Π»ΠΈΡ‡Π°ΡŽΡ‚ΡΡ Π² Ρ€Π°Π·Π½Ρ‹Ρ… ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Ρ… систСмах ΠΈ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ…. Код, Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΠΉ Π½Π° Linux x86-64, Π½Π΅ запустится Π½Π° Windows ΠΈΠ»ΠΈ ARM Π±Π΅Π· ΠΏΠΎΠ»Π½ΠΎΠΉ ΠΏΠ΅Ρ€Π΅Π΄Π΅Π»ΠΊΠΈ.

ПослС выполнСния всСх Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Ρ… дСйствий ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π΄ΠΎΠ»ΠΆΠ½Π° ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ свою Ρ€Π°Π±ΠΎΡ‚Ρƒ. Для этого ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ систСмный Π²Ρ‹Π·ΠΎΠ² sys_exit, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ сообщаСт ядру ΠΎΠ± ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ процСсса ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΊΠΎΠ΄ Π²Ρ‹Ρ…ΠΎΠ΄Π°. Если Π·Π°Π±Ρ‹Ρ‚ΡŒ этот шаг, процСсс ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡΡ‚Π°Ρ‚ΡŒΡΡ Π²ΠΈΡΠ΅Ρ‚ΡŒ Π² систСмС Π² Π·ΠΎΠΌΠ±ΠΈ-состоянии.

БистСмный Π²Ρ‹Π·ΠΎΠ² НомСр (x86-64) РСгистр Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° 1 РСгистр Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° 2
sys_write 1 RDI (fd) RSI (buf)
sys_exit 60 RDI (status) -
sys_read 0 RDI (fd) RSI (buf)
sys_open 2 RDI (filename) RSI (flags)

Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° ELF-Ρ„Π°ΠΉΠ»Π°

ΠŸΡ€ΠΎΡΡ‚ΠΎ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π±Π°ΠΉΡ‚ΠΎΠ² нСдостаточно для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ опСрационная систСма запустила ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ. Π€Π°ΠΉΠ» Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρƒ исполняСмых Ρ„Π°ΠΉΠ»ΠΎΠ². Π’ Linux стандартом являСтся ELF (Executable and Linkable Format). Π­Ρ‚ΠΎΡ‚ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ содСрТит Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ, ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰ΠΈΠ΅, ΠΊΠ°ΠΊ Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ ΠΊΠΎΠ΄ Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ, Π³Π΄Π΅ находится Ρ‚ΠΎΡ‡ΠΊΠ° Π²Ρ…ΠΎΠ΄Π° ΠΈ ΠΊΠ°ΠΊΠΈΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Π½ΡƒΠΆΠ½Ρ‹.

НаиболСС минималистичный ELF-Ρ„Π°ΠΉΠ» для x86-64 состоит ΠΈΠ· Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° ELF, Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ (Program Header) ΠΈ самого ΠΊΠΎΠ΄Π°. Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ELF начинаСтся с магичСского числа 7F 45 4C 46 (Π² ASCII это .ELF), Π·Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ слСдуСт информация ΠΎ разрядности (1 Π±Π°ΠΉΡ‚) ΠΈ порядкС Π±Π°ΠΉΡ‚ (1 Π±Π°ΠΉΡ‚). Π‘Π΅Π· ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠ³ΠΎ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° ядро Linux откаТСтся Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ Ρ„Π°ΠΉΠ» с ошибкой"Exec format error".

Π’ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ указываСтся смСщСниС (offset) Π΄ΠΎ Π½Π°Ρ‡Π°Π»Π° ΠΊΠΎΠ΄Π° ΠΈ Π΅Π³ΠΎ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΉ адрСс. Π’Π°ΠΊΠΆΠ΅ критичСски Π²Π°ΠΆΠ΅Π½ Ρ‚ΠΈΠΏ Ρ„Π°ΠΉΠ»Π°: для исполняСмого Ρ„Π°ΠΉΠ»Π° это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ET_EXEC ΠΈΠ»ΠΈ ET_DYN. Ошибка Π² расчСтах смСщСний ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ Ρ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ процСссор Π½Π°Ρ‡Π½Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»Π½ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ ΠΊΠ°ΠΊ ΠΊΠΎΠ΄, Ρ‡Ρ‚ΠΎ Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎΠ΅ ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅.

ΠŸΠΎΡ‡Π΅ΠΌΡƒ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ Ρ‚Π°ΠΊ Π²Π°ΠΆΠ½Ρ‹?

Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ ELF Π·Π°Π³Ρ€ΡƒΠ·Ρ‡ΠΈΠΊΡƒ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмы, ΠΊΡƒΠ΄Π° ΠΏΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ ΠΊΠΎΠ΄ Π² памяти. Если ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Π½Π΅Π²Π΅Ρ€Π½Ρ‹ΠΉ адрСс, процСссор попытаСтся Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΈΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡŽ ΠΏΠΎ адрСсу, Π³Π΄Π΅ находятся Π΄Π°Π½Π½Ρ‹Π΅, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡŽ Illegal Instruction.

Пошаговая сборка Hello World

Для создания ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡˆΠ΅ΡΡ‚Π½Π°Π΄Ρ†Π°Ρ‚Π΅Ρ€ΠΈΡ‡Π½Ρ‹ΠΉ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€ ΠΈΠ»ΠΈ ассСмблСр для Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ Π±Π°ΠΉΡ‚ΠΎΠ², Π° Π·Π°Ρ‚Π΅ΠΌ собСрСм ΠΈΡ… Π² Π±ΠΈΠ½Π°Ρ€Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ». Рассмотрим Π»ΠΎΠ³ΠΈΠΊΡƒ формирования ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ. Π‘Π½Π°Ρ‡Π°Π»Π° ΠΈΠ΄Π΅Ρ‚ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ELF, Π·Π°Ρ‚Π΅ΠΌ ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ строку"Hello World\n" Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ sys_write.

Π‘Ρ‚Ρ€ΠΎΠΊΠ° тСкста Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½Π° Π² сСкции Π΄Π°Π½Π½Ρ‹Ρ…. Π’ машинном ΠΊΠΎΠ΄Π΅ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄Ρ‹ ΠΈΠ»ΠΈ ТСстко Π·Π°Π΄Π°Π½Π½Ρ‹Π΅ адрСса, Ссли Π·Π½Π°Π΅ΠΌ, Π³Π΄Π΅ окаТСтся ΠΊΠΎΠ΄. Для упрощСния Π² Ρ€ΡƒΡ‡Π½ΠΎΠΌ ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ часто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ статичСскиС адрСса ΠΈΠ»ΠΈ Π²Ρ‹Ρ‡ΠΈΡΠ»ΡΡŽΡ‚ смСщСния ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ инструкции (RIP-relative addressing).

; ПсСвдокод Π»ΠΎΠ³ΠΈΠΊΠΈ Π½Π° ассСмблСрС (для понимания)

mov rax, 1; sys_write

mov rdi, 1; stdout

mov rsi, msg; адрСс строки

mov rdx, 12; Π΄Π»ΠΈΠ½Π° строки

syscall

mov rax, 60; sys_exit

xor rdi, rdi; статус 0

syscall

msg: db"Hello World", 10

ПослС формирования ΠΏΠΎΠ»Π½ΠΎΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π±Π°ΠΉΡ‚ΠΎΠ², Π²ΠΊΠ»ΡŽΡ‡Π°Ρ всС Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ, Π΄Π°Π½Π½Ρ‹Π΅ ΡΠΎΡ…Ρ€Π°Π½ΡΡŽΡ‚ΡΡ Π² Ρ„Π°ΠΉΠ» Π±Π΅Π· Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ ΠΈΠ»ΠΈ с Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ΠΌ .bin. Π—Π°Ρ‚Π΅ΠΌ Ρ„Π°ΠΉΠ»Ρƒ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π°Ρ‚ΡŒ ΠΏΡ€Π°Π²Π° Π½Π° исполнСниС ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ chmod +x. Волько послС этого ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ Ρ„Π°ΠΉΠ» Π² Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π΅.

β˜‘οΈ ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΏΠ΅Ρ€Π΅Π΄ запуском

Π’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ: 0 / 4

Анализ Π±Π°ΠΉΡ‚ΠΎΠ² ΠΈ ΠΎΡ‚Π»Π°Π΄ΠΊΠ°

Как Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ„Π°ΠΉΠ» создан, наступаСт этап Π²Π΅Ρ€ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ. Π˜Π½ΡΡ‚Ρ€ΡƒΠΌΠ΅Π½Ρ‚ hexdump ΠΈΠ»ΠΈ xxd позволяСт ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ сыроС содСрТимоС Ρ„Π°ΠΉΠ»Π°. Π’Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ магичСскиС числа ELF Π² Π½Π°Ρ‡Π°Π»Π΅ ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄ процСссора Π΄Π°Π»Π΅Π΅. Π›ΡŽΠ±ΠΎΠ΅ ΠΎΡ‚ΠΊΠ»ΠΎΠ½Π΅Π½ΠΈΠ΅ ΠΎΡ‚ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΠΎΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ ΠΎΡˆΠΈΠ±ΠΊΡƒ Π² ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ.

Для Π°Π½Π°Π»ΠΈΠ·Π° исполнСния ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΎΡ‚Π»Π°Π΄Ρ‡ΠΈΠΊ GDB. Запустив ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ ΠΏΠΎΠ΄ ΠΎΡ‚Π»Π°Π΄Ρ‡ΠΈΠΊΠΎΠΌ, ΠΌΠΎΠΆΠ½ΠΎ пошагово ΠΏΡ€ΠΎΡ…ΠΎΠ΄ΠΈΡ‚ΡŒ инструкции ΠΈ Π½Π°Π±Π»ΡŽΠ΄Π°Ρ‚ΡŒ Π·Π° ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ содСрТимого рСгистров. Π­Ρ‚ΠΎ СдинствСнный способ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΏΠΎΡ‡Π΅ΠΌΡƒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΡƒΠΏΠ°Π»Π°, Ссли ΠΎΠ½Π° Π½Π΅ Π²Ρ‹Π²Π΅Π»Π° тСкст. Команда info registers ΠΏΠΎΠΊΠ°ΠΆΠ΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ состояниС процСссора.

⚠️ Π’Π½ΠΈΠΌΠ°Π½ΠΈΠ΅: ΠŸΡ€ΠΈ ΠΎΡ‚Π»Π°Π΄ΠΊΠ΅ машинного ΠΊΠΎΠ΄Π° Π±ΡƒΠ΄ΡŒΡ‚Π΅ остороТны с адрСсациСй. ΠŸΠΎΠΏΡ‹Ρ‚ΠΊΠ° Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎ адрСсу 0 ΠΈΠ»ΠΈ Π² Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Π½ΡƒΡŽ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ памяти Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ сигнал SIGSEGV (Segmentation Fault).

Если ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° запускаСтся, Π½ΠΎ Π½Π΅ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ тСкст, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Π΄Π»ΠΈΠ½Ρƒ строки Π² рСгистрС RDX. Если Π΄Π»ΠΈΠ½Π° ΡƒΠΊΠ°Π·Π°Π½Π° мСньшС Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΉ, Π²Ρ‹ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚Π΅ ΠΎΠ±Ρ€Π΅Π·Π°Π½Π½ΠΎΠ΅ сообщСниС. Если большС β€” Π½Π° экранС появится мусор ΠΈΠ· сосСдних ячССк памяти. Π’ΠΎΡ‡Π½ΠΎΡΡ‚ΡŒ Π² Π±Π°ΠΉΡ‚Π°Ρ… здСсь Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½Π°.

Π‘Ρ€Π°Π²Π½Π΅Π½ΠΈΠ΅ с высокоуровнСвыми языками

Π‘Ρ€Π°Π²Π½ΠΈΠΌ наш Ρ€ΡƒΡ‡Π½ΠΎΠΉ Ρ‚Ρ€ΡƒΠ΄ с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ компилятор GCC для ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π½Π° C. ΠšΠΎΠΌΠΏΠΈΠ»ΡΡ‚ΠΎΡ€ добавляСт мноТСство Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… инструкций для ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ срСды выполнСния (runtime), ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки ΠΈ динамичСской Π»ΠΈΠ½ΠΊΠΎΠ²ΠΊΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ. Π Π°Π·ΠΌΠ΅Ρ€ исполняСмого Ρ„Π°ΠΉΠ»Π° Π½Π° C Π±ΡƒΠ΄Π΅Ρ‚ Π² дСсятки Ρ€Π°Π· большС нашСго минималистичного Hello World.

ВысокоуровнСвыС языки Π°Π±ΡΡ‚Ρ€Π°Π³ΠΈΡ€ΡƒΡŽΡ‚ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° ΠΎΡ‚ Π΄Π΅Ρ‚Π°Π»Π΅ΠΉ памяти ΠΈ рСгистров, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ²Ρ‹ΡˆΠ°Π΅Ρ‚ ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ, Π½ΠΎ сниТаСт ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒ. ПониманиС машинного ΠΊΠΎΠ΄Π° Π΄Π°Π΅Ρ‚ прСимущСство Π² ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΊΡ€ΠΈΡ‚ΠΈΡ‡Π½Ρ‹Ρ… участков ΠΈ написании Π΄Ρ€Π°ΠΉΠ²Π΅Ρ€ΠΎΠ² ΠΈΠ»ΠΈ эксплойтов бСзопасности, Π³Π΄Π΅ Π²Π°ΠΆΠ΅Π½ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Π±Π°ΠΉΡ‚.

Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° читаСмости ΠΊΠΎΠ΄Π° Π½Π° машинном ΡƒΡ€ΠΎΠ²Π½Π΅ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π° для Π±ΠΎΠ»ΡŒΡˆΠΈΡ… ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΠ². Π”Π°ΠΆΠ΅ нСбольшой измСнСния Π² ΠΊΠΎΠΌΠΏΠΎΠ½ΠΎΠ²ΠΊΠ΅ сСкций ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΎΠ²Π°Ρ‚ΡŒ пСрСсчСта всСх адрСсов ΠΈ смСщСний Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ, Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ Ρ‚Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Π½Π΅ΠΏΡ€Π°ΠΊΡ‚ΠΈΡ‡Π½Ρ‹ΠΌ для ΠΏΡ€ΠΈΠΊΠ»Π°Π΄Π½ΠΎΠ³ΠΎ программирования.

МоТно Π»ΠΈ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Hello World Π½Π° машинном ΠΊΠΎΠ΄Π΅ для Windows?

Π”Π°, Π½ΠΎ структура Ρ„Π°ΠΉΠ»Π° Π±ΡƒΠ΄Π΅Ρ‚. ВмСсто ELF ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ PE (Portable Executable). Π’Π°ΠΊΠΆΠ΅ ΠΎΡ‚Π»ΠΈΡ‡Π°ΡŽΡ‚ΡΡ систСмныС Π²Ρ‹Π·ΠΎΠ²Ρ‹: Π² Windows ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ API Win32 ΠΈΠ»ΠΈ Π½Π°Ρ‚ΠΈΠ²Π½Ρ‹Π΅ Π²Ρ‹Π·ΠΎΠ²Ρ‹ ядра Ρ‡Π΅Ρ€Π΅Π· syscall с Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ Π½ΠΎΠΌΠ΅Ρ€Π°ΠΌΠΈ ΠΈ соглашСниями ΠΎ Π²Ρ‹Π·ΠΎΠ²Π°Ρ….

Бколько Π±Π°ΠΉΡ‚ Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ ELF-Ρ„Π°ΠΉΠ»?

ΠœΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΠΉ ELF-Ρ„Π°ΠΉΠ» для x86-64, выводящий тСкст ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ°ΡŽΡ‰ΠΈΠΉΡΡ, Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚ ΠΎΠΊΠΎΠ»ΠΎ 120-140 Π±Π°ΠΉΡ‚. Π­Ρ‚ΠΎ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ ΠΈ сам ΠΊΠΎΠ΄. Π€Π°ΠΉΠ»Ρ‹, созданныС стандартными компиляторами, ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ вСсят нСсколько ΠΊΠΈΠ»ΠΎΠ±Π°ΠΉΡ‚ ΠΈΠ·-Π·Π° Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π½Ρ‹Ρ… Ρ‚Π°Π±Π»ΠΈΡ† ΠΈ сСкций.

Π—Π°Ρ‡Π΅ΠΌ ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΌΠ°ΡˆΠΈΠ½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ Π² 2026 Π³ΠΎΠ΄Ρƒ?

ПониманиС машинного ΠΊΠΎΠ΄Π° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ дляreverse engineering, Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π΄Ρ€Π°ΠΉΠ²Π΅Ρ€ΠΎΠ², создания компиляторов, написания шСллкода для тСстирования бСзопасности ΠΈ Π³Π»ΡƒΠ±ΠΎΠΊΠΎΠΉ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ критичСских систСм.