Monografias.com > Sin categoría
Descargar Imprimir Comentar Ver trabajos relacionados

Debug (página 2)



Partes: 1, 2

Una vez que el programa
está en ejecución, el indicador ("prompt") es un
guión "-", indicando que el "Shell" (http://www.zator.com/Hardware/images/Ico_hoja.gif ) espera
recibir órdenes.  Para salir basta pulsar una
Q.  Como muchos programas de su
género,
sus comandos empiezan
por una letra o combinación de ellas (pueden usarse
indistintamente mayúsculas o minúsculas) y ciertos
parámetros opcionales (no es imprescindible separar la
letra de opción de los parámetros opcionales que
siguen).  La opción más sencilla es la
interrogación ?, cuyo resultado es una lista
resumida de las opciones disponibles:

ensamblar     A [dirección]
comparar      C dirección de
intervalo
volcar        D
[intervalo]
escribir      E dirección [lista
de valores]
llenar        F lista de
intervalos
ir           
G [=dirección] [direcciones]
hex           H
valor1 valor2
entrada       I puerto
cargar        L
[dirección] [unidad] [primer_sector] [número]
mover         M
dirección de intervalo
nombre        N [nombre_ruta]
[lista_argumentos]
salida        O byte de
puerto
proceder      P [=dirección]
[número]
salir         Q
registrar     R [registrar]
buscar        S lista de
intervalos
seguimiento   T [=dirección] [valor]
desensamblar  U [intervalo]
escribir      W [dirección]
[unidad] [primer_sector] [número]
asignar memoria
expandida             
XA [#páginas]
desasignar memoria
expandida          
XD [identificador]
asignar páginas de memoria expandida   XM
[Lpágina] [Ppágina] [identificador]
mostrar estado de
la memoria
expandida XS

La mayoría de los comandos de debug ejecutan una
acción
y vuelven al indicador del shell, pero si es un comando largo,
como puede ser mostrar un trozo grande de código,
puede detenerse pulsando CTRL-Pausa o interrumpirse con CTRL-C
para volver al shell.

Una característica poco conocida, es que debug
puede aceptar entradas desde un fichero "Script", que puede ser
un simple fichero de texto ASCII en el que
cada comando esté separado del anterior por un
INTRO.  Después del último, que debe ser una
"Q" para salir de debug, es conveniente dejar una
línea en blanco pulsando INTRO dos veces.  Las
líneas pueden contener comentarios.  Cualquier cosa a
partir del carácter punto y coma (;) hasta el
final de la línea, será ignorado.

; esto es un comentario

D   ; aquí se mostrará algo…

Suponiendo que tengamos un fichero "Script" de nombre
Ordenes.txt,  puede ser utilizado como entrada para
debug mediante un comando de redirección en la
siguiente forma:

DEBUG < Ordenes.txt

También puede conseguirse que el programa redireccione
la salida hacia un fichero que puede ser inspeccionado más
tarde.   Aunque tiene la dificultad de tener que trabajar "a
ciegas", puede ser de utilidad en
determinadas circunstancias.  Por ejemplo, cuando se desea
un volcado de determinadas zonas de la memoria.  En el caso
anterior podría obtenerse un fichero Result.txt con el
siguiente comando:

DEBUG < Ordenes.txt > Result.txt

§3 
Errores

Cuando debug no sabe interpretar un comando, muestra un
mensaje de error y un indicador "^" debajo del sitio del
comando donde está el error.

§4  Entradas
& Salidas

DEBUG asume que los datos
numéricos proporcionados son hexadecimales, y cuando se
trate de direcciones de memoria, deben introducirse en forma
segmentada (http://www.zator.com/Hardware/images/Ico_hoja.gif
H5.1
).  A su vez, los resultados son mostrados
también en formato hexadecimal cuando se refieren a
direcciones de memoria.  Cuando se trata simplemente del
contenido de ciertas posiciones de memoria, el resultado es
mostrado en formato hexadecimal y en ASCII.  Por ejemplo,
una salida puede presentar el siguiente aspecto:

177C:0180  01 21 10 03 41 10 05 61-10 07 81 10 09 A1 10
0B   .!..A..a……..
177C:0190  C1 10 0D E1 10 0F 01 11-11 21 11 13 41 11 15
61   ………!..A..a
177C:01A0  11 17 81 11 19 A1 11 1B-C1 11 1D E1 11 1F 01
12   …………….
177C:01B0  21 21 12 23 41 12 25 61-12 27 81 12 29 A1 12
2B   !!.#A.%a.'..)..+
177C:01C0  C1 12 2D E1 12 2F 01 13-31 21 13 33 41 13 35
61   ..-../..1!.3A.5a
177C:01D0  13 37 81 13 39 A1 13 3B-C1 13 3D E1 13 3F 01
14   .7..9..;..=..?..
177C:01E0  41 21 14 43 41 14 45 61-14 47 81 14 49 A1 14
4B   A!.CA.Ea.G..I..K
177C:01F0  C1 14 4D E1 14 4F 01 15-51 21 15 53 41 15 55
61   ..M..O..Q!.SA.Ua

Cada fila muestra 16 posiciones de memoria a partir de la
posición señalada por las columnas de la izquierda,
que las muestran como desplazamiento:segmento.  El bloque
central muestra el contenido hexadecimal de cada byte, mientras
que el bloque derecho contiene la representación
ASCII.  Por ejemplo, la 5ª fila muestra el contenido de
las posiciones 177C:01C0 a 177C:01CF (ambas inclusive).  Sus
dos últimos bytes contienen respectivamente los caracteres
5 y a, que corresponden a las cantidades 35h y 61h
del bloque central.  Que como sabemos (http://www.zator.com/Hardware/images/Ico_hoja.gif E2.2.1a), equivalen a
los decimales 53 y 97, que son precisamente los valores
ASCII de los caracteres mencionados.

Nota: Por razón de que éste tipo de
salida pueda ser listado a impresora, el
bloque derecho no contiene en realidad la
representación ASCII de todos los caracteres (algunos ni
siquiera tienen una representación imprimible).  En
realidad solo se muestran los caracteres imprimibles del primer
bloque (US-ASCII). El resto está representado por un
punto.

No perder de vista que, a pesar de que algunas posiciones de
memoria puedan contener valores cuya equivalencia ASCII sea un
carácter imprimible.  Esto no significa que
dichas posiciones representen efectivamente tales valores para la
aplicación que las utiliza. Por ejemplo, puede que en
realidad, las dos posiciones de memoria mencionadas (dos
octetos), en vez de los caracteres 5 y a,
representen una palabra de 16 bits en formato Little Endian
(http://www.zator.com/Hardware/images/Ico_hoja.gif E2.2.6a), que a su vez
representan una cantidad entera (un número). 

§5 
Comandos

Aunque su descripción completa llenaría todo
un capítulo [2], a
continuación comentamos algunas de las opciones más
interesantes relativas a inspección del código y de
contenidos de memoria.

§5.1  La opción D ("Dump")
permite obtener un volcado del contenido de la memoria (de
debug).  La sintaxis acepta dos formas:

D [dirección-inicial] [L
posiciones-desde-dirección-inicial]

D [direccion-inicial][direccion-final]

 Naturalmente, para que exista algo en el bufer de
memoria (al principio quizás solo contiene basura) es
preciso indicarle que lea algo.  Este algo puede ser un
rango de direcciones de memoria RAM; una
dirección absoluta de disco (sector); un fichero, o el
contenido de los registros del
procesador
Para empezar puede indicársele que cargue un fichero
xxx.xyz, que tenemos en el directorio actual o en el PATH, cuyo
contenido queremos ver.

C:> debug xxx.xyz

-D

aquí se obtendría una salida análoga a la
comentada http://www.zator.com/Hardware/images/Ico_hojaFup.gif.

Hemos visto un ejemplo al tratar de los servicios de
interrupciones del PC (http://www.zator.com/Hardware/images/Ico_hoja.gif Servicios-BIOS),
aquí mostraremos otro.  Sabemos que el punto de
inicio de la BIOS es la
dirección F000:FFF0 (http://www.zator.com/Hardware/images/Ico_hoja.gif H4.1), y que desde
esta posición hasta el final de la memoria DOS hay 16
bytes.  Puede obtenerse un volcado de estas posiciones con
el siguiente comando:

-D F000:FFF0

La salida en mi equipo es:

F000:FFF0  CD 19 E0 00 F0
30 36 2F-33 30 2F 39 37 00 FC 38   …..06/30/97..8

En este caso el comando solo muestra una línea porque
ha alcanzado el final de la memoria.  Puede verse que la
fecha de la BIOS del sistema ocupa las
últimas posiciones.

Si se ordena el volcado de una dirección
suficientemente alejada del final de la memoria, sin indicar
ningún número de posiciones, por defecto se toma el
valor 128 (8 filas de 16 posiciones).  Si desea una cantidad
distinta, hay que añadir una L ("Long") y el
número de posiciones, hasta un máximo de 64 KB
(FFFF).  Todos los números deben ser expresados en
hexadecimal.  Por consiguiente los dos comandos que siguen
son equivalentes (recuerde que 80 es el equivalente hexadecimal
de 128):

D FE00:0000

D FE00:0000 L 80

He aquí el resultado:

FE00:0000  41 77 61 72 64 20 53 6F-66 74 77 61 72 65 49
42    Award SoftwareIB
FE00:0010  4D 20 43 4F 4D 50 41 54-49 42 4C 45 20 34 38
36    M COMPATIBLE 486
FE00:0020  20 42 49 4F 53 20 43 4F-50 59 52 49 47 48 54
20    BIOS COPYRIGHT  .
FE00:0030  41 77 61 72 64 20 53 6F-66 74 77 61 72 65 20
49    Award Software I
FE00:0040  6E 63 2E 6F 66 74 77 61-72 65 20 49 6E 63 2E
20    nc.oftware Inc. .
FE00:0050  41 77 03 0C 04 01 01 6F-66 74 77 E9 12 14 20
43    Aw…..oftw… C
FE00:0060  1C 41 77 61 72 64 20 4D-6F 64 75 6C 61 72 20
42    .Award Modular B
FE00:0070  49 4F 53 20 76 34 2E 35-31 50 47 4D 00 8E 32
EC    IOS v4.51PGM..2.

 Sabemos que esta zona corresponde al área de la
BIOS del Sistema…

§5.2  Otra opción muy interesante nos
permite buscar determinados contenidos a través de la
memoria utilizando el prefijo S ("Search").  Existen
dos sintaxis alternativas:

S direccion-de-inicio L longitud-a-explorar
contenido-a-buscar

S direccion-de-inicio direccion-final L contenido-a-buscar

El contenido debe ser proporcionado en hexadecimal (tal como
aparecería en la columna central del ejemplo anterior) o
entre comillas si es un texto ASCII.  Por ejemplo, en un
equipo IBM, deseo ver algunas características de la
BIOS.  Se que estos datos se alojan a partir de la
posición F000:0000 hasta el final de la memoria.  Es
decir, una longitud de 64 Kbytes (FFFF) a partir de la
posición de inicio, y que seguramente, los datos buscados
estarán cerca de la identificación de la propia
BIOS (la cadena "IBM").  Por lo que utilizo la siguiente
sintaxis [3]:

-s f000:0000 L ffff "IBM"

y obtengo la siguiente salida:

F000:3A0C
F000:3A70
F000:3B13
F000:4839
F000:48BA
F000:492A
F000:499A
F000:4A0A

con las direcciones donde se ha encontrado la ocurrencia
buscada.  A continuación puedo explorar las
proximidades de cada posición.  Por ejemplo para la
primera:

-D f000:3a00

F000:3A00  61 73 65 20 36 2E 30 20-66 6F 72 20 49 42 4D
20   ase 6.0 for IBM
F000:3A10  54 68 69 6E 6B 50 61 64-00 20 20 20 20 20 00
43   ThinkPad. .C
F000:3A20  6F 70 79 72 69 67 68 74-20 31 39 38 35 2D 31
39   opyright 1985-19
F000:3A30  39 39 20 50 68 6F 65 6E-69 78 20 54 65 63 68
6E   99 Phoenix Techn
F000:3A40  6F 6C 6F 67 69 65 73 20-4C 74 64 2E 0D 41 6C
6C   ologies Ltd..All
F000:3A50  20 52 69 67 68 74 73 20-52 65 73 65 72 76 65
64   Rights Reserved
F000:3A60  0D 0D 28 43 29 20 43 4F-50 59 52 49 47 48 54
20   ..(C) COPYRIGHT
F000:3A70  49 42 4D 20 43 4F 52 50-4F 52 41 54 49 4F 4E
20   IBM CORPORATION

§5.3  Si lo que se busca está en un
fichero, primero hay que cargarlo.  Lo que se puede hacer de
dos formas:  en la propia invocación de debug,
o mediante los comandos N y L.  Por ejemplo,
si queremos inspeccionar el contenido del fichero
more.com, podemos utilizar dos formas:

C:WINDOWS>debug c:windowscommandmore.com

C:WINDOWS>debug
– N c:windowscommandmore.com

– L

La sintaxis para el prefijo N es:

N [path-name]nombre-de-fichero

En ambos casos el contenido del fichero será cargado en
memoria y podrá ser utilizado.  http://www.zator.com/Hardware/images/Bombilla_.gifAtención: después de la orden L
("Load"), debug le avisará si no encuentra el
fichero, pero seguirá su funcionamiento.  En tal caso
simplemente piensa que N señala el nombre de un
nuevo fichero que creará, con el contenido de la memoria
-de debug-, cuando posteriormente seleccione la
opción escribir W ("Write").

Nota: Como ya habrá deducido, debug
permite leer un fichero, realizar modificaciones en él
(con la opción E) y escribir el fichero modificado
bajo otro nombre con N/W.

 A continuación podemos comprobar el tamaño
del fichero cargado.  Para ello usamos la opción
R (ver estado de los registros) y obtenemos el siguiente
resultado:

-R
AX=0000  BX=0000  CX=2917  DX=0000 
SP=FFFE  BP=0000  SI=0000  DI=0000
DS=17A7  ES=17A7  SS=17A7  CS=17A7  IP=0100   NV UP EI PL NZ NA PO NC
17A7:0100 E8CD0F        CALL
10D0

Aquí nos interesa especialmente el contenido del
registro CX,
cuyo valor, 2917h (1519d) en este caso, señala el
tamaño del fichero en bytes. También
podíamos haber utilizado directamente el comando R CX que
nos proporciona el valor de dicho registro:

-R CX
CX 2917
:

Nota: A continuación del valor
correspondiente, debug muestra dos puntos (:),
señalando que puede cambiar el valor del registro
introduciendo un nuevo número.  Pulse INTRO para
dejar las cosas como están y volver al "prompt" (-) de
debug.

Al llegar a este punto, es importante señalar que, a
excepción de los ficheros .exe, debug carga
los ficheros a partir de la dirección 100h (256d) de "su"
memoria.  De forma que el primer octeto del fichero se carga
en la dirección 100; el segundo en 101; etc.  En
nuestro caso, el fichero se extenderá desde la
posición 100h hasta 2A17h (100h + 2917h).

A continuación, para buscar la cadena "Microsoft" en
el fichero, utilizamos cualquiera de los siguientes comandos:

– S 100 L 2917 "Microsoft"

– S 100 2a17 "Microsoft"

El primer comando señala el punto de inicio y el
tamaño de la zona a buscar;  el segundo utiliza los
puntos inicial y final de la exploración.  Con ambos
se obtiene la misma respuesta:

17A7:1083
17A7:10B2 

Truco: Debido a la forma especial en que se cargan
los ejecutables .exe, si quiere inspeccionar la forma
nativa de uno de estos ficheros (como es su imagen en el
disco), debe hacer una copia del fichero; renombrarlo con
cualquier otra terminación (o sin ella) y cargar esta
copia.  En caso contrario, debug se preparará
para funcionar como un verdadero depurador de tiempo de
ejecución (run-time), para lo que cargará el
fichero y lo acomodará en memoria de forma que pueda
ejecutarse [5].

Como ejercicio, compruebe las distintas longitudes y aspecto
(especialmente al principio) de un mismo fichero .exe
cargándolo con debug de las dos formas (busque en
su sistema un .exe lo más pequeño posible).


§5.4
  Además de la capacidad de leer
ficheros antes mencionada, quizás una de las opciones
más interesantes (y peligrosas) de debug es la
posibilidad de leer/escribir el contenido de disco a bajo nivel
mediante los prefijos L ("Load") y W
("Write").  Se utiliza la siguiente sintaxis:

L [Dirección] [Unidad] [Primer_sector]
[Número]

W [Dirección] [Unidad] [Primer_sector]
[Número]

El significado de los parámetros es como sigue:

  • Dirección: Posición de la memoria
    de debug, a partir de la cual se instalarán los datos
    leídos del disco, o se tomarán para el proceso de
    escritura
    (aquí se utiliza generalmente el valor 100h).
  • Unidad: Valor numérico que indica la
    lógica a utilizar.  0 =
    A:;  1 = B:;  2 = C:;  3 =
    D:, etc [6]
  • Primer sector: A partir del que se
    realizará la lectura,
    o se comenzará a escribir.
  • Número: Número de sectores que se
    desea cargar/escribir.  Como debug no puede leer/escribir
    más de 64 Kbytes (216 = 65536) y los
    sectores de disco son de 512 bytes, el máximo
    número de sectores es 128 (80h).  Así pues,
    el valor máximo aquí es 80. 

Ejemplo:  Para obtener el contenido del sector de
arranque ("Master boot sector" MBR) de un disquete en A:,
utilizaremos el comando:

C:WINDOWS>debug
– L 100 0 0 1

– D 100 L 200

Como el resultado no cabe en una pantalla, ingeniaremos un
procedimiento
para conservarlo en un fichero (más adelante nos
servirá para otro propósito).  Para ello
creamos un fichero script.txt con el siguiente contenido (dos
INTRO después de la "Q"):

L 100 0 0 1
D 100 L 200 Q

 A continuación invocamos debug con el
comando

C:WINDOWS>debug < D:buzonscript.txt >
D:buzonresultad.txt

 

 

 

 

Autor:

José Luis Peñaloza Gallegos

México

11 de Septiembre de 2008

Partes: 1, 2
 Página anterior Volver al principio del trabajoPágina siguiente 

Nota al lector: es posible que esta página no contenga todos los componentes del trabajo original (pies de página, avanzadas formulas matemáticas, esquemas o tablas complejas, etc.). Recuerde que para ver el trabajo en su versión original completa, puede descargarlo desde el menú superior.

Todos los documentos disponibles en este sitio expresan los puntos de vista de sus respectivos autores y no de Monografias.com. El objetivo de Monografias.com es poner el conocimiento a disposición de toda su comunidad. Queda bajo la responsabilidad de cada lector el eventual uso que se le de a esta información. Asimismo, es obligatoria la cita del autor del contenido y de Monografias.com como fuentes de información.

Categorias
Newsletter