[ Tutorial de SoftIce ]
Por Black Fenix


[ ¿QUE ÉS SOFTICE ? ]


Para aquel que desconozca lo que significa el SoftIce en el mundillo del cracking y la ingeniería inversa, se podría decir que básicamente es el pilar en el que todo buen cracker apoya sus conocimientos y la mayoria de sus posibilidades de éxito. Es el debugger por excelencia, programado por los "wizards" de la compañia bullet.gif (296 bytes) Numega Technologies, sus características lo convierten en un arma casi imprescindible para afrontar cualquier tarea de cracking o debugging. No debe faltar, por eso te aconsejo que si puedes lo compres, no te arrepentirás, ya que merece la pena pagar por una joya de este tipo.

"Ya sé Kung-Fu - Demuestraló..." The Matrix


[ SOFTICE ] - "Nuestro congelador particular"


La palabra SoftIce define perfectamente lo que esta gran herramienta significa, "congela" el software para su posterior preparación, de la misma manera que podemos congelar las barras de pan y al día siguiente comernoslas bien calentitas después de haberlas pasado por el microondas. Después de esta comparación  tan subversiva, voy a dar paso al tutorial de nivel básico sobre lo que mucha gente estaba esperando (ya era hora dirán muchos). En este tutorial haré un repaso de los comandos más básicos, creación de macros y personalización del inicio del SoftIce. Supongo que todos habeis instalado el software (esto es muy fácil y creo que no se debe explicar, si alguien necesita una explicación que la pida formalmente enviandome un bullet.gif (296 bytes) e-mail). El tutorial aquí expuesto a sido traducido y resumido en su mayor parte de los originales en Inglés, he añadido algunas observaciones y trucos a los comandos más útiles. No puedo asegurar que la traducción sea perfecta, por eso, si alguien encuentra algún error espero que me lo comunique.


[ SOFTICE ] - "Personalización del entorno"


Comenzaré por explicar la personalización del SoftIce, esta personalización resulta fundamental en las primeras versiones, por el contrario en las últimas versiones se incluye una herramienta llamada Symbol Loader desde la cual podremos realizar los ajustes necesarios sin necesidad de editar ningún fichero. Esto resulta muy cómodo ya que nos permite cargar las funciones exportadas por cualquier DLL en cualquier momento y sin tener que reiniciar el ordenador. Aún así podemos modificar de forma directa estos archivos en las versiones más modernas, por eso es importante conocer los detalles más significativos de los archivos que en versiones previas debiamos modificar. En particular el archivo de personalización se llama WINICE.DAT y se encuentra en el directorio donde se haya instalado el SoftIce.

Una vez localizado el archivo podremos editarlo con un editor de textos y realizar los cambios necesarios para adaptar el SoftIce a nuestro gusto. Entre las primeras líneas de este archivo vereis:

LOWERCASE=OFF
bullet.gif (296 bytes) Desensamblado en minúsculas: Determina si SoftIce usa letras minúsculas para representar el desensamblado del código, por defecto se encuentra desactivada.

MOUSE=ON
bullet.gif (296 bytes) Activa el mouse: Activa o desactiva el mouse para que pueda ser utilizado cuando SoftIce está activo. Resulta útil cuando nuestro mouse no funciona correctamente con el SoftIce (el mio por ejemplo).

HST=256
bullet.gif (296 bytes) Tamaño del buffer de historial: Determina el tamaño del buffer de historial que usará el SoftIce.Por defecto 256KB. El buffer de historial contiene toda la información visualizada en la ventana de comandos. Además, salvar el buffer de historial a un archivo es de gran utilidad para volcar grandes cantidades de datos, código desensamblado. Para salvar el buffer de historial a un archivo usaremos la utilidad NMSYM que es una orden de comandos que funciona externamente a SoftIce, aún disponiendo de este utilidad SoftIce se queda corto en cuanto a volcados de memoria a disco se refiere, por lo que a veces se hace indispensable utilizar un volcador (dumper) externo o interno, en la sección de bullet.gif (296 bytes) Tools de mí página encontraras el bullet.gif (296 bytes) SoftDump de Quine.

TRA=8
bullet.gif (296 bytes) Tamaño del buffer de trazado: Este valor determina el tamaño del buffer de trazado. El buffer de trazado puede mantener un registro de trazados para los comandos bullet.gif (296 bytes) BPR y bullet.gif (296 bytes) BPRW. Por defecto este valor se establece en 8 KB.

INIT="X;"
bullet.gif (296 bytes) Cadena de inicialización: Esta línea indica los comandos que SoftIce deberá ejecutar una vez se haya inicializado, por defecto encontramos el comando X, que simplemente sale del SoftIce sin realizar ninguna operación seguido del caracter ";" obligatorio. El valor aquí especificado puede sernos útil para por ejemplo trazar el Windows desde su inicio más primitivo :), cambiar el tamaño de la ventana de código o para iniciar una sesión de debugging remota. Para añadir más comandos deberemos de separarlos por el caracter ";" un ejemplo:

LINES 50;ALTKEY ALT Z;WR;X;

Este ejemplo cambia las lineas visualizadas a 50, establece como teclas de activación la combinación Alt+Z, activa la ventana de registros y sale del SoftIce.

A continuación vereis la asignación de comandos a cada tecla de función, os aconsejo que las dejeis tal y como están ya que la mayoría de tutoriales del SoftIce asumen que están configuradas de esta manera. Para asignar un comando a una tecla, se utiliza esta sintaxis:

Tecla activación + Tecla Función = "comando1;comando2;comando_n...;"

Donde tecla de activación puede ser: A -> Alt, C -> Control, S para Shift o ninguna. Aquí vemos unos ejemplos:

F5="^x;"
SF3="^format;"
CF9="TRACE OFF;"
AF3="^wc;"

A continuación viene la parte más importante de todas, la sección que indica que funciones se cargarán al inicio del SoftIce para que esten disponibles mediante los comandos que establecen breakpoints. Aquí vemos una linea de ejemplo:

EXP=c:\WINDOWS\SYSTEM\KERNEL32.DLL

Esta línea indica que se carguen todas las funciones que son exportadas por la librería KERNEL32.DLL, con esto podremos establecer breakpoints   en cualquiera de estas funciones. Recomiendo que añadas las lineas siguientes a la seccóon de exportación, si es que no las tienes.

EXP=c:\WINDOWS\SYSTEM\KERNEL32.DLL    // Funciones del KERNEL32
EXP=c:\WINDOWS\SYSTEM\USER32.DLL        // Funciones básicas de cuadros de diálogo
EXP=c:\WINDOWS\SYSTEM\GDI32.DLL            // Funciones de dibujo del GDI de windows
EXP=c:\WINDOWS\SYSTEM\ADVAPI32.DLL    // Funciones para el manejo del registro de Windows

Recuerda cambiar el camino por el correcto, ya que windows puede estar instalado en otro directorio que no sea el del ejemplo. Los ficheros de exportación pueden ser de varios tipos, EXE, DRV, etc. no tiene porque ser DLL's recuerdalo.

La exportación de simbolos resulta muy útil cuando tenemos un software que basa su protección en funciones de alguna DLL o realiza un uso intensivo de estas , por eso siempre es importante comprobar las funciones que son exportadas por el ejecutable y si combiene incluirlas en esta sección. Cada vez que incluyamos una libreria, deberemos de reiniciar para que los cambios surtan efecto. Este problema se ha visto solucionado con el antes mencionada Symbol Loader, el cual nos permite cargar los símbolos de exportación sin tener que reiniciar.

Por el momento hemos terminado con el archivo de configuración (quedan más cosas pero estan son las más primordiales, si quieres saber el resto ¿que tal si te miras la ayuda que viene con el SoftIce? ).

Veamos ahora en una imagen, lo que podría ser una teórica distribución del area de trabajo del SoftIce:

softice.gif (121869 bytes)
bullet.gif (296 bytes) Esto es más o menos lo que nos aparecerá cada vez que activemos el SoftIce con Ctrl+D (tecla por defecto)

VENTANA DE REGISTROS: Muestra el estado actual de los flags del micro y los valores de cada uno de sus registros internos más utilizados. Se activa y desactiva con el comando WR (Windows Register). Para mover el cursor a esta ventana se utiliza Alt-R (por defecto), esto nos permitirá modificar sus valores :) .
VENTANA DE VARIABLES LOCALES:Muestra el marco actual de la pila, si disponemos del código fuente de la aplicación podemos ver que es cada uno de los valores que esta contiene, en la mayoría de casos no dispondremos del código fuente por lo que esta ventana no es de gran utilidad. Podemos activarla/desactivarla  con el comando WL. Para mover el cursor a esta ventana se utiliza Alt-L (por defecto).
FLECHAS DE NAVEGACIÓN: Si disponemos de un ratón que funcione correctamente con SoftIce, podemos hacer click sobre estas flechas para desplazar el texto  de las diferentes ventanas. Si no disponemos de mouse, podemos utilizar las siguientes teclas para movernos por el entorno:

Dirección del desplazamiento y distancia Teclas
Desplazarse la ventana a la página previa PageUp / Página Arriba
Desplazarse la ventana a la siguiente página PageDown / Página Abajo
Desplazarse la ventana a la línea previa UpArrow / Flecha Arriba
Desplazarse la ventana a la línea siguiente DownArrow / Flecha Abajo
Saltar a la primera línea del fichero fuente Home / Origen
Saltar a la última línea del fichero origen End / Fín
Desplaza la ventana a la izquierda un carácter LeftArrow / Flecha Izquierda
Desplaza la ventana un carácter a la derecha RightArrow / Flecha Derecha

