cómo arranca el sistema operativo ms

Anuncio
CÓMO ARRANCA EL SISTEMA
OPERATIVO
MS-DOS + WINDOWS’951
DESENSAMBLADO2 DE LOS SECTORES DE
PARTICIÓN Y DE ARRANQUE
Marzo 1997
Marco Antonio y Pedro Pablo Gómez Martín
[email protected]
1
Sistema mixto: instalado Windows’95 primera edición, con la opción de conservar el sistema operativo anterior, el
MS-DOS 6.22. Antes de empezar a arrancar, pulsando F4, arrancaba el MS-DOS, en vez de Windows 95.
2
Este desensamblado se hizo únicamente con fines didácticos, para entender el funcionamiento del arranque.
ARRANQUE DEL SISTEMA INTEL x86
Cuando el ordenador se enciende, los procesadores INTEL están preparados para que su
primera instrucción a ejecutar sea la situada en FFFF:0000. En esta posición, está colocada la
ROM-BIOS, de modo que lo primero que ejecuta la CPU al encenderse son las instrucciones de la
BIOS.
En ellas, hay rutinas de verificación de la integridad del sistema, comprobandose el buen
funcionamiento del procesador con algunas operaciones, la buena comunicación con la tarjeta
gráfica, de las disqueteras, etc. De estas comprobaciones, la más conocida es el chequeo de la
memoria.
Tras comprobar el buen funcionamiento del equipo, la BIOS establece sus variables
internas. Entre ellas están la cantidad de memoria del sistema punteros a estructuras de control
como el buffer del teclado, etc.
Además, busca las posibles ampliaciones BIOS que pudiera haber en la controladora de
disco, tarjeta gráfica, etc, y captura las interrupciones BIOS, que permiten al sistema un manejo de
las operaciones de E/S de forma independiente al hardware.
Una vez hecho todo esto, debe ceder el control al sistema operativo. Para evitar la
dependencia de la BIOS con un sistema operativo concreto, lo que hace es cargar un sector
determinado (el primero) de las unidades de almacenamiento, de modo que el sistema operativo
que pudiera haber sido instalado en ellas debe haberse encargado de ocupar ese sector que, una vez
cargado y ejecutado por la BIOS, dará las instrucciones necesarias al procesador para comenzar la
carga del S.O.
La BIOS, por lo tanto, tras terminar su inicialización, leerá el primer sector de la unidad A:.
Si no lo consigue, tratará de leer el primero de la unidad C:. Si tampoco lo consiguiera, avisaría al
usuario y 'ejecutaría' ROM-BASIC, o, en su defecto, detendría completamente el sistema . En
algunos casos, el orden de acceso a las unidades puede ser cambiado mediante el SETUP de la
BIOS.
En los disquettes, el primer sector es ya el sector de arranque del sistema operativo. Sin
embargo, en los discos duros no lo es. El primer sector tiene la llamada tabla de partición que
contiene las posibles (hasta 4) particiones del disco duro. En ella está indicado el 'dueño' de cada
partición, su comienzo, su final, y si es o no partición de arranque.
En ese mismo sector, hay, además de la tabla, un pequeño código que analiza la tabla y obra
en consecuencia, ejecutando el primer sector, ahora sí sector de arranque, de la partición que esté
especificada como activa en la tabla. Ese código es el que se ha analizado más abajo.
Para acabar, dos anotaciones. La BIOS, antes de dar el control al primer sector de la unidad
comprueba si es un sector ejecutable o no lo es, para evitar cuelgues del sistema al ejecutar sectores
no válidos. Si es o no ejecutable aparece indicado en los dos últimos bytes que deben ser 55h y
AAh para que la BIOS ejecute el sector.
Por último, he dicho que en la tabla de partición sólo entran cuatro posibles particiones. Sin
embargo el MS-DOS (o el Windows'95) admiten más de cuatro. Esto es debido a que crean una
partición de arranque (C:), y una partición extendida, que son las incluidas en la tabla de partición.
Pero la extendida tiene, a su vez, en su primer sector una nueva tabla de partición con una partición
primaria, que será ella misma, y otra extendida, indicando la siguiente. Aparece así una especie de
'lista enlazada', de modo que se permiten más de 20 particiones (hasta que se acaben las letras).
Nada más. Aquí va el código.
SECTOR DE PARTICION DEL DISCO DURO.
LA BIOS LO CARGA INICIALMENTE EN LA POSICION 0000:7C00
0DBD:7C00
0DBD:7C01
0DBD:7C03
0DBD:7C05
0DBD:7C08
0DBD:7C0A
0DBD:7C0B
0DBD:7C0C
0DBD:7C0D
0DBD:7C0E
0DBD:7C0F
0DBD:7C10
0DBD:7C13
0DBD:7C16
0DBD:7C17
0DBD:7C18
FA
33C0
8ED0
BC007C
8BF4
50
07
50
1F
FB
FC
BF0006
B90001
F2
A5
EA1D060000
CLI
XOR
MOV
MOV
MOV
PUSH
POP
PUSH
POP
STI
CLD
MOV
MOV
REPNZ
MOVSW
JMP
0DBD:7C1D
0DBD:7C20
0DBD:7C22
0DBD:7C25
0DBD:7C27
0DBD:7C2A
0DBD:7C2C
0DBD:7C2F
0DBD:7C31
0DBD:7C33
BEBE07
B304
803C80
740E
803C00
751C
83C610
FECB
75EF
CD18
MOV
MOV
CMP
JZ
CMP
JNZ
ADD
DEC
JNZ
INT
0DBD:7C35 8B14
0DBD:7C37 8B4C02
MOV
MOV
0DBD:7C3A
0DBD:7C3C
0DBD:7C3F
0DBD:7C41
0DBD:7C43
0DBD:7C46
0DBD:7C48
0DBD:7C4B
0DBD:7C4C
0DBD:7C4E
0DBD:7C50
0DBD:7C51
0DBD:7C54
0DBD:7C56
0DBD:7C58
0DBD:7C59
0DBD:7C5B
MOV
ADD
DEC
JZ
CMP
JZ
MOV
LODSB
CMP
JZ
PUSH
MOV
MOV
INT
POP
JMP
JMP
8BEE
83C610
FECB
741A
803C00
74F4
BE8B06
AC
3C00
740B
56
BB0700
B40E
CD10
5E
EBF0
EBFE
; Deteniene las interrupciones
; Coloca los registros de segmento
; en el segmento actual (0000h)
; coloca la pila dentro de ese
; segmento. Ajusta los valores de
; SI y DI para copiarse (pero no
; el sector entero, sino sólo el
; código) a la posición
; 0000:0600 para dejar el espacio
; libre para el sector de arranque
; de la partición del dusco duro
DI,0600
; que contiene el S.O.
CX,0100
; Copia 256 bytes, que es lo que
; ocupa el código ejecutable y las
; cadenas de texto de error.
0000:061D
; Salta a la siguiente instrucción
; de su nuevo emplazamiento.
SI,07BE
; Busca en la tabla de particiones
BL,04
; situada a partir de 0000:07BE
BYTE PTR [SI],80 ; la partición de arranque.
7C35
; Si la encuentra, continúa.
BYTE PTR [SI],00
7C48
SI,+10
BL
7C22
; Si no, salta a ejecutar una
18
; hipotética ROM-BASIC.
AX,AX
SS,AX
SP,7C00
SI,SP
AX
ES
AX
DS
; Aquí sigue tras encontrar la
; partición de arranque.
DX,[SI]
; Almacena el nº de la unidad, el
CX,[SI+02] ; cabezal, sector y cilindro donde
; comienza la partición (DX y CX).
BP,SI
; Busca otra posible partición de
SI,+10
; arranque, para encontrar un poBL
; sible error en la tabla de par7C5D
; tición.
BYTE PTR [SI],00
7C3C
SI,068B
; Aquí salta si hay algún error
; en la tabla de partición.
AL,00
; Muestra el mensaje:
7C5B
;
SI
;
'Invalid partition table'
BX,0007
;
AH,0E
; en la pantalla, (página 0,
10
; color 7),
SI
;
7C4B
;
7C5B
; y realiza un bucle sin fín.
; Aquí salta si no hay error en la tabla de
; información de comienzo de la partición.
0DBD:7C5D BF0500
MOV
DI,0005
0DBD:7C60 BB007C
MOV
BX,7C00
0DBD:7C63 B80102
MOV
AX,0201
0DBD:7C66 57
PUSH
DI
0DBD:7C67 CD13
INT
13
0DBD:7C69 5F
POP
DI
0DBD:7C6A 730C
JNB
7C78
0DBD:7C6C 33C0
XOR
AX,AX
0DBD:7C6E CD13
INT
13
0DBD:7C70 4F
DEC
DI
0DBD:7C71 75ED
JNZ
7C60
0DBD:7C73 BEA306
MOV
SI,06A3
0DBD:7C76 EBD3
JMP
7C4B
particiones. Tiene en DX y CX la
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
Carga el primer sector de la
partición de arranque, usando
los datos sacados de la tabla
de partición. Coloca en DI un
contador (inicialmente a 5) que
indica el número de intentos que
se van a realizar si hay error
en la lectura del nuevo sector
de arranque. Si al quinto intento no lo consigue, muestra:
'Error loading operating system'
y detiene el ordenador, usando
la misma rutina que en el caso
del error en la tabla de
partición
; Aquí salta si no hubo error al cargar el nuevo sector, que ahora se encuen; tra en la posición 0000:7C00, 'pisando' ya los datos de la tabla de parti; ciones.
0DBD:7C78 BEC206
MOV
SI,06C2
; Mira si el sector cargado es de
0DBD:7C7B BFFE7D
MOV
DI,7DFE
; arranque (últimos dos bytes con
0DBD:7C7E 813D55AA
CMP
WORD PTR [DI],AA55
; AA55h). Si lo es, lo
0DBD:7C82 75C7
JNZ
7C4B
; ejecuta, y si no lo es, muestra:
0DBD:7C84 8BF5
MOV
SI,BP
;
'Missing operating system'
0DBD:7C86 EA007C0000
JMP
0000:7C00
; y detiene el sistema, con la
; rutina de siempre.
;
;
;
;
;
Registros antes de saltar al sector de arranque:
AX = 0000
BX = 7C00
CX = <Cilindro-sector>
DX = <Unidad-Cabezal> CS = 0000
DS = 0000
ES = 0000
SS = 0000
SP = 7C00 (?)
BP = 06C2
SI = 06C2
DI = 7DFE
VOLCADO DE MEMORIA TRAS LA ULTIMA INSTRUCCION
0DBD:7C80
0DBD:7C90 69 64
0DBD:7CA0 6C 65
0DBD:7CB0 20 6F
0DBD:7CC0 6D 00
0DBD:7CD0 69 6E
0DBD:7CE0 6F 00
0DBD:7CF0 00 00
0DBD:7D00 00 00
Después son todo
20 70
00 45
70 65
4D 69
67 20
00 00
00 00
00 00
0's
61
72
72
73
73
00
00
00
72
72
61
73
79
00
00
00
74
6F
74
69
73
00
00
00
69-74
72-20
69-6E
6E-67
74-65
00-00
00-00
00-00
69
6C
67
20
6D
00
00
00
6F
6F
20
6F
00
00
00
00
49
6E
61
73
70
00
00
00
6E
20
64
79
65
80
00
00
76
74
69
73
72
58
00
00
61
61
6E
74
61
13
00
00
6C
62
67
65
74
19
00
00
Inval
id partition tab
le.Error loading
operating syste
m.Missing operat
ing system...X..
o...............
................
...........
80
00
00
00
55
01
00
00
00
AA
..
...??.?.........
...?........-...
................
..............U.
VOLCADO DE LA TABLA DE PARTICIONES,
GUARDADAS EN EL MISMO SECTOR
0DBD:7DB0
0DBD:7DC0
0DBD:7DD0
0DBD:7DE0
0DBD:7DF0
01
01
00
00
00
E5
00
00
06
05
00
00
3F
3F
00
00
3F
FF
00
00
E4
CD
00
00
3F
C0
00
00
00-00
16-0E
00-00
00-00
00
00
00
00
81
C0
00
00
16
D5
00
00
0E
2D
00
00
00
00
00
00
SECTOR DE ARRANQUE DE LA UNIDAD C:
MS-DOS + WINDOWS'95
Como este sector de arranque es un poquito más complicado que el código del sector de
partición, explicaré antes su funcionamiento.
La misión del sector es comprobar que existe una copia del sistema operativo en disco. Si
existe dicha copia, la ejecuta, y si no, muestra un mensaje de error al usuario pidiendo que se
cambie el disco y que se pulse una tecla. Hay que darse cuenta de que el sector de arranque de la
partición activa del disco duro es igual que el sector de arranque que pone el sistema operativo en el
primer sector de los disquettes al formatearlos, de ahí que deba comprobar si está o no el DOS
grabado en el disco.
Para detectar si está el disco tiene el sistema operativo, busca en el primer sector del
directorio raíz el archivo IO.SYS. Si lo está, lo carga en memoria (posición 0070:0000), y lo
ejecuta.
Hasta aquí, la teoría de la inicialización del MS-DOS. Pero el sector que vamos a analizar
nosotros es MS-DOS + WINDOWS'95. La principal diferencia es que primero busca el archivo
WINBOOT.SYS, si lo encuentra, lo carga y lo ejecuta. Si no lo encuentra, busca el archivo
IO.SYS. Si lo encuentra lo ejecuta, y si no, muestra ya el mensaje de error. Hay, sin embargo, unas
cuantas 'chapuzas' en medio (by Micro$oft). Tras encontrar cualquiera de los dos archivos, se
cargan solo los cuatro sectores del fichero, y sobre los datos cargados, se hacen dos
comprobaciones que ¡¡sólo las cumple el WINBOOT.SYS!! ¡¡Qué marginación!! ¡¡¿¿Qué pasa si
está el IO.SYS, y no el WINBOOT.SYS??!! ¡Lo carga, pero no lo ejecuta! J*der, que locura.
Bueno, olvidemos todo esto, y centremonos un poco más en el código. Porque la teoría de lo
que hace es bien sencilla, pero hacerlo... ¡no hay que olvidar que estamos ayudando al ordenador a
nacer!. Para acceder al disco solo disponemos de las funciones de lectura de la BIOS, a la que hay
que dar el nº de sector de la pista, el cilindro y la cabeza de lectura. Y nosotros, queremos ya
acceder al directorio raíz, cuya posición depende de la partición desde donde estemos arrancando,
del número de FAT que tenga dicha partición, del espacio que ocupe la FAT, y de un montón de
cosas más. ¿Cómo podemos encontrar por lo tanto el directorio raíz? Bueno, bueno, bueno. Antes,
expliquemos un poco cómo estructura el MS-DOS los discos, pues este sector de arranque es del
MS-DOS, y ya cuenta con que las estructuras del disco están creadas.
En primer lugar, está el sector lógico de la partición número 0, que es donde se sitúa el
sector de arranque que, desde un disquette, es cargado por la BIOS directamente, y que desde el
disco duro, es cargado por el BootTrap del sector de partición.
Después viene la FAT (File Alocation Table), que contiene información sobre las
posiciones donde están grabados cada archivo dentro del disco. Esta estructura es muy importante
dentro del disco, hasta el punto de que si se corrompiese, la información del disco se perdería. Por
tanto, el MS-DOS, para evitar esto, mantiene, tras la primera FAT, otra (u otras) copias de la FAT,
como 'copias de seguridad'.
Tras las posibles copias, se encuentra la información del directorio raíz, que contiene los
nombres de los archivos o directorios situados en el directorio raíz del disco, además de su
longitud, atributos, fecha, y el primer cluster que ocupa dentro del disco. El tamaño de todos estos
datos es variable, dependiendo del número de 'entradas' (de archivos) que se quieran tener, como
máximo, en el directorio raíz.
Por último, se sitúa la zona de datos, dividida en clusters, donde se graba finalmente el
contenido de cada archivo o subdirectorio.
Vemos por lo tanto que para saber el número del primer sector del directorio raíz hay que
saber el número de copias de la FAT y el número de sectores que ocupa cada una; y para saber
donde comienza la zona de datos hay que saber el número de entradas del directorio raíz.
Por si esto fuera poco, previendo que el espacio asignado al sector de arranque de la
partición se quede pequeño, existe la posibilidad de dejar varios sectores entre el sector de arranque
y el primer sector de la primera FAT para el programa de arranque.
Además, como hay que averiguar el número de sector del DISCO al que queremos acceder,
y no de la PARTICION, debemos saber el número de sectores desde el principio del disco hasta el
principio de la partición desde la que estamos arrancando.
Vemos pues que para acceder al directorio raíz y a la zona de datos, necesitamos conocer
bastantes cosas sobre el tamaño de las estructuras del disco. ¿Como las averiguamos?
Afortunadamente, el tamaño de estas estructuras queda fijado al formatear el disco, al igual que el
sector de arranque, por lo que dentro de este sector se graban, además del código, una serie de datos
muy útiles para poder acceder a las zonas del disco. Estan situadas al principio del sector, entre una
instrucción de salto al código que evita la 'ejecución' de los datos, y el propio código.
Entre estos datos, hay también información sobre la estructura física del disco, es decir el
número de pistas, el número de sectores por pista, etc. Esto es debido a que con los datos anteriores,
calculabamos el número de sector del disco al que queríamos acceder, pero para la BIOS esto no es
suficiente, pues debemos darle, como ya se ha dicho, el número de cilindro (pista), el número de
cabeza (cara) donde se debe leer, y el número de sector dentro de la pista al que queremos acceder,
para lo que necesitamos saber la estructura física del medio de almacenamiento.
Por último, antes de pasar a explicar las variables y el código, decir que tras la parte
ejecutable, vuelve a haber otra zona de datos conteniendo las cadenas de error que se muestran al
usuario, y las cadenas de los archivos que se buscan en el disco.
VARIABLES
(Sacadas de ‘MS-DOS Avanzado’ y ‘PC-INTERNO 2.0’)
Pos
Significado
En esta implementación
7C00 JMP SHORT Codigo
EB3Ch
7C02 NOP
90h
; En algunas implementaciones es un JMP largo, y no aparece el
; NOP, al necesitar la codificación de la instrucción 3 bytes.
7C03 Nombre del fabricante
MSWIN4.0
7C0B Bytes por sector
0200h
7C0D Sectores por cluster
10h
7C0E Sectores para el arranque, incluyendo
0001h
el ya cargado.
7C10 Número de FAT’s
02h
7C11 Número de entradas en el raíz.
0200h
7C13 Sectores totales en la partición.
0000h
(no usado, pocos bytes)
7C15 Byte de descripción del medio. (?)
F8h
7C16 Número de sectores por FAT
00E2h
7C18 Sectores por pista
003Fh
7C1A Número de cabezas
0040h
7C1C Nº de sectores desde el principio de
la unidad hasta el principio de la
partición.
7C20 Sectores totales en la partición. Usa
cuatro bytes, y si se completa
7C24 Número físico de la unidad.
7C26 ??????????????????????
7C27 Número de serie del volumen
7C2B Etiqueta del volúmen (no usada en esta
implementación).
7C36 Sistema de ficheros
7C3E Puntero a la cadena del archivo que se
busca en el raíz.
10h
000E1681h
0080h
29h
22276CE8h
10h
‘FAT16
7DF1h
‘
CÓDIGO
El código se carga en la posición 0000:7C00. En ese punto está la instrucción de salto ya citada,
que salta, en esta implementación, hasta la posición 0000:7C40, desde donde comenzamos.
0DBD:7C40
0DBD:7C41
0DBD:7C43
0DBD:7C45
0DBD:7C48
0DBD:7C49
0DBD:7C4A
0DBD:7C4D
0DBD:7C50
0DBD:7C51
0DBD:7C52
0DBD:7C53
0DBD:7C54
0DBD:7C57
0DBD:7C5A
0DBD:7C5D
0DBD:7C5F
0DBD:7C60
0DBD:7C61
0DBD:7C62
0DBD:7C63
0DBD:7C64
0DBD:7C67
0DBD:7C6B
0DBD:7C6E
0DBD:7C71
0DBD:7C72
0DBD:7C75
0DBD:7C77
0DBD:7C79
FA
33C9
8ED1
BCFC7B
16
07
BD7800
C57600
1E
56
16
55
BF2205
897E00
894E02
B10B
FC
F3
A4
06
1F
BD007C
C645FE0F
8B4618
8845F9
FB
386624
7C04
CD13
723C
CLI
XOR
MOV
MOV
PUSH
POP
MOV
LDS
PUSH
PUSH
PUSH
PUSH
MOV
MOV
MOV
MOV
CLD
REPZ
MOVSB
PUSH
POP
MOV
MOV
MOV
MOV
STI
CMP
JL
INT
JB
0DBD:7C7B
0DBD:7C7E
0DBD:7C7F
0DBD:7C82
0DBD:7C85
0DBD:7C88
0DBD:7C8B
0DBD:7C8D
8A4610
98
F76616
03461C
13561E
03460E
13D1
50
MOV
CBW
MUL
ADD
ADC
ADD
ADC
PUSH
CX,CX
SS,CX
SP,7BFC
SS
ES
BP,0078
SI,[BP+00]
DS
SI
SS
BP
DI,0522
[BP+00],DI
[BP+02],CX
CL,0B
;
;
;
;
Anula las interrupciones,
y coloca la pila, y los
registros de segmentos SS
y ES.
;
;
;
;
;
;
;
;
;
;
Carga en DS:SI la posición
del DDPT, o tabla de parámetros de disquette, con
información BIOS, y lo mete
en la pila. Modifica la
INT 1Eh a 0000:0522, que debe apuntar a la DDPT, y copia en esa posición la
DDPT que había construído
la BIOS.
ES
; Tras esto, modifica algunos
DS
; valores de la tabla (retarBP,7C00
; do para la próxima operación
BYTE PTR [DI-02],0F
; de E/S, y sectores
AX,[BP+18]
; por pista).
[DI-07],AL
[BP+24],AH
7C7B
13
7CB7
;
;
;
;
;
AL,[BP+10]
;
;
WORD PTR [BP+16];
AX,[BP+1C]
;
DX,[BP+1E]
;
AX,[BP+0E]
;
DX,CX
;
AX
Realiza RESET de la controladora de discos si está
arrancando desde disquette
(creo). Si hay error, muestra mensaje, si no, sigue.
Halla en DX:AX el número
de sectores en el disco hasta el primer sector del directorio raíz usando los datos del final, y los mete
en la pila (los usará luego),
y en 0000:7BFC
0DBD:7C8E
0DBD:7C8F
0DBD:7C92
0DBD:7C95
0DBD:7C98
0DBD:7C9B
0DBD:7C9D
0DBD:7CA0
0DBD:7CA2
0DBD:7CA3
0DBD:7CA5
0DBD:7CA8
0DBD:7CAB
0DBD:7CAC
0DBD:7CAD
0DBD:7CB0
0DBD:7CB2
0DBD:7CB4
0DBD:7CB7
52
8946FC
8956FE
B82000
8B7611
F7E6
8B5E0B
03C3
48
F7F3
0146FC
114EFE
5A
58
BB0007
8BFB
B101
E89400
7247
PUSH
MOV
MOV
MOV
MOV
MUL
MOV
ADD
DEC
DIV
ADD
ADC
POP
POP
MOV
MOV
MOV
CALL
JB
DX
[BP-04],AX
[BP-02],DX
AX,0020
SI,[BP+11]
SI
BX,[BP+0B]
AX,BX
AX
BX
[BP-04],AX
[BP-02],CX
DX
AX
BX,0700
DI,BX
CL,01
7D4B
7D00
0DBD:7CB9
0DBD:7CBB
0DBD:7CBD
0DBD:7CBF
0DBD:7CC0
0DBD:7CC3
0DBD:7CC4
0DBD:7CC5
0DBD:7CC6
0DBD:7CC8
0DBD:7CC9
0DBD:7CCB
0DBD:7CCD
0DBD:7CD0
0DBD:7CD2
382D
7419
B10B
56
8B763E
F3
A6
5E
744A
4E
740B
03F9
83C715
3BFB
72E5
CMP
JZ
MOV
PUSH
MOV
REPZ
CMPSB
POP
JZ
DEC
JZ
ADD
ADD
CMP
JB
[DI],CH
7CD6
CL,0B
SI
SI,[BP+3E]
0DBD:7CD4
0DBD:7CD6
0DBD:7CD8
0DBD:7CDB
0DBD:7CDE
0DBD:7CE0
0DBD:7CE2
EBD7
2BC9
B8D87D
87463E
3CD8
7599
BE807D
JMP
SUB
MOV
XCHG
CMP
JNZ
MOV
7CAD
CX,CX
AX,7DD8
AX,[BP+3E]
AL,D8
7C7B
SI,7D80
0DBD:7CE5
0DBD:7CE6
0DBD:7CE7
0DBD:7CE9
0DBD:7CEA
0DBD:7CEC
0DBD:7CEE
0DBD:7CF0
0DBD:7CF2
0DBD:7CF4
0DBD:7CF7
0DBD:7CF9
0DBD:7CFB
0DBD:7CFE
AC
98
03F0
AC
84C0
7417
3CFF
7409
B40E
BB0700
CD10
EBEE
BE837D
EBE5
LODSB
CBW
ADD
LODSB
TEST
JZ
CMP
JZ
MOV
MOV
INT
JMP
MOV
JMP
SI
7D12
SI
7CD6
DI,CX
DI,+15
DI,BX
7CB9
SI,AX
AL,AL
7D05
AL,FF
7CFB
AH,0E
BX,0007
10
7CE9
SI,7D83
7CE5
;
;
;
;
;
;
Calcula el número de sectores
que ocupa el directorio raíz,
(cada entrada son 32 bytes),
y suma el resultado al nº de
sectores anteriores, dejando
el resultado en 0000:7BFC
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
Obtiene de la pila en DX:AX
el nº del primer sector del
raíz. Usando una rutina, a
la que luego llegaremos,
carga en la posición
0000:0700 ese primer sector.
Si hay error muestra el mensaje, y reinicia.
Esto forma ahora parte de
un bucle, que busca, en el
sector del raíz cargado, el
nombre del archivo situado
en 0000:[0000:7C3E] (en
un principio a WINBOOT.SYS)
Aquí hay un error. Solo
ha cargado el primer sector
del raíz, pero busca el
nombre como si lo hubiese
cargado entero :-???
;
;
;
;
;
;
;
;
;
;
Aquí salta si en el raíz no
encuentra el archivo de
arranque buscado. Si estaba
buscando 'WINBOOT.SYS' cambia el puntero, y repite la
búsqueda con 'IO.SYS' (usando la misma rutina), y si
estaba buscando ya el IO.SYS
muestra un mensaje, y
rearranca.
;
;
;
;
;
;
;
;
;
;
;
;
;
;
Rutina de escribir mensajes.
Se le pasa en DS:SI una especie de puntero a la cadena, la cual deberá terminar en FFh. Tras escribirla, modifica SI, para que
apunte a la cadena
'Cambie el disco y presione
una tecla', que acaba en
00h, y llamandose a sí misma
la escribe. Tras esto, usando
la INT 16h, espera que se
pulse una tecla, y después
reinicia el sistema con
0DBD:7D00
0DBD:7D03
0DBD:7D05
0DBD:7D07
0DBD:7D09
0DBD:7D0A
0DBD:7D0B
0DBD:7D0D
0DBD:7D10
BE817D
EBE0
33C0
CD16
5E
1F
8F04
8F4402
CD19
MOV
JMP
XOR
INT
POP
POP
POP
POP
INT
SI,7D81
7CE5
AX,AX
16
SI
DS
[SI]
[SI+02]
19
; la INT 19h
0DBD:7D12
0DBD:7D15
0DBD:7D18
0DBD:7D1B
0DBD:7D1D
0DBD:7D1F
0DBD:7D20
0DBD:7D21
0DBD:7D24
0DBD:7D26
0DBD:7D29
0DBD:7D2C
0DBD:7D2F
0DBD:7D30
0DBD:7D32
0DBD:7D35
0DBD:7D36
0DBD:7D38
0DBD:7D3C
0DBD:7D3E
0DBD:7D44
0DBD:7D46
BE827D
8B7D0F
83FF02
72C8
8BC7
48
48
8A4E0D
F7E1
0346FC
1356FE
BB0007
53
B104
E81600
5B
72C8
813F4D5A
75A7
81BF0002424A
759F
EA00027000
MOV
MOV
CMP
JB
MOV
DEC
DEC
MOV
MUL
ADD
ADC
MOV
PUSH
MOV
CALL
POP
JB
CMP
JNZ
CMP
JNZ
JMP
SI,7D82
; Aquí salta cuando encuentra
DI,[DI+0F]
; en el raíz el fichero busDI,+02
; cado. Mirando en la entrada
7CE5
; del directorio, saca el
AX,DI
; cluster de comienzo del arAX
; chivo. Si es diferente de 2,
AX
; muestra error de disco con
CL,[BP+0D]
; la rutina anterior. Si es 2,
CX
; calcula el SECTOR de comienAX,[BP-04]
; zo, usando el nº de sector
DX,[BP-02]
; de comienzo de la zona de
BX,0700
; datos guardado en 0:7BFC, y
BX
; el nº de sectores*cluster.
CL,04
; Usando una rutina propia,
7D4B
; carga los 4 primeros secBX
; tores del archivo en 0:0700
7D00
; (=0070:0000), que, supongo,
WORD PTR [BX],5A4D
; se encargarán de cargar
7CE5
; el archivo completo. Antes
WORD PTR [BX+0200],4A42
; de darle el control
7CE5
; comprueba los dos primeros
0070:0200
; bytes del archivo, que deben
; ser 'MZ' (archivo ejecuta; ble), y las dos primeras
; instrucciones: INC DX;
; DEC DX. Si el archivo no
; cumple alguna de las condi; ciones, muestra el error, y
; si las cumple, lo ejecuta, a
; partir de la posición
; 0070:0200 (la parte anterior
; deben ser datos.) He mirado
; y las condiciones solo las
; cumple el WINBOOT.SYS :-???
; He dicho que solo carga cua; tro sectores del archivo.
; Esto lo hace así porque debe
; situar al programa en la po; sición 0000:0700. Sin embar; go, en la posición 0000:7C00
; está éste sector de arranque,
; con los datos de la unidad
; de almacenamiento, que no
; deben ser 'pisadas'. Por
; tanto, tiene poco espacio
; para cargar todo el .SYS,
; y la única solución es car; gar un pequeño trozo, que
; se encargará de 'cargarse'
; a sí mismo en una zona de
; memoria más conveniente.
0DBD:7D4B
0DBD:7D4C
0DBD:7D4D
0DBD:7D4E
0DBD:7D4F
0DBD:7D50
0DBD:7D52
0DBD:7D55
0DBD:7D56
0DBD:7D59
0DBD:7D5A
0DBD:7D5C
0DBD:7D5F
0DBD:7D61
0DBD:7D64
0DBD:7D66
0DBD:7D68
0DBD:7D6A
0DBD:7D6C
0DBD:7D6F
0DBD:7D71
0DBD:7D72
0DBD:7D73
0DBD:7D74
0DBD:7D76
0DBD:7D77
0DBD:7D79
0DBD:7D7A
0DBD:7D7D
0DBD:7D7F
50
52
51
91
92
33D2
F77618
91
F77618
42
87CA
F7761A
8AF2
8A5624
8AE8
D0CC
D0CC
0ACC
B80102
CD13
59
5A
58
7209
40
7501
42
035E0B
E2CC
C3
;
;
AX
;
DX
;
CX
;
CX,AX
;
DX,AX
;
DX,DX
;
WORD PTR [BP+18];
CX,AX
;
WORD PTR [BP+18];
DX
CX,DX
WORD PTR [BP+1A]
DH,DL
DL,[BP+24]
CH,AL
AH,1
AH,1
CL,AH
AX,0201
13
CX
DX
AX
7D7F
AX
7D7A
DX
BX,[BP+0B]
7D4B
PUSH
PUSH
PUSH
XCHG
XCHG
XOR
DIV
XCHG
DIV
INC
XCHG
DIV
MOV
MOV
MOV
ROR
ROR
OR
MOV
INT
POP
POP
POP
JB
INC
JNZ
INC
ADD
LOOP
RET
[Libro de los Virus:
Virus de BOOT ;-) ]
Esta es la rutina de carga,
que convierte el nº de sector al formato BIOS
(cabeza, cilindro, etc.)
Carga 'CX' sectores a partir del número de sector
DX:AX y los deja en
ES:BX. Requiere que
BP=7C00, y DS=0000
DATOS DEL PRINCIPIO DEL SECTOR, CON EL JMP EB3E90
0DBD:7C00
0DBD:7C10
0DBD:7C20
0DBD:7C30
EB
02
81
20
3E
00
16
20
90
02
0E
20
4D
00
00
20
53
00
80
20
57
F8
00
20
49
E2
29
46
4E-34
00-3F
E8-6C
41-54
2E
00
27
31
30
40
22
36
00
00
20
20
02
3F
20
20
10
00
20
20
01
00
20
F1
00
00
20
7D
.>.MSWIN4.0.....
........?.@.?...
......).l'"
FAT16
.}
DATOS FINALES, TRAS EL CODIGO.
Los dos últimos bytes (AA55) indican al sector de partición que este sector
es ejecutable.
0DBD:7D80
0DBD:7D90
0DBD:7DA0
0DBD:7DB0
0DBD:7DC0
0DBD:7DD0
0DBD:7DE0
0DBD:7DF0
03
69
6F
43
20
74
53
00
18
73
FF
61
79
65
59
57
01
74
0D
6D
20
63
53
49
27
65
0A
62
70
6C
4D
4E
0D
6D
45
69
72
61
53
42
0A
61
72
65
65
0D
44
4F
44
20
72
20
73
0A
4F
4F
69-73
69-6E
6F-72
65-6C
69-6F
00-49
53-20
54-20
63
63
20
20
6E
4F
20
53
6F
6F
45
20
65
20
20
59
20
72
2F
64
20
20
53
53
64
72
53
69
75
20
59
00
65
65
FF
73
6E
20
53
00
20
63
0D
63
61
20
80
55
73
74
0A
6F
20
20
01
AA
...'..Disco de s
istema incorrect
o...Error E/S...
Cambie el disco
y presione una
tecla...IO
SYSMSDOS
SYS..
.WINBOOT SYS..U.
Descargar