Збірка для x86 Linux, 106 байт
BITS 32
org 0x2E620000
db 0x7F, "ELF", 1, 1, 1, 0 ; e_ident
dd 0, 0
dw 2 ; e_type
dw 3 ; e_machine
dd 1 ; e_version
dd _start ; e_entry
dd phdr - $$ ; e_phoff
dd 0 ; e_shoff
dd 0 ; e_flags
dw 0x34 ; e_ehsize
dw 0x20 ; e_phentsize
phdr: dd 1 ; e_phnum ; p_type
; e_shentsize
dd 0 ; e_shnum ; p_offset
; e_shstrndx
dd $$ ; p_vaddr
fname equ $ - 2
db 'out', 0 ; p_paddr
dd filesize ; p_filesz
dd filesize ; p_memsz
dd 5 ; p_flags
dd 0x1000 ; p_align
_start: mov al, 5 ; 5 = open syscall
mov ebx, fname
mov cl, 65 ; 65 = O_WRONLY | O_CREAT
mov dx, 666q
int 0x80
lea edx, [byte ecx + filesize - 65]
xchg eax, ebx
xchg eax, ecx
mov cl, 0
mov al, 4 ; 4 = write syscall
int 0x80
mov al, 1 ; 1 = exit syscall
int 0x80
filesize equ $ - $$
Це для ассемблера nasm. Побудуйте двійковий файл за допомогою командного рядка:nasm -f bin -o a.out selfrep.asm && chmod +x a.out
Ось такий самий файл, як і шістнадцятковий дамп: 7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 00 02 00 03 00 01 00 00 00 4C 00 62 2E 2C 00 00 00 00 00 00 00 00 00 00 00 34 00 20 00 01 00 00 00 00 00 00 00 00 00 62 2E 6F 75 74 00 6A 00 00 00 6A 00 00 00 05 00 00 00 00 10 00 00 B0 05 BB 36 00 62 2E B1 41 66 BA B6 01 CD 80 8D 51 29 93 91 B1 00 B0 04 CD 80 B0 01 CD 80
За потребою програма копіює себе в окремий файл. (Програма могла бути значно коротшою, якби їй було дозволено просто записати в stdout і дозволити користувачеві перенаправляти файл.)
Я уникав використовувати будь-які прикордонні трюки для зменшення розміру. Це має бути повністю сумісний 32-розрядний бінарний ELF.
Відредаговано, щоб додати : У наведеній версії створений файл - це просто звичайний файл, але мені здається, що за пару байтів (і крихітний вигин правил) ви можете створити щось трохи цікавіше. Ця версія на два байти більше, на 108 байт:
BITS 32
org 0x00010000
db 0x7F, "ELF", 1, 1, 1, 0 ; e_ident
dd 0, 0
dw 2 ; e_type
dw 3 ; e_machine
dd 1 ; e_version
dd _start ; e_entry
dd phdr - $$ ; e_phoff
dd 0 ; e_shoff
dd 0 ; e_flags
dw 0x34 ; e_ehsize
dw 0x20 ; e_phentsize
phdr: dd 1 ; e_phnum ; p_type
; e_shentsize
dd 0 ; e_shnum ; p_offset
; e_shstrndx
dd $$ ; p_vaddr
fname: db 'asr', 0 ; p_paddr
dd filesize ; p_filesz
dd filesize ; p_memsz
dd 7 ; p_flags
dd 0x1000 ; p_align
_start: mov al, 5 ; 5 = open syscall
mov ebx, fname
inc byte [ebx]
mov cl, 65 ; 65 = O_WRONLY | O_CREAT
mov dx, 777q
int 0x80
lea edx, [byte ecx + filesize - 65]
xchg eax, ebx
xchg eax, ecx
mov cl, 0
mov al, 4 ; 4 = write syscall
int 0x80
mov al, 1 ; 1 = exit syscall
int 0x80
filesize equ $ - $$
Назвіть цю версію asrдля "самовідтворювача":nasm -f bin -o asr asr.asm && chmod +x asr
Шістнадцятковий дамп-версія для людей з обмеженими можливостями:
7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 00 02 00 03 00 01 00 00 00 4C 00 01 00 2C 00 00 00 00 00 00 00 00 00 00 00 34 00 20 00 01 00 00 00 00 00 00 00 00 00 01 00 61 73 72 00 6C 00 00 00 6C 00 00 00 07 00 00 00 00 10 00 00 B0 05 BB 38 00 01 00 FE 03 B1 41 66 BA FF 01 CD 80 8D 51 2B 93 91 B1 00 B0 04 CD 80 B0 01 CD 80
Коли ви запускаєте його, він створює майже ідентичний файл з ім'ям bsr, але той, який сам виконується. Запустивши його, створимо ще один двійковий файл з назвою csr. І так далі.
(Зауважте, що набридливі речі починають відбуватися після zsr. Я розглядав можливість створення версії, яка б каскадувала зміну імені atrтощо), але, думаю, більшість людей заздалегідь набридне, тому, мабуть, не варто зайвих байтів. )