VENTANA ESPÍA: Muestra el valor de las variables espiadas con el comando WATCH. Se activa y desactiva con el comando WW.Para mover el cursor a esta ventana se utiliza Alt-W (por defecto).
VENTANA DE DATOS: Muestra el contenido de la memoria cuando se utilizan los comandos DD DB DW etc. Se activa y desactiva con el comando WD.Para mover el cursor a esta ventana se utiliza Alt-D (por defecto).
VENTANA DE CÓDIGO: Muestrra el código desensamblado (esto será en la mayoría de los casos) y si disponemos del código fuente, también nos lo puede mostrar. Se activa/desactive con el comando WC (el servicio por favor?). Para mover el cursor a esta ventana se utiliza Alt-C (por defecto).
VENTANA DE COMANDOS: Nos permite introducir comandos y nos muestra el resultado de estos.
VENTANA DE LA PILA DE LA FPU: Esta ventana no sale en la imagen, pero se encarga de mostrarnos el contenido de la FPU, para activarla/desactivarla se utiliza el comando WF.
VENTANA DE REGISTROS PARA PENTIUM III: Esta tampoco aparece en el ejemplo, nos muestra el contenido de los registros adicionales del Pentium III, se activa/desactiva con WX.

Bueno estas son las areas de trabajo, ahora que ya las conocemos vamos a ver como podemos alterar su tamaño. Para alterar el tamaño de cualquier ventana, usaremos el comando que se utilize para activarla seguido del número de líneas que queremos que se nos muestre. P. ej:

:WC 10

Muestra la ventana de código con 10 líneas.
También podemos cambiar el tamaño total de la ventana de SoftIce con los comandos LINES y WIDTH p. ej:

: LINES 50
: WIDTH 120

Esto hace que el tamaño total de la ventana de SoftIce sea de 50 líneas por 120 columnas. >También podemos cambiar la posición de la ventana del SoftIce con el comando SET ORIGIN x y, donde x e y son las coordenadas en pixels onde queremos que aparezca la ventana. Esto es util porque a veces el SoftIce puede taparnos datos de las ventanas de Windows, con este comando movemos la ventana del SotIce sin tener que salir de este.

Aquí tines algunos comandos/teclas de gran utilidad para moverte por la "arena" mas cómodamente:

SET FONT n -> Establece el tipo de fuente especificada en n pudiendo ser 1 2 o 3
Control+L -> Se utiliza en algunas ocasiones muy raras en las que parte de la ventana del SoftIce se ve tapada por otra ventana de Windows (refresca la ventana y la pinta de nuevo).
Control+Alt+Home-> Reestablece la posición de la ventana del softIce a las coordenadas 0,0

Bueno ya sabemos más o menos en que entorno nos deberemos mover, parece hostíl, pero aun así no debes dudar de su "poder". Veamos ahora otro tema bastante importante.


[ SOFTICE ] - ¿Cuando se activa el SoftIce?


Una vez se instale el SoftIce, este aparecerá en cualquiera de las siguientes ocasiones:

bullet.gif (296 bytes) Cuando se cargue el SoftIce. Por defecto, la cadena de inicialización de este contiene el comando X (Salir/Exit), por eso se cerrará inmediatamente. Ver más arriba la línea INIT=.
bullet.gif (296 bytes) Cuando se pulse Ctrl+D. Esta tecla rápida activa/desactiva la ventana del SoftIce.
bullet.gif (296 bytes) Cuando se active algún breakpoint.
bullet.gif (296 bytes) Cuando el SoftIce captura un fallo en el sistema, normalmente una excepción no gestionada por el propio programa que causó el fallo. (tipico mensaje:
"Este programa a efectuado una operación no válida y....bla bla.."). Cuando SoftIce se activa de esta manera, tenemos dos opciones, ver donde falló el programa y intentar arreglarlo (nunca lo he conseguido) o dejar que Windows continue con el error (para ello deberemos teclear el comando SET FAULTS OFF el cual hará que SoftIce no se active cuando se produzcan errores o excepciones no controladas por los programas, siguiendo el proceso de error normal).
bullet.gif (296 bytes) Cuando el sistema se cuelge resultando en una pantalla azul en NT.

Cuando el SoftIce se activa, todas las tareas de fondo quedan en pausa, todas las interrupciones son desactivadas, incluso el reloj de Windows (más de una vez he llegado tarde a una cita por esto :)  y es que a uno se le pasan las horas volando delante del SoftIce ).  SoftIce se encarga de acceder al video y el teclado mediante accesos directos al hardware, con lo cual el sonido quedará desactivado, los programas de grabación de Cds también, el WinAmp todo, todo, todo. Excepto la reproducción de Cd's de audio (por lo menos podremos tener algo de música en nuestra sesiones) que no depende de la CPU y va por cuenta propia directamente por el cable de audio de nuestra unidad de CD.


[ SOFTICE ] - Guía de comandos más utilizados


Antes de seguir adelante aclarar que SoftIce solo entiende los números hexadecimales, por lo tanto cualquier número que sea especificado como parámetro se supone que es hexadecimal. Esto deberá ser tenido muy encuenta ya que podemos equivocarnos pensando que 10 es 10h.

 marcador.gif (1024 bytes) ?: Evaluar expresión.

Para Windows 3.1 -> ? [command | expression]
Para Windows 9x y NT ->
? [expression]

Bajo Windows 3.1, el parámetro especificado determina cuando se visualiza la ayuda o se evalua una expresión. si se especifica un comando, H muestra información detallada sobre este, incluyendo la sintaxis del comando y un ejemplo. Si se especifica un expresión, la expresión es evaluada, y el resultado es visualizado en hexadecimal, decimal, decimal con signo (solo si <0), y ASCII.

Pajo Windows 9x y NT, el comando ? solo evalua expresiones. Utiliza el comando bullet.gif (296 bytes) H para obtener ayuda sobre los comandos del SoftIce. Para evaluar una expresión introduce el comando ? seguido de la expresión a evaluar. El resultado es visualizado en hexadecimal, decimal, decimal con signo (solo si <0), y ASCII.

:? 10*4+3
00000043 0000000067 "C"

Nota: Todos los números especificados en la expresión son interpretados como números hexadecimales.

marcador.gif (1024 bytes) A [ dirección ]: Se utiliza para ensamblar nuevas intrucciones  en la direccíon de memória especificada por dirección. Este comando soporta el juego de instrucciones de los 80x86. Si no se especifica ninguna dirección, se ensamblará a partir de la última dirección donde se indicara. Si se introduce este comando y no se hubo introducido previamente una dirección, se comenzará a ensamblar a partir del CS:EIP actual. Este comando entra en el ensamblador interactivo del SoftIce. Una dirección visualiza una entrada de datos por cada linea ensamblada. Teclea la instrucción a ensamblar y pulsa ENTER, así por cada instrucción a ensamblar, cuando no quieras ensamblar más instrucciones pulsa ENTER dos veces.

marcador.gif (1024 bytes) BC lista | *: Borra uno o más puntos de ruptura (breakpoints). Lista es una série de indices por cada punto de ruptura separada por comas o espacios.Para borrar todos los breakpoints usaremos el comando: BC * , para borrar el breakpoint 3 y el 6 haremos: BC 3 6.

marcador.gif (1024 bytes) BD lista | *: Desactiva uno o más puntos de ruptura (breakpoints). Lista es una série de indices por cada punto de ruptura separada por comas o espacios.Para desactivar todos los breakpoints haremos: BD *, para desactivar el breakpoint 3 y el 6 haremos: BD 3 6.

marcador.gif (1024 bytes) BE lista | *: Activa uno o más puntos de ruptura (breakpoints). Lista es una série de índices por cada punto de ruptura separada por comas o espacios.Para activar todos los breakpoints haremos: BE *, para desactivar el breakpoint 3 y el 6 haremos: BE 3 6.

marcador.gif (1024 bytes) BL lista | *: Visualiza un listado con todos los breakpoints que tenemos establecidos, esten activos o no. En este listado aparece el índice, el tipo de breakpoint , su estado y cualquier condición que este tenga asignada.

marcador.gif (1024 bytes) BMSG window-handle [L] [ begin-msg [end-msg]] [c= count]: Establece un breakpoint en uno o más mensajes de Windows.

window-handle: El Handle HWND de la ventana que se retorna por las funciones CreateWindow o CreateWindowEX.
L: Muestra los mensajes en la ventana de comandos del SoftIce.
begin-msg:
Mensaje único o número de mensaje más bajo que este en un rango de valores válido. si no se especifica un rango de mensajes, solo el mensaje begin-msg surtirá efecto.

Nota: Para la variables begin-msg y end-msg, los números de los mensajes pueden ser especificados en hexadecimal o  por su valor ASCII actual, por ejemplo WM_QUIT. Para ver una lista de estos valores puedes utilizar el comando bullet.gif (296 bytes) WMSG.

end-msg: El valor máximo del rango de mensajes de Windows.
c= contador de veces que se ejecutará hasta su activación final.
IF expresion expresión condicional: La expresión debe evaluarse como  TRUE (no-cero) para que el breakpoint se active.
DO command Breakpoint action: Una serie de comandos del SoftIce que se ejecutaran cada vez que el breakpoint se active.

Ejemplo:

:BMSG 9BC wm_mousefirst wm_mouselast

