Object Reproducing Programs
 

Author: Yuval Yarom (yval@memco.co.il)
Notes: The attached quine program is a self reproducing Sparc
executable.  I have tested it under Solaris 2.4 and Solaris 2.6.  I do
not know if it works on anything else.  The output is the contents of
the executable file.  The program simply dumps its memory image to the standard output.  To
create it, I compiled the following foo.c to assembler, tweaked with the
assembly code a bit (inlining calls to syscall, deleting unneeded stuff,
etc.), compiled the assembly code, and loaded it (use 'ld foo.o -dn -a
-e main').  After running ld, a.out contans too much data.  The first
run of such a.out produces quine.
Ed. note:  I would classify this as a cheat, but it's a unique idea.
 

#include <sys/syscall.h>
int end();
main() {
        char *a = (char *)(((long)main) & ~0xfff);

        while (a < (char *)end)
                syscall(SYS_write,1, a++, 1);
        syscall(SYS_exit, 0);
}

end(){}

The executable

Another smaller executable
 

Language: Assembler (in fact, machine code)
Author:   Bertram Felgenhauer
Note:     These programs print their own binary to stdout, reconstructed
          from memory. MS DOS specific.
===START===
.model tiny
.code
.startup
s:      mov     ah,40h
        inc     bx
        mov     cl,offset x-offset s
        mov     dx,si
        int     21h
        ret
x:
end
====END====
begin 644 SELF.COM
*M$!#L0J+ULTAPP
 
end

Description: COM files are just too simple - memory images of themselves.
  So we just write it to standard output. Assumes bx=0, ch=0, si=0100
  on startup (true for MS DOS)

===START===
; self-rep EXE file, boot strap.
; exe -> 75 bytes.
.model small
.code
&       equ     offset
; our own EXE header, quite minimalistic
        db      "MZ"    ; 00 signature
        dw      & e+32  ; 02 last 512-page
        dw      1       ; 04 number of 512-pages
        dw      0       ; 06 number of relocation entries
        dw      2       ; 08 header size in paragraphs
        dw      32      ; 0A min number of paragraphs in memory
        dw      32      ; 0C max
        dw      4       ; 0E initial SS
        dw      512     ; 10 initial SP
        dw      0       ; 12 checksum
        dw      offset start
                        ; 14 initial IP
        dw      0       ; 16 initial CS
                        ; 18 offset of relocation table
                        ; 1A overlay number
; our main program; part of it is used as the header, too
start:  push    cs
        pop     ds
        inc     bx
        mov     cl,20h
@l:     mov     ah,40h
        cwd
        int     21h     ; 1st: write header; 2nd: write code segment
        xor     cl,0Bh  ; (offset e) xor 32; must have odd parity
        jpe     @l
        mov     ah,4Ch
        int     21h     ; exit program
e:
.stack  256
end start
====END====
begin 644 SELF.EXE
M35I+  $    " "  (  $   "   8    #A]#L2"T0)E-6DL  0    ( (  @
>  0   (  !@    .'T.Q(+1 F<TA@/$+>O:T3,TA
 
end