Skip to content

A self replicating program outputs its own entire source code. This is the smallest self-replicating program possible in rust.

Notifications You must be signed in to change notification settings

Pingasmaster/smallest-self-replicating-programs-quines

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

The smallest self-replicating program I found in a bunch of languages.

Rust

fn main(){print!("{}",include_str!(file!()))}

What it does

file!(): This is a builtin macro that yields the path of the current source file as a string literal at compile time. include_str!(...): This macro takes a file path (known at compile time) and injects the file contents as a &'static str into the compiled binary. So include_str!(file!()) becomes a string containing the full source code of the program itself. I don't consider this cheating since no external file is involved and this is a rust-ism. print!("{}", ...): Finally it prints that string to stdout, emitting its own source code.

Putting it all together: The compiled program contains its own source code as a baked-in string and outputs it when run. In computer folklore, this creature is called a quine. The Rust ecosystem makes it surprisingly straightforward by giving it compile-time introspection tools.

Assembly:

Crash-after-write variant (15 bytes of .text):

bits 64
section .text
global _start

_start:
    push    1
    pop     rdi
    mov     eax, edi
    mov     esi, _start
    push    byte end - _start
    pop     rdx
    syscall

end:

Clean exit variant (21 bytes of .text):

bits 64
section .text
global _start

_start:
    push    1
    pop     rdi
    mov     eax, edi
    mov     esi, _start
    push    byte end - _start
    pop     rdx
    syscall

    xor     edi, edi
    mov     al, 60
    syscall

end:

What it does

rdx = end - _start computes the size (in bytes) of the whole program in memory, rsi = _start points to the beginning of its own code, and write(1, _start, end - _start) uses the write syscall to dump its own bytes to stdout. The top version omits exit(0) so it falls through into padding after the write and typically crashes (15 bytes of .text). The clean-exit variant adds 6 bytes for exit(0). Both versions use mov esi, _start (non-PIE absolute) and push byte end - _start (8-bit length), so they assume size < 128 bytes.

So when you assemble and run it:

nasm -felf64 q.asm -o q.o
ld q.o -o q
./q > dump
hexdump -C q
hexdump -C dump   # identical to above

dump will contain exactly the same bytes as the executable’s text segment.

Again, some say that considering the bytecode size of the program is cheating. I don't think so since I could have written the bytecode by hand anyways with enough determination from the assembly I wrote. If you think this is cheating, I challenge you to do better.

“Smallest”?

I can’t prove these are the absolute smallest possible 64-bit NASM or rust quine/self-replicator, but hit me up if you've found better with no data section (for asm) or no dependencies for rust.

About

A self replicating program outputs its own entire source code. This is the smallest self-replicating program possible in rust.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published