Este ejemplo establece un breakpoint en el manejador de mensajes de la ventana 9BC para los comandos wm_mousefirst wm_mouselast, este rango de comandos incluye todos los eventos que se pueden realizar con el ratón. Para ver el manejador asignado a una ventana deberemos usar el comando bullet.gif (296 bytes) TASK (para obtener el nombre de la aplicación) y luego el comando bullet.gif (296 bytes) HWND nombre_tarea para obtener todos los manejadores asociados a esta tarea. Este comado puede resultar muy potente para entrar en un determinado punto del programa. Con tan solo especificar el tipo de evento, lograremos acceso al código que controla este evento :), algunos resultan especialmente utiles como WM_GETTEXT, WM_QUIT, para una descripción de los comandos de mensaje te aconsejo que te mires la guía de referéncia del API de Windows.

marcador.gif (1024 bytes) BPINT int-number [al|ah|ax= value] [c= count] (solo Windows 3.1): Establece un breakpoint en la interrupción especificada. Int-number va desde 00h hasta 5fh. Este comando resulta de especial utilidad en las aplicaciones de MS-DOS que basan su funcionamiento en el uso de interrupciones. Mediante este comando podemos establecer un breakpoint sobre cualquier interrupción (int-number). Mediante el valor AX|AH|AL podemos especificar el valor que deberá tener el registro para que el breakpoint surta efecto. Esto sirve para "filtrar" de alguna manera el servicio concreto de la interrupción. El comando BPINT solo funciona con interrupciones manejadas desde la IDT (Interrupt Descriptor Table).

Ejemplo:

BPINT 21 ah=4c

En este ejemplo se establece un breakpoint sobre la interrupción 21h, servicio 4Ch que indica que se termine la ejecución del programa en curso.

marcador.gif (1024 bytes) BPINT int-number [IF expression] [DO "command1;command2;..."] (Windows 9x y NT): Establece un breakpoint en la interrupción especificada. Int-number va desde 00h hasta FFh, expression debe ser una exresión que se evalue como TRUE  (diferente a 0) para que el breakpoint surta efecto. command debe ser una lista  de los comandos de SoftIce que se ejecutaran cuando el breakpoint surta efecto. El comando BPINT solo funciona con interrupciones manejadas desde la IDT. Si se ejecuta una interrupción bajo una ventana de DOS (Virtual Machine), el control es transferido a un manejador de windows en modo protegido. Este manejador, llamará posteriormente al manejador en modo real que es apuntado por la tabla de vectores de interrupción del DOS. Para ir directamente al código en modo real se puede ejecutar el siguiente comando:

:G @ &0:(int-number*4)

El siguiente ejemplo muestra un breakpoint que se activará cuando se ejecute una interrupción software 2Eh si el thread que hizo la llamada tiene el identificador (TID) igual al thread actual en el momento que se introdujo el comando (_TID). Cada vez que el breakpoint surte efecto el contenido de la dirección 82345829h se vuelca, como efecto del comando DO.

: BPINT 2E IF tid==_tid do "dd 82345829"

marcador.gif (1024 bytes) BPIO: Establece un breakpoint para un acceso de E/S a un puerto.

Para Windows 3.1-> BPIO port [verb] [ qualifier value] [c= count]

Para Windows 95 -> BPIO [-h] port [verb] [IF expression] [DO "command1;command2;..."]

Para Windows NT -> BPIO port [verb] [IF expression] [DO "command1;command2;..."]

port valor de un byte o una palabra.
verb:
R lectura (read), W escritura (Write), RW lectura y escritura (Reads and Writes)
qualifier:
EQ igual (equal), NE no igual (not equal), GT mayor que (greater than), LT menor que (less than), M mascara, una mascara se representa por una combinación de 1 y 0 y X, donde X son valores sin importancia.
value:
Byte, palabra , o doble palabra.
c=
: contador de activación
-h:
Usa los registros de depuración para establecer un breakpoint en un dispositivo virtual (VXD). Disponible solo para procesadores Pentium bajo Windows 95.
IF expression expresión condicional:
La expresión debe evaluarse como TRUE (diferente que 0) para que el breakpoint surta efecto.
DO command:
Una serie de comandos que se ejecutaran cuando el breakpoint se active.

Debido al comportamiento de la arquitectura de los x86, los breakpoints BPIO son tenidos en cuenta mientras el procesador este ejecutando instrucciones en el nivel de privilegio RING 3. Esto significa que las actividades de E/S realizadas por código en RING 0, como la de dispositivos VXD y las del gestor de la máquina virtual de Windows (VMM), no son capturadas por estos breakpoints. Exclusivamente para Windows 95 se puede utilizar la opción -H para forzar al SoftIce a la utilización de los registros de depuración. Esto te permite capturar las operaciones de E/S realizadas por código en RING 0.

Ejemplo:

: BPIO -H 378 RW

Este breakpoint se activará cada vez que se intente leer/escribir un valor al puerto 378h, si se ejecuta por algún dispositivo VXD bajo Windows 95, este también surtirá efecto debido a la opción -H. Este pequeño truco de la -H es bastante útil para cuando tengamos que enfrentarnos a mochilas.

marcador.gif (1024 bytes) BPM: Establece un breakpoint en un acceso o ejecución de una posición de memoria.

Para Windows 3.1-> BPM[size] address [verb] [ qualifier value] [ debug-reg] [c= count]

Para Windows 9x y NT -> BPM[size] address [verb] [ debug-reg] [IF expression] [DO "command1;command2;..."]

size: Especifica el rango de posiciones cubiertos por el breakpoint. Por ejemplo, si se establce una doble palabra y el tercer byte es modificado, el breakpoint se activará. El tamaño es también importante si se especifica el calificador opcional. B Byte, W Word, D Double Word.
verb: R lectura (read)  , W Escritura (Write), RW Lectura y escritura (Read and Write), X Ejecución (Execute).
qualifier: EQ igual (equal), NE no igual (not equal), GT mayor que (greater than), LT menor que (less than), M mascara, una mascara se representa por una combinación de 1 y 0 y X, donde X son valores sin importancia.
value:
Byte, palabra , o doble palabra.
debug-reg: Registro de depuración, pudiendo ser: DR0, DR1, DR2, DR3.
c=: contador de activación.
IF expression expresión condicional: La expresión debe evaluarse como TRUE (diferente que 0) para que el breakpoint surta efecto.
DO command:
Una serie de comandos que se ejecutaran cuando el breakpoint se active.

Utiliza los breakpoint BPM para hacer que el SoftIce se active cuando ciertos tipos de accesos sean realizados a las posiciones de memoria. Se pueden utilizar los parametros size y verb para filtrar los accesos de acuerdo con su tipo, y puedes usar el parametro DO, solamente en NT para especificar los comandos de SoftIce que se ejecutarán tras la activación del breakpoint.

Si no se especifica un registro de depuración, SoftIce utiliza el primer registro disponible empezando por el DR3 y continuando hacia abajo. No se debe incluir un registro de depuración a menos que se esté depurando una aplicación que utilize estos registros, como puede ser otro depurador. Si no se especifica verb, RW es el valor por defecto. si no se especifica size, B es el valor por defecto.

Para Windows 3.1: Bajo Windows 3.1 puedes utitlizar el parámetro count para activar el breakpoint solamente después de que se haya ejecutado un número de veces especifico.

Para Windows 95x: Los breakpoints establecidos en rangos de memoria entre 400000 - 7FFFFFFF (aplicaciones Win32) son direcciones sensibles al contexto. Esto significa que el breakpoint se activará solo cuando el contexto de memoria donde se estableció el breakpoint se encuentre activo. Si un BPM se establece sobre una DLL que existe en múltiples contextos, el breakpoint se activará en todos los contextos donde esta exista. Por ejemplo, si se pone un BPM X en el KERNEL32 este podrá activarse en cualquier contexto donde se encuentre esta DLL.

Para Windows NT: cualquier breakpoint establecido en una dirección inferior a 80000000h (2 GB) es sensible al contexto. Esto incluye aplicaciones WIN32 y aplicaciones DOS V86. Asegurate que estés en el contexto correcto antes de establecer el breakpoint.

Los BPM pueden utilizarse tambien con las funciones API del Windows, y ofrecen una manera más efectiva de que el breakpoint surta efecto cuando el comando BPX no funciona. Esto es debido a que usan los registros de depuración como método de activación, y no el conocido sistema de sustitución del código por el de la interrupcion INT 3 o INT 1. La desventaja es que sólo podemps tener un máximo de 4 BPM debido a que solo existen 4 registros de depuración disponibles en todos los Pentium.

El siguiente ejemplo establece un breakpoint para un acceso de escritura sobre la posición de memoria DS:80150000h . El breakpoint surte efecto la primera vez que se escriba en esta posición un valor mayor que 5.

:BPM ds:80150000 if (byte(*ds:80150000)>5)

marcador.gif (1024 bytes) BPR: Establece un breakpoint en un rango específico de memoria.

Para Windows 3.1-> BPR start-address end-address [ verb] [c= count]
Para Windows 9x ->
BPR start-address end-address [ verb] [IF expression][DO "command1;command2;..."]

start-address: Inicio del rango de memoria.
end-address:
Fin del rango de memoria.
verb:
Puede ser uno de los siguientes valores:

R Lectura (Read)
W Escritura (Write)
RW Lectura y escritura (Reads and Writes)
T Trazar hacia atras en ejecución
TW Trazar hacia atrás cuando se escribe a la memoria.

c= Contador de activación del breakpoint.
IF expression Conditional expression:
la expresión debe evluarse como TRUE (diferente a 0) para que se active el breakpoint.
DO command Breakpoint action:
Una serie de comandos de SoftICE que se ejecutarán cuando el breakpoint se active.

Utiliza el comando BPR para establecer breakpoints que se activan cuando ciertos tipos de accesos a memoria se realizan sobre un rango entero de memoria.

No existe un rango explícito para los breakpoint de ejecución, sin embargo se puede utilizar el verbo (verb) R para establecer breakpoints en un rango. Una instrucción de entrada se considera como una lectura para los breakpoints de rangos. Si no se especifica un verbo (verb) W es el valor por defecto.

En ciertas circusntancias el breakpoint de rango degrada el rendimiento del sistema. Cualquier lectura o escritura en una página de 4KB que contenga un breakpoint de rango es analizada por SoftIce para determinar si satisface la condición del breakpoint. Esta degradación de rendimiento no es usualmente perceptible, sin embargo,  puede ser extrema en casos donde se realizen frecuentes accesos al rango de memoria.

Los verbos T y TW activan el trazado hacia atrás en el rango especificado. Estos no causan breakpoints, en vez de eso escriben información sobre todas las instrucciones que pudieran haber causado la activación del breakpoint al registro (log) el cual puede ser visualizado con los comandos bullet.gif (296 bytes) SHOW o bullet.gif (296 bytes) TRACE.

Cuando un breakpoint de rango se activa y SoftIce aparece, el valor actual de CS:EIP apunta a la instrucción que causó la activación.

Los breakpoint de rango se establecen siempre en páginas de tablas que están activas cuando se introduce el comando BPR. Por consiguiente, si direcciones de rango estan por debajo de los 4MB, el breakpoint de rango será atado a la máquina virtual actual cuando el BPR se introdujo. Por este hecho, hay algunas areas de memoria donde los breakpoints de rango no están soportados. Estas zonas incluyen las páginas de tablas, las tablas de descriptores globales (GDT), las tablas de descriptores de interrupción (IDT), y el mismo SoftIce. Si se intenta establecer en breakpoint de rango sobre una de estas zonas, SoftIce retornará un error.

Existen dos areas más en las que no se deben establecer estos breakpoints, pero aún si lo hacemos, SoftIce no retornará ningún error. Estas areas son la pila de Windows de nivel0 y areas críticas en el VMM. Las pilas de nivel 0 de Windows normalmente se separan en segmentos de datos separados. Si se pone un breakpoint sobre una pila de nivel 0 o sobre un area crítica de la VMM, podrias colgar el sistema. Si la memoria que cubre el breakpoint de rango es movida o intercambiada, el breakpoint de rango la seguirá.

El siguiente ejemplo define un breakpoint en un rango de memoria. El breakpoint se activa si se realiza algún acceso de escritura a la memoria entre ES:0 y ES:1FFF

: BPR es:0 es:1fff w

marcador.gif (1024 bytes) BPRW: Establece un breakpoint en un programa de Windows o en un código de segmento.

Para Windows 3.1-> BPRW module-name | selector [verb]

Para Windows 9x -> BPRW module-name | selector [verb] [IF expression][DO "command1;command2;..."]

module-name: Cualquier nombre de un módulo válido de Windows que contenga segmentos de código.
selector:
Selector de16-bit válido en un programa de Windows.
verb:
Puede ser uno de los siguientes valores:

R Lectura (Read)
W Escritura (Write)
RW Lectura y escritura (Reads and Writes)
T Trazar hacia atras en ejecución
TW Trazar hacia atrás cuando se escribe a la memoria.

IF expression Conditional expression: la expresión debe evluarse como TRUE (diferente a 0) para que se active el breakpoint.
DO command Breakpoint action:
Una serie de comandos de SoftICE que se ejecutarán cuando el breakpoint se active.

El comando BPRW en un método corto para establecer breakpoints de rango en todos los segmentos de código de un programa de Windows, o en uno solo segmento.El comando BPRW actualmente establece el mismo tipo de breakpoint que el comando bullet.gif (296 bytes) BPR. Por eso, si introduces el comando bullet.gif (296 bytes) BL despues de BPRW, verás donde se establecieron breakpoints de rango separado para cubrir los segmentos especificados con el comando BPRW. Para obtener un selector de 16bit válido para un programa de Windows utilizaremos el comando HEAP.
Para borrar los breakpoints creados con el comando BPRW se precisa que estos sean borrados separadamente con el comando bullet.gif (296 bytes) BC.

En Windows 9x, debido a un cambio de la arquitectura del sistema, los BPRs no son soportados en código de nivel 0 (ring 0). Por ejemplo, no se pueden utilizar BPRs para capturar el código de un VXD. Cuando se establece un BPRW en una aplicación de 32bit o una DLL, se establece un solo breakpoint de rango comenzando por la imagen base del ejecutable y finalizando en la imagen base más el tamaño de la imagen.

El siguiente ejemplo establece un rango de post-trazado en todos los segmentos de código del Program Manager. Todas las instrucciones que ejecute el Program Manager son registradas al buffer de post-trazado y posteriormente las podremos examinar con los comandos bullet.gif (296 bytes) SHOW y bullet.gif (296 bytes) TRACE.

:BPRW progman t

marcador.gif (1024 bytes) BPX: Establece o borra un breakpoint de ejecución.

Para Windows 3.1-> BPX [ address] [c= count]
Para Windows 95 -> BPX [ address] [IF expression] [DO "command1;command2;..."]

address: Dirección lineal donde establecer el breakpoint.
c=
Contador de activación del breakpoint.
IF expression Conditional expression:
la expresión debe evluarse como TRUE (diferente a 0) para que se active el breakpoint.
DO command Breakpoint action:
Una serie de comandos de SoftICE que se ejecutarán cuando el breakpoint se active.

Utiliza el comando BPX para definir breakpoints que se activan cuando se ejecuta la instrucción que hubiera en la dirección especificada en address.
Se debe establecer la dirección justo en el primer byte de código (opcode) de la instrucción en la que deseamos establecer el breakpoint. Si no se especifica ninguna dirección y el cursor se encuentra en la ventana de código (WC) cuando se escribe el comando, se establecerá el breakpoint justo en la dirección donde se encuentre el cursor, si ya existía un breakpoint, este será eliminado.

Si el cursor se encuentra en la ventana de comandos, deberá especificarse la dirección. Si solo se especificara el offset, el valor actual de CS se usará como segmento para componer la dirección completa.

El comando BPX normalmente colocará una INT 3 en la dirección donde se establezca. Se utiliza este metodo en vez de asignar un registro de trazado, ya que así se pueden tener más breakpoints activos (hasta 256). Si se desea utilizar un registro de trazado (DR0,DR1,DR2,DR3), deberemos utilizar la misma sintaxis pero utilizando el comando BPM y especificando X como verbo. Realizando esto conseguiremos hacernos invisibles ante el posible código anti-debugging que pueda detectar breakpoints, esto es un pequeño truco que a veces resulta de gran utilidad.

Si se intenta  establecer un BPX en una dirección que se encuentre en memoria ROM, se utilizará automaticamente un registro de trazado en lugar de usar el metodo de la INT 3. Esto es así ya que la memoria ROM no puede ser modificada (Read Only Memory -> ROM).

Para Windows 9x, todos los BPX establecidos en el rango de memoria 400000 - 7FFFFFFF (aplicaciones WIN32) son direcciones sensibles al contexto. Esto es, solo se activan si el contexto donde estos se establecieron esta activo. Aún asi, si se establece un breakpoint en una DLL que existe en multiples contextos, este estará también activo en todos esos contextos.

Para Windows NT, cualquier breakpoint establecido en una dirección inferior a 80000000h (2 GB) es una dirección sensible al contexto.Esto es, solo se activará si el contexto donde estos se establecieron esta activo. Esto incluye aplicaciones WIN32,WIN16 y aplicaciones DOS V86. Asegurate de que estas en el contexto correcto antes de establecer el breakpoint.

Este ejemplo establece un BPX en la instrucción que se encuentra 10h bytes pasando el CS:EIP actual, si el registro EAX es diferente que 0 el breakpoint se activará  y ejecutara un comando que nos mostrará el contenido de la cadena apuntada por ds:esi

BPX eip+10 if eax!=0 do "d DS:ESI;"

marcador.gif (1024 bytes) C start-address L start-address-2: Compara dos bloques de datos.

start-address: Inicio del primer rango de memoria.
L:
longitud a comparar en bytes.
start-address-2:
Inicio del segundo rango de memoria a comparar.

Cuando un byte del primer rango no coincide con el del segundo, SoftIce mostrará ambos bytes y su dirección.

El siguitente ejemplo compara 10h bytes empezando desde las direcciónes DS:805FF000h y DS:806FF000h.

: C ds:805ff000 l 10 ds:806ff000

marcador.gif (1024 bytes) CLS: Borra el contenido de la ventana de comandos.
marcador.gif (1024 bytes) CODE: Se utiliza para activar/desactivar la visualización de los códigos de operanción de las instrucciones visualizadas en la ventana de código. Su uso es muy sencillo: CODE ON (activa la visualización) y CODE OFF (la activa).
marcador.gif (1024 bytes) CPU [-i] : Muestra todos los registros de la CPU (generales, de control, de trazado y de segmento). En NT si se especifica el parámetro -i y se dispone de un controlador avanzado de interrupciones (APIC), se mostrará la información de E/S relativa a este.

marcador.gif (1024 bytes) D: Muestra el contenido de la memoria.

Para Windows 3.1 -> D[size] [address]
Para Windows 9x y NT -> D[size] [address [l length]]

size: Especificador de tamaño.

B: Byte
W:
Palabra (Word)
D:
Doble Palabra (Double Word)
S:
Real corto (Short Real)
L:
real largo (Long Real)
T:
Real de 10 bytes.

address: Dirección de memoria que se desea visualizar.
l length: Muestra length bytes en la ventana de comandos.

SoftIce muestra el contenido de la memoria usando el formato especificado en el parámetro size, si no se especifica este parametro, SoftIce usa el último utilizado. Para los valores hexadecimales de byte, word y double word la representación ASCII es visualizada.

Para Windows 9x y NT, si se especifica el parámetro L seguido se una longitud, SoftIce mostrará el numero solicitado de bytes a la ventana de comandos independientemente del estado de la ventana de datos. SoftIce siempre muestra filas enteras, si el parametro length no es multiplo de una fila, SoftIce lo redondeará automaticamente.

marcador.gif (1024 bytes) DATA [window-number] : Muestra otra ventana de datos.

window-number: Número de ventana que se desea visualizar.Puede ser 0,1,2 o 3.

SoftIce soporta hasta 4 ventanas de datos. Cada ventana puede mostrar diferentes direcciones y/o formatos.Solo una ventana es visible cada vez, Especificando DATA sin ningún parámetro activará la siguiente ventana. Las ventanas estan numeradas de 0 a 3. Este número es visualizada a mano derecha de la ventana de datos. El comando DATA es muy útil cuando se asigna a una tecla de función.

El siguiente ejemplo activa la ventana número 3:

: DATA 3

marcador.gif (1024 bytes) E [size] [address [ data-list]]: Edita el contenido de la memoria.

size: Especificador de tamaño.

B: Byte
W:
Palabra (Word)
D:
Doble Palabra (Double Word)
S:
Real corto (Short Real)
L:
real largo (Long Real)
T:
Real de 10 bytes.

address: Dirección de memoria a editar.
data-list:
Lista de objetos de datos del tamaño especificado (bytes, words, double words,short reals, long reals, or 10-byte reals) o cadenas literales separadas por comas o especios. Las cadenas literales pueden ser delimitadas con comillas simples o dobles.

Si no se especifica una lista de datos, el cursor se moverá a la ventana de datos donde allí se podrá editar el contenido. Si se especifica la lista de datos, la memoria será modificada al instante. Si la ventana de datos no está visible, esta se hará visible automaticamente. Se soportan los modos de edición ASCII Y HEX. Para cambiar de modo de edición se pulsa la tecla TAB.

marcador.gif (1024 bytes) EC: Entra o sale de la ventana de código.

El comando EC coloca el cursor en la ventana de Código o en la ventana de Comandos.

    - Si el cursor está en la ventana de comandos, este se mueve a la de código.

    - Si el cursor está en la ventana de código, este se mueve a la de comandos.

    - Si la ventana de código no está visible cuando se introduce el comando, esta se hace visible.

Cuando el cursor está en la ventana de código, algunas opciones se vuelven activas y facilitan el trazado. Estas opciones son las siguientes.

    - Establecer breakpoints de tipo "apunta y dispara": Estos se establecen con el comando BPX. Si no se especifican parámetros (tecla por defecto F9), un breakpoint de jecución se establecera en la posición actual del cursor de la ventana de código.

    - Ir a la línea del cursor: Establece un breakpoint temporal en la línea donde se encuentra el cursor y comienza la ejecución tecleando HERE o pulsando F7.

    - Desplaza la ventana de código: Las teclas de  desplazamiento (UpArrow, DownArrow, PageUp and PageDn) son redefinidas mientras el cursor está en la ventana de código, permitiendo la navegación con estas por el listado del código.

Modo de sólo código fuente: En modo código fuente, puedes desplazar la ventana de código utilizando la tecla CTRL en combinación con una tecla de desplazamiento.

marcador.gif (1024 bytes) EXIT: Fuerza un salida del programa de DOS o Windows. Este comando no es soportado bajo Windows 9x o NT.

marcador.gif (1024 bytes) EXP [[module!][ partial-name]] | [!]: Muestra los simbolos exportados por las DLLs.

module!:   Muestra los simbolos exportadas por el módulo especificado.
partial-name:
Símbolo de exportación o los primeros caracteres del nombre del simbolo de exportación. El caracter ? puede ser usado como mascara.
! Display: 
Lista de modulos para los cuales SoftIce a cargado sus simbolos de exportación.

El siguiente ejemplo lista todos los simbolos exportados por la librería USER32.DLL que comienzen por "IS". El caracter ! es utilizado para diferenciar el nombre del módulo del calificador.

:EXP user32!is

marcador.gif (1024 bytes) F: Rellena un area de memoria con datos.

address: Dirección de inicio que se rellenará.
l length:
Longitud en bytes a rellenar.
data-list:
Lista de bytes o cadenas literales separadas por comas o espacios. Una cadena literal puede estar delimitada con comillas dobles o simples.

La memoria se rellena con series de bytes o caracteres en la lista de datos (data-list). Se rellena empezando por la dirección especificada en address y continua hasta alcanzar la longitud especificada. Si la longitud de data-list es inferior que la longitud especificada, el data-list es repetido tantas veces como sea necesario.

El siguiente ejemplo rellena memoria empezando por la dirección DS:8000h para un longitud de 100h bytes con la cadena 'Test'. La cadena 'Test' es repetida tantas veces como haga falta hasta completar la longitud.

: F ds:8000 l 100 'test'

marcador.gif (1024 bytes) FAULTS [on | off]: Activa/desactiva la capturación de fallos.

marcador.gif (1024 bytes) G [=start-address] [ break-address]: Ir a una dirección de código.

=start-address: Cualquier expresión que equivalga a una dirección aceptable.
break-address: Cualquier expresión que equivalga a una dirección aceptable.

El comando G sale de SoftIce. Si se especifica break-address, se establecera un breakpoint de una sola ejecución a esa dirección. La ejecución comienza en el CS:EIP actual a no ser que se especifique una dirección de inicio (start-address). La ejecución continua hasta que la dirección de ruptura (breakpoint-address) es alcanzada, se pulse la tecla de activación de SoftIce, o se produzca un breakpoint que ya estuviera establecido. Cuando SoftIce se activara por cualquier motivo, el breakpoint de una sola ejecución es eliminado.

La dirección de ruptura (breakpoint-address) debe ser el primer byte de un código de instrucción. El comando G sin parametros se comporta igual que el comando X.Si la ventana de registros está visible cuando SiftIce se activa, todos los registros que hayan sido alterados desde el último comando G son visualizados en negrita.

Para Windows 3.1, el breakpoint de una sola ejecución utiliza una INT 3.
Para Windows 9x y NT -> el breakpoint de una sola ejecución utiliza un registro de trazado. Si no hay registros de trazado libres, se usará una INT 3.

marcador.gif (1024 bytes) GDT [selector]: Muestra la tabla global de descriptores, si se especifica selector, se mostrará información  de ese selector.

marcador.gif (1024 bytes) H: Muestra información de ayuda.

Para Windows 3.1 -> H [command | expression]
Para Windows 9x y NT ->
H [command]

Bajo Windows 3.1, el parámetro especificado determina cuando se visualiza la ayuda o se evalua una expresión. si se especifica un comando, H muestra información detallada sobre este, incluyendo la sintaxis del comando y un ejemplo. Si se especifica un expresión, la expresión es evaluada, y el resultado es visualizado en hexadecimal, decimal, decimal con signo (solo si <0), y ASCII.

Bajo Windows 9x y NT, el comando H muestra ayuda sobre los comandos de SoftIce. Ver el comando bullet.gif (296 bytes) ? para evaluar expresiones. Para mostrar ayuda general sobre todos los comandos de SoftIce introduce el comando H sin parámetros. Para ver información detallada sobre comandos especificos, utiliza el comando H seguido del nombre del comando.

marcador.gif (1024 bytes) HBOOT: Hace un reset total del sistema, equivale ha hacer un Ctrl+Alt+Del.

marcador.gif (1024 bytes) HWND: (Windows 3.1 y 9x) : Muestra información sobre el manejador de la ventana.

Para Windows 3.1 -> HWND [ level] [ task-name]
Para Windows 9x ->
HWND [-x][hwnd | [[ level][ process-name]]

level: Nivel de jerarquía de Windows. 0 es el nivel más superior, 1 es el siguiente y así con los siguientes. Los niveles de las ventanas representan una relación de padre. Por ejemplo, una ventana en nivel 1 tiene una ventana padre en nivel 0.
task-name:
Cualquier tarea Windows que haya sido cargada. Estos nombres los podemos averiguar mediante el uso del comando bullet.gif (296 bytes) TASK.
-x:
Muestra información extendida sobre la ventana (dimensiones, clase, propietario, padre, hijos, y muchas más cosas).
hwnd:
Manejador de ventana de Windows.
process-name:
Nombre de cualquier proceso cargado.

Usando un manejador de ventana espececífico (hwnd) como parámetro mostrará solamente la información relativa a la ventana perteneciente a ese manejador. Si se especifica un manejador de ventana, no es necesario especificar los parámetros opcionales de nivel y proceso (level y process-name).

Por cada manejador de ventana, la siguiente información es mostrada:

Class Name: Nombre de la clase o átomo de la clase a la que esta ventana pertenece.
Window Procedure:
Dirección del proceso que controla esta ventana. Este parámetro tiene bastante importancia si pretendemos eliminar ventanas de alguna aplicación.

marcador.gif (1024 bytes) HWND (Windows NT) : Muestra información sobre el manejador de las ventanas.

Para Windows NT -> HWND [-x][-c] [ hwnd-type | desktop-type | process-type |thread-type | module-type | class-name]

-x: Muestra información extendida sobre la ventana (dimensiones, clase, propietario, padre, hijos, y muchas más cosas).
-c: Hijos. Fuerza la visualización de la jerarquía de las ventanas cuando se busca por tipo de thread (thread-type), tipo de módulo (module type) o nombre de clase (class-name).
hwnd-type:
Manejador o puntero a una estructura de ventana.
desktop-type:
Manejador de escritorio o puntero de escritorio a una estructura de ventana (solo NT 3.51).
process-type, thread-type or module-type:
Tipo de ventana propietaria. Un valor que SoftIce puede interpretar como ser de un tipo específico como el nombre del proceso, identificador del Thread, o la imagen base del módulo.
class name:
Nombre de una clase de ventana registrada.

Cuando se especifica la opción extendida, o un tipo de propietario (process-type, thread-type, o module-type) como parámetro, el comando HWND no enumerará automáticamente las ventanas hijas. Especificando la opción (-c) se fuerza la enumeración, independientemente del critério de busqueda especificado.

Por cada manejador de ventana, la siguiente información es mostrada:

Handle: Manejador. Cada manejador de ventana se indenta para mostrar sus ventanas hijas y la relación con el resto de ventanas.
Class Name: Nombre de la clase o átomo de la clase a la que esta ventana pertenece.
WinProc:
Dirección del proceso que controla esta ventana. Este parámetro tiene bastante importancia si pretendemos eliminar ventanas de alguna aplicación.
TID: Identificador del thread propietario de la ventana.
Module: Nombre del módulo propietario (si está disponible). Si el nombre del módulo es desconocido, el manejador del módulo serña visualizado como una dirección lineal de 32bits o un selector de 16bits selector:desplazamieno, dependiemdo del tipo de módulo.

marcador.gif (1024 bytes) I [size] port :Lee un valor de un puerto de E/S.

size: B, para byte, W para word y D para DWORD.
port:
Dirección del puerto de E/S.

Se usa el comando I para leer y mostrar valores desde un puerto hardware. La entrada puede ser realizada como un byte, una palabra o una doble palabra.

Con excepción de los registros de interrupción enmascarables, el comando I realiza una instrucción de E/S, visualizando el valor actual del puerto hardware. Aún así, en el caso de puertos virtualizados, el dato retornado por el comando I puede no coincidir con el que la aplicación vea.

El único puerto al que softIce no puede acceder es el de registro de interrupciones enmascarables (Puerto 21h y A!h). Para estos puertos SoftIce muestra el valor que tenian cuando se activo este.

El siguiente ejemplo lee un byte del puerto 378h (normalmente LPT1);

: IB 378

marcador.gif (1024 bytes) I1HERE [ON | OFF] : Activar SofIce cuando se ejecute una INT 1. Utiliza el comando I1HERE para especificar que cualquier interrupción 1 activará la pantalla del SoftIce. Esta característica es de gran utilidad para parar los programas en localidades especificas. Cuando I1HERE esta en activa, SoftIce comprueba si realmente se trata de una interrupción 1 en el código antes de activarse. Si no es una INT 1, SoftIce no se activará.
Para hacer uso de esta característica, coloca una INT 1 en el código que sigue inmediatamente antes de la localidad donde quieres parar el programa.Cuando ocurra la INT 1, se activará SoftIce. Después de esto, el EIP actual apuntará a la instrucción INT 1.

El VMM, Windows memory management VxD, ejecuta instrucciones INT 1 antes de ciertas salidas fatales. Si se tiene activada I1HERE, se podrán capturar estas situaciones. La INT 1 es generada por el VMM y suele ser causada por un fallo de página no válida con los registros tal y como sigue:

EAX: Dirección donde se produjo el fallo.
ESI:
Apunta a un mensaje en ASCII.
EBP:
apunta a un  CRS (Client Register Structure tal y como se define en el fichero include del  DDK VMM.INC).

marcador.gif (1024 bytes) I3HERE [ON | OFF | DRV] : Activar SoftIce cuando se ejecute una INT 3.

DRV: Activar la captura de la INT 3 por encima de los 2GB. Esto sirve para poder capturar la llamada de un driver a la función DebugBreak();

Usar el comando I3HERE para especificar que cualquier interrupción 3 activará el SoftIce. Esta característica es de gran utilidad para parar tu programa en un localidad especifica. Para hacer uso de esta función, establece I3HERE en ON, y coloca una INT 3 en tu código inmediatamente antes de la localidad donde quieres que se pare. Cuando suceda la INT 3, SoftIce se activará. En este punto el EIP actual apunta a la instrucción INT 3.

marcador.gif (1024 bytes) IDT [interrupt-number]: Muestra la tabla de descriptores de interrupción, si se especifica el número de interrupción, se mostrará información  de esa interrupción.

marcador.gif (1024 bytes) LDT [selector]: Muestra la tabla local de descriptores, si se especifica selector, se mostrará información  de ese selector.

marcador.gif (1024 bytes) LINES [25 | 43 | 50]: Cambia el número de líneas que se visualizan en la ventana del SoftIce al número especificado 25, 43 o 50, bajo Windows 9x o NT con el driver de video universal el número de líneas puede ser cualquiera que quepa en la pantalla.

marcador.gif (1024 bytes) M source-address l length dest-address: Mueve datos de una dirección a otra.

source-address: Inicio de la dirección fuente.
length:
Longitud en bytes.
dest-address:
Inicio de la dirección de destino.

El número especificado de bytes es movido desde la dirección de inicio a la dirección de destino. El siguiente ejemplo mueve 2000h bytes (8KB) de memória desde la posición apuntada por DS:1000h hasta ES:5000h.

M ds:1000 l 2000 es:5000

marcador.gif (1024 bytes) MACRO [ macro-name] | [*] | [= " macro body"]: Define un nuevo comando que es un superconjunto de comandos de SoftIce.

macro-name: No sensible a mayúsculas, un nombre de 3 a 8 caracteres para la macro que va a ser definida, o el nombre de una macro ya existente.
macro-body:
Cadena entrecomillada que contiene una lista de comandos de SoftIce y sus parametros, cada comando separado por punto y coma (;).
* Borra una o todas las macros definidas.
=
Define o redefine una macro.

El comando MACRO es utilizado para definir nuevos comandos de macro que son superconjuntos de comandos de SoftIce ya existentes. Las macros definidas pueden ser ejecutadas directamente desde la línea de comandos de SoftIce. También se utiliza para listar, editar o borrar  macros individuales. Las macros tienen que ver directamente con los breakpoints, ya que las acciones ejecutadas por estos son simples macros que no poseen nombre, y pueden ser ejecutadas directamente por el motor de breakpoints del SoftIce.

Si no se especifica ninguna opción, una lista de todas las macros definidas será mostrada, o si se especifica el nombre de una macro, la macro será insertada en el buffer de comandos para que pueda ser editada. Cuando se define o redefine una macro, la siguiente forma del comando macro es utilizada.

MACRO macro-name = " macro-body"

El nombre de la macro puede tener una longitud de 3 a 8 carácteres, y puede contener cualquier carácter alfanumérico y guiones bajos (_). Si el nombre de la macro ya existe, el comando MACRO la redefinirá. El nombre de la macro no puede ser un duplicado de un comando de SoftIce. El nombre de la macro debe estar seguida   por el signo "=", el cual debe ser seguido por la cadena entrecomillada que define el cuerpo de la macro.

El cuerpo de la macro debe estar entrecomillado al inicio y al fin ("). El cuerpo de la macro se compone de una colección de comandos de SoftIce ya existentes, o macros ya definidas, separados/as por punto y coma (;). Cada comando puede contener los parametros literales necesarios,  o pueden usar la forma %<parametro#>, donde parámetro debe estar entre 1 y 8. Cuando la macro es ejecutada desde la linea de comandos, cualquier referencia a un parámetro será expandida en el cuerpo de la macro desde los parametros especificados cuando el comando se ejecutó. Si se precisa añadir el simbolo literal (") o el simbolo (%) dentro del cuerpo de  la macro, se deberá preceder el caracter con el caracter barra invertida (\). Debido a que la barra invertida se usa para secuencias de escape, para especificar una barra invertida como literal, se usarán bos barras invertidas (\\). El comando final dentro de la macro no precisa ser finalizado con punto y coma.

Puedes definir macros en el Symbol Loader de SoftIce usando la misma sintáxis descrita aquí. Cuando cargues el SoftIce, cada definición de macro es creada y disponible para su uso. SoftIce muestra un mensaje por cada macro definida para recordarte su presencia. Debido a que las macros consumen memória, puedes establecer el máximo número de macros con nombre y sin nombre (las ejecutadas por los breakpoints) que pueden ser definidas durante una sesión de SoftIce. El valor por defecto es 32 que es también el valor mínimo. El valor máximo es 256.Lo siguiente son ejemplos de macros válidas.

XWHAT = "WHAT EAX;WHAT EBX;WHAT ECX; WHAT EDX; WHAT ESI; WHAT EDI"
OOPS = "I3HERE OFF;GENINT 3"
1shot = "bpx eip do \"bc bpindex \""
pbsz = "? hibyte(hiword(*(%1-8))) << 5"
tag = "? *(%1-4)"

Las macros son una de las características més destacables del SoftIce, podemos combinarlas con breakpoints e incluso hacer que acepten parámetros. Una macro bien diseñada combinada con un breakpoint bien colocado puede ahorrarnos horas de trazado, recuerda usar macros cuando debas realizar tareas repetitivas o cuando uses comandos muy largos.

marcador.gif (1024 bytes) MOD [ partial-name]: Muestra la lista de módulos de Windows. Para Windows 9x y NT ver más abajo bullet.gif (296 bytes) MOD.

partial-name: Prefijo del nombre del módulo de Windows.

Este comando muestra la lista de módulos de Windows en la ventana de comandos. Un módulo es una aplicación de Windows o una DLL. Todos los módulos de 16bit serán los primeros en mostrarse, seguidos de los de 32bit. Si se especifica un nombre parcial (partial-name), sólo los módulos que comienzen con el nombre parcial serán mostrados.

Por cada módulo cargado se muestra la siguiente información:

module handle: Manejador de 16bit que Windows asigna a cada módulo.Es un selector de 16bit de la base de registros del módulo que es similar en formato a la cabezera del EXE del fichero del módulo.
pe-header:
Selector:offset de la cabezera del fichero PE del módulo. Para módulos de 32bit sólo se mostrará un valor.
module name:
El nombre especificado en el fichero .DEF usando la palabra clave 'NAME' o 'LIBRARY'.
file name:
camino completo y nombre del fichero ejecutable del módulo.

marcador.gif (1024 bytes) MOD [-u | -s] | [ partial-name*]: Muestra la lista de módulos de Windows. Para Windows 3.1 ver más arriba bullet.gif (296 bytes) MOD.

-u: Muestra sólo los módulos en el espacio de usuario.
-s:
Muestra sólo módulos en el espacio de sistema.
partial-name:
Prefijo del nombre del módulo de Windows.

Este comando muestra la lista de módulos de Windows en la ventana de comandos.Si se especifica un nombre parcial (partial-name), sólo los módulos que comienzen con el nombre parcial serán mostrados. La lista se muestra en el siguiente orden.

16-bit modules
32-bit driver modules (sólo Windows NT)
32-bit application modules

Para Windows 95, la lista de módulos es global. Un módulo es una aplicación de Windows o una DLL. Todos los módulos tienen un valor hMod.

Para Windows NT, el comando MOD es especifico para cada proceso. Serán visualizados todos los módulos que sean visibles desde el proceso actual. Esto incluye módulos de 16bit, todos los módulos de 32bits, y todos los módulos de drivers. Esto significa que si se desean ver módulos especificos, se debe cambiar a la dirección de contexto apropiada antes de usar el comando MOD. Se puede distinguir entre módulos de aplicación y módulos de drivers, ya que las aplicaciones tienen direcciones inferiores a los 2GB (80000000h). Los módulos de 16 bits son los únicos que tienen un valor hMod.

Por cada módulo cargado se muestra la siguiente información:

module handle: Manejador de 16bit que Windows asigna a cada módulo.Es un selector de 16bit de la base de registros del módulo que es similar en formato a la cabezera del EXE del fichero del módulo.
base:
Dirección lineal base del ejecutable. Es utilizada también como el manejador del módulo parra ejecutables de 32bits. sólo se mostrará este valor para m´ódulos de 32bits.
pe-header:
Selector:offset de la cabezera del fichero PE del módulo. Para módulos de 32bit sólo se mostrará un valor.
module name:
El nombre especificado en el fichero .DEF usando la palabra clave 'NAME' o 'LIBRARY'.
file name:
camino completo y nombre del fichero ejecutable del módulo.

marcador.gif (1024 bytes) O [size] port: Escribe un valor a un puerto de E/S.

size: B, para byte, W para word y D para DWORD.
port:
Dirección del puerto de E/S.

Los comandos de escritura a puertos se utilizan para escribir un valor a un puerto hardware. La escritura puede ser de tipo byte, palabra (word), o doble palabra (dword). Si no se especifica un tamaño (size) el valor por defecto es B. Todas las salidas son enviadas inmediatamente al hardware con la excepción de los registros de para enmascarar interrupciónes (Puerto 21h y A1h). Estos no tendrán efecto hasta que no se salga de la ventana de SoftIce.

marcador.gif (1024 bytes) P [RET]: Ejecuta una "paso" (instrucción) de programa.

RET: Retorna.Traza hasta que se encuentre una instrucción de retorno o una instrucción de retorno de interrupción.

El comando P ejecuta un paso lógico de un programa. En modo ensamblador, una instrucción en el CS:EIP actual es ejecutada a menos que se trate de una llamada (call), una interrupción, un bucle o una instrucción de cadena (REP). En estos casos, la rutina entera o una iteracción es completada antes de retornar el control a SoftIce. Si se especifica RET, SoftIce trazará hasta que se encuentre un retorno o un retorno de interrupción. Esta función sirve tanto en código de 16bit o 32bit y también funciona en código de nivel 0. El comando P usa el flag de un solo paso parar muchas instrucciones. Para llamadas (call), interrupciones, bucles, o instrucciones de repetición de cadena, el comando P usa un breakpoint de tipo INT 3 de una sola ejecución.

En modo código fuente se ejecuta un comando de código. Si el código fuente llama a otro procedimiento, no se seguirá la llamada . El procedimiento es tratado como un solo comando. Si la ventana de registros está visible cuando SoftIce se activa, todos los registros que hayan sido alterados desde el comando P, se mostrarán con el atributo de video negrita. Para instrucciones de llamada, los registros iluminados muestran que registros fueran utilizados por la rutina que se llamó. En un procedimiento largo, puede haber un retardo notable cuando se ejecute el comando P RET, porque SoftIce estará trazando una a una cada instrucción.

Para Windows 9x y NT, el comando P, por defecto, es especifico del thread. Si el EIP actual está ejecutando el thread X, SoftIce no aparecerá hasta que el paso del programa suceda en el thread X. Para cambiar este comportamiento, se puede usar el comando SET con la palabra clave THREADP o desactivar el trazado especifico de threads en las preferencias de inicialización.

marcador.gif (1024 bytes) PAGE [address [L length]]: Ejecuta una "paso" (instrucción) de programa.

address: Dirección virtual, segmento:desplazamiento. o selector:desplazamiento, del cual se desea obtener información sobre la pagina. La salida incluye la dirección virtual y física.
length:
Número de páginas a visualizar.

El comando PAGE puede ser usado para listar el contenido del directorio de la página actual o el contenido de tablas de páginas individuales. Los directorios con múltiples páginas solo son usados por Windows NT.
En la arquitectura de un x86, una directorio de página contiene 1024 entradas de 4 bytes cada una, donde una entrada especifica la localización y los atributos de una tabla de página que es usada para mapear un rango de memoria en referencia a la posición de la entrada en el directorio (Esto rangos son mostrados en la parte de más a la derecha de la salida del comando PAGE).

Cada entrada representa la localización y atributos de una página específica dentro del rango de memoria mapeado por la tabla de páginas. El tamaño de una de estas páginas es de 4Kb en los procesadores x86, de lo que se deduce que una tabla de páginas mapea 4MB de memoria (4KB/page * 1024 entradas), y el directorio de páginas mapea hasta 4GB de memoria (4MB/tabla de páginas * 1024 entradas). NT 4.0 usa las caracteristicas de páginas de 4MB de los procesadores Pentium/Pentium Pro. NTOSKRNL, HAL, y todos los dirivers de arranque son mapeados en una página de 4MB que empieza en 2GB (800000000h). Cuando se especifica el parámetro dirección (address), se muestra información sobre la entrada de la tabla de pagina que mapea la dirección pasada. Esta información incluye lo siguiente:

- La dirección lineal virtual del inicio de la página mapeada por la entrada.
- La dirección física que corresponde al inicio de la página mapeada por la entrada.
- Los atributos de la entrada de la tabla de la página. Esta información correspode directamente a los atributos definidos por el procesador. Los atributos de página son representados por bits que indican la validez de la entrada, si la página esta "sucia" o se ha accedido ha ella, si es una página de usuario o de supervisor. Solo los atributos activos son mostrados por SoftIce.
- El tipo de página. Esta información es interpretada desde el campo de un bit definido por Windows en la entrada de la tabla de páginas y los tipos mostrados por SoftIce corresponden a las definiciones de Windows.

Utiliza el parámetro longitud (length) con el parámetro dirección (address) para listar información sobre un rango de tablas de páginas consecutivas. Debe destacarse que el comando PAGE no cruzará límites de tablas de página cuando se liste un rango. Esto significa que, si se muestran menos páginas de las que se especificaron, se deberá usar un segundo comando PAGE para listar páginas empezando desde donde terminó la primera lista.

La siguiente información es mostrada por el comando PAGE:

physical address: Si un directorio de página está siendo mostrado entonces esta es la dirección física de la tabla de página a la cual se refiere la entrada de la página del directorio. Cada entrada de directorio de página hace referencia una tabla de páginas que controla 4MB de memoria. Si el parámetro dirección (address) se introduce de manera que se muestren páginas especificas, entonces este valor es la dirección física que corresponde al inicio de una página.

linear address: Solo para Windows 3.1 y Windows 95: Si el directorio de página está siendo visualizado entonces esta es la dirección virtual de una tabla de páginas. Esta es la dirección que se debería usar en SoftIce para mostrar el contenido de la memoria con el comando bullet.gif (296 bytes) D. Si se están mostrando páginas especificas, esta es la dirección virtual de una página. si se introdujo una longitud entonces esta es la dirección virtual  del inicio de cada página.

attribute: Este es el atributo del directorio o de la tabla de páginas. Los atributos válidos son como siguen:

Windows 3.1, Windows 95, y NT Solo Windows NTy
P Presente S Supervisor
D Sucia RW Lectura/Escritura
A Accedida 4M 4 MB page (sólo NT 4.0)
U Usuario  
R Sólo lectura  
NP No esta presente  

marcador.gif (1024 bytes) R: Modifica el contenido de los registros.

Para Windows 3.1 -> R [ register name [[=]value]]
Para Windows 9x y NT -> R [ -d | register name | registername [[=]value]]

register name: Cualquiera de los siguientes:AL,AH,AX,EAX,BL,BH,BX,EBX,CL,CH,CX,ECX,DL,DH,DX,EDX,DI,EDI,SI,ESI,BP,EBP,SP,ESP,IP,EIP,FL,DS,GS,CS,ES,SS-
value: Si el nombre del registro es cualquiera menos FL (flags), el valor es una expresión o un valor hexadecimal. If el nombre del registro es FL, valor es una serie de uno o más de los siguientes símbolos, precedidos opcionalmente de un símbolo más o menos.

O Overflow (flag de desbordamiento)
D Direction (flag de dirección)
I Interrupt flag (flag de interrupción)
S sign (flag de signo)
Z zero flag (flag de cero)
A auxiliary carry flag (flag auxiliar de acarreo)
P parity flag (flag de paridad)
C carry flag (flag de acarreo)
-d muestra los registros en la ventana de comandos.

Ejemplos:

> R ah=5

Pone el registro AH igual a 5

> R FL=ozp

Activa los flags O Z y P.

> R FL

Mueve el cursor a la ventana de registro y lo coloca bajo el primer flag.

> R FL=O+A-C

Activa los flags O y A y desactiva el flag C.

marcador.gif (1024 bytes) RS: Restaura la pantalla del programa. Este comando es de gran utilidad cuando se estan trazando programas que actualizan la pantalla frecuentemente y la pantalla de SoftIce puede verse afectada (raramente sucede).

marcador.gif (1024 bytes) S: Busca datos en la memoria.

Para Windows 3.1 -> S [address L length data-list]
Para Windows 9x y NT ->
S [-cu] [address L length data-list]

address: Dirección donde empezar a buscar.
length:
Longitud en bytes.
data-list:
Lista de bytes o cadenas entrecomilladas separadas/os por comas o espacios. Las cadenas pueden ir entre comillas simples o dobles.
-c:
Busqueda sensible a las mayúsculas.
-u:
Buscar cadena en formato Unicode.

Este comando busca en la memoria los datos que coincidan con los especificados en data-list.La busqueda comienza en la dirección especificada en address y continua hasta la longitud especificada. Cuando se encuentra una coincidencia se muestra en la ventana de datos y el siguiente mensaje es mostrado en la ventana de comandos.

PATTERN FOUND AT location

Ejemplo:

> s 30:0 L ffffffff 'string'

Esto busca la cadena 'string' por todo el espacio virtual de memória de 4GB.

 marcador.gif (1024 bytes) SHOW [B | start] [l length]: Muestra las instrucciones que se encuentren en el buffer de trazado.

B: Muestra instrucciones empezando por la instrucción mas antigua en el buffer.
start:
Número hexadecimal que especifica un índice dentro del buffer desde el cual se empezará desensamblar. Un índice de 1 corresponde a la instrucción más nueva del buffer.
length:
Número de instrucciones a visualizar.

Utiliza el comando SHOW para mostrar instrucciones del buffer de trazado. Si hay código fuente para las instrucciones, se visualizará en modo mezclado; si no, sólo el se muestra el código. Solo se puede utilizar el comando SHOW si existen instrucciones en el buffer de trazado. Para llenar el buffer de trazado, utiliza el comando bullet.gif (296 bytes) BPR con los parámetros T o TW para especificar un rango de memoria.

El comando SHOW muestra todas las instrucciones y código fuente en la ventana de Comandos. Cada instrucción es precedida por su índice dentro del buffer de trazado. La instrucción cuyo índice sea 1 es la instrucción más reciente. Una vez se ha introducido el comando SHOW, se pueden utilizar las flechas Arriba y Abajo   para desplazarse através de los contenidos del buffer. Para salir del comando SHOW pulsa la tecla ESC. si no se especifica ningún parámetro para SHOW, se mostrarán todas las instrucciones en el buffer.

marcador.gif (1024 bytes) TASK: Visualiza la lista de tareas de Windows. El comando TASK se utiliza para mostrar información relativa a las tareas que se están ejecutando. La tarea activa, es mostrada con un asterisco después de su nombre. Este comando es de utilidad cuando un fallo de protección general (GP fault) ocurre, ya que se indica el programa que causó el fallo, tambien es de utilidad para obtener los nombres de las tareas. Para Windows NT, este comando es específico de cada proceso y solo muestra las tareas de 16bits que se estan ejecutando en NT. Para ver información relativa a otros procesos se utiliza el comando bullet.gif (296 bytes) PROC.

La salida que produce este comando es la siguiente:

Task Name: Nombre de la tarea.
SS:SP:
Dirección de la pila de la tarea cuando esta abandono el control por última vez.
StackTop:
Desplazamiento de la parte superior de la pila.
StackBot:
Desplazamiento de la parte baja de la pila.
StackLow:
El valor mínimo que SP ha tenido cuando hubiera habido algún cambio de contexto lehano a la tarea.
TaskDB:
Selector para el segmento de datos base de la tarea.
hQueue:
Manejador de cola para la tarea. Esto es simplemente el selector para la cola.
Events:
Número de eventos excelentes en la cola.

Para Windows 3.1 y Windows 9x, el comando TASK funciona para aplicaciones de 16 y 32bits, sin embargo, los siguientes campos varian para aplicaciones de 32bits:

StackBot: La dirección legal más alta de la pila mostrada como un desplazamiento lineal de 32bits.
StackTop:
La dirección legal más baja de la pila mostrada como un desplazamiento lineal de 32bits.
StackLow:
Este campo no se utiliza.
SS:SP: 
Contiene el selector de 16bits del desplazamiento de la pila. Si examinas la dirección base del selector de 16bits, podrás ver que este apunta a la misma memoria que apunta el puntero lineal de 32bits usado con el selector de los datos de 32bits.

marcador.gif (1024 bytes) TRACE [b | off | start]: Entra o sale del modo de simulación de trazado.

b: Comienza el trazado desde la instrucción más antigua en el buffer de trazado.
off:
Sale del modo de simulación de trazado.
start:
Número hexadecimal especificando un índice dentro del buffer de trazado desde el cual se iniciará el trazado. Un índice igual a 1 corresponde a la instrucción más reciente que se introdujo en el buffer.

Utiliza el comando TRACE para salir, entrar y visualizar el estado actual del modo de simulación de trazado. El comando TRACE sin parámetros muestra el estado actual del modo de simulación de trazado.

Solo se puede utilizar el modo de simulación de trazado si el buffer de trazado contiene instrucciones. Para llenar este buffer, utiliza el comando bullet.gif (296 bytes) BPR con los parámetros T o TW para especificar un rango de memoria.

Cuando el modo de trazado de simulación está activado, la línea de ayuda inferior del SoftIce señala el modo de trazado y muestra el índice de la instrucción actual.

Utiliza los comandos  XT, XP, y XG para trazar através del buffer de trazado. Cuando se esté trazando dentro del buffer de trazado, el único registro que cambia es el registro EIP debido a que los rangos de trazado anteriores NO guardan el contenido de todos los registros. Se pueden utilizar todos los comandos de trazado excepto los siguientes:  X, T, G, P, HERE, y XRSET.

marcador.gif (1024 bytes) WMSG: Visualiza el nombre y el número de los mensajes de Windows especificados.

Para Windows 3.1 -> WMSG [partial-name]

Para Windows 9x y NT -> WMSG [ partial-name| msg-number]

partial-name: Nombre del mensaje de Windows o los primeros caracteres de este. Si se encuentra más de una coincidencia en los carácteres entonces se mostrarán todos los mensajes que comienzen con los carácteres especificados.

msg-number: Número hexadecimal que representa el mensaje. Solo el mensaje que coincide con el número especificado es mostrado.

Esta orden es de utilidad para obtener los valores numéricos que representan los mensajes de Windows, para así poder utilizarlos en combinación con el comando bullet.gif (296 bytes) BMSG.

El siguiente ejemplo muestra todos los mensajes de Windows que empiezen por WM_GET:

: WMSG wm_get*

Y esta sería su salida por pantalla:

000D WM_GETTEXT
000E WM_GETTEXTLENGTH
0024 WM_GETMINMAXINFO
0031 WM_GETFONT
0087 WM_GETDLGCODE

 


Pues creo que con esto basta para que le perdais el miedo al mejor debugger jamás programado, ya se que faltan comandos pero vuelvo a repetir que con estos hay más que suficiente para afrontar casi todas las tareas que nos puedan surgir. Mi recomendación ahora es que sigais practicando con tutoriales más concretos sobre aplicaciones concretas para acabar de perderle el miedo a este genial debugger.


You are inside Reversed Minds pages.

por Mr. Silver / WKT!