Si estás interesado en la industria del hacking, es probable que te hayas encontrado con JTAG.
Es probable que lo hayas utilizado en el pasado para reprogramar algún hardware.
Pero, ¿cómo funciona exactamente JTAG?
Depuración de Hardware para Ingenieros de Reversa
Vamos a echar un vistazo a JTAG desde el punto de vista de la ingeniería inversa.
JTAG es una interfaz de hardware que fue desarrollada con la intención de asistir a desarrolladores y testers con la depuración a nivel bajo.
JTAG fue desarrollado con la intención original de probar circuitos integrados y muestrear pines de IO en un objetivo que está siendo probado.
Este tipo de interfaz de depuración permite a cualquier ingeniero probar conexiones en PCBs sin necesidad de sondear el pin físico.
JTAG utiliza dos registros.
El primero es el registro de instrucciones.
El segundo es el registro de datos.
Para aprovechar estos registros, se deben ingresar los estados adecuados en la máquina de estados utilizando ciertas señales de interfaz.
Estos son:
- TMS – el pin utilizado para navegar y controlar la máquina de estados JTAG.
- TDI – el pin de entrada que se utiliza para escribir datos en el objetivo.
- TDO – el pin de salida que se utiliza para leer datos del objetivo.
- TCK – que se utiliza para determinar cuándo se muestrean los datos para todas las entradas y todas las salidas.
- TRST- un pin que puede usarse para reiniciar la máquina de estados al estado inicial, aunque este es completamente opcional.
La máquina de estados puede ser navegada usando las líneas TMS y TCK, específicamente, cuando los datos son escritos o leídos por TDI o TDO.
TMS se muestrea en TCK, lo que significa que la línea TMS debe ser afirmada antes de que TCK pueda ser alternado para navegar a través de la máquina de estados.
Los datos finalmente se desplazan al registro de instrucciones conocido como IR o al registro de datos conocido como DR, lo cual depende del estado de la máquina de estados JTAG.
Una vez que una operación se completa exitosamente, los datos resultantes pueden ser desplazados fuera de DR entrando en el estado “Shift-DR”.
Cuando todo esto ocurre, todos los fabricantes pueden implementar las características que deseen sobre JTAG.
El estándar JTAG puede tratar IR y DR como registros de desplazamiento y, como tal, permitir que múltiples objetivos se encadenen en serie.
En pocas palabras, JTAG puede definir una máquina de estados que se navega a través de al menos 4 señales, y con ella, los usuarios finales pueden escribir y leer desde dos registros de desplazamiento conocidos como IR y DR.
Los Registros
Ahora volveremos a los dos registros que JTAG utiliza, el registro de instrucciones y el registro de datos.
Cuando se trata del registro de instrucciones, se utiliza para determinar qué función está a punto de llevar a cabo el controlador JTAG como una escritura de memoria o lectura de memoria.
Cuando se trata del registro de datos, se utiliza como una entrada adicional para el registro de instrucciones, lo que permite al usuario proporcionar una dirección para leer o escribir.
Aquí están los pasos que deben seguirse para escribir un registro con éxito:
- Ingresar al estado de reinicio de lógica de prueba o LTR – se hace afirmando la línea TMS y ciclando CLK un total de 5 veces.
- Ingresar al Estado de Selección de IR.
- Ingresar al Estado de Captura de IR.
- Ingresar al Desplazamiento de IR, donde los datos pueden cargarse en el IR desde TDI.
- Ingresar al Estado de Salida de IR.
- Ingresar al Estado de Actualización de IR – la etapa que bloquea el valor en el IR.
Después de los siguientes pasos, la operación se realizará y el resultado se cargará en el registro de datos para ser desplazado.
Tenga en cuenta que muchas instrucciones requieren que un registro de datos se complete antes de operar correctamente.
Una vez que el registro de datos está escrito y actualizado, la operación puede realizarse y el resultado puede desplazarse fuera del registro de datos en su totalidad.
También hay ciertos registros que no requieren que se cargue el DR.
Cuando se trata del estándar JTAG, define los siguientes registros de instrucción.
BYPASS – una instrucción que conecta TDI y TDO, y cuando está en el estado Shift DR, los datos pueden transferirse de TDI a TDO con un retraso de un ciclo TCK, y se carga 0 en el registro de datos durante el estado Capture DR.
Esto se utiliza para determinar cuántos dispositivos están juntos en una cadena de escaneo.
IDCODE – una instrucción que, cuando se carga, el Registro de Código de Identificación del Dispositivo se selecciona como el camino serial entre TDI y TDO, y en el estado Capture-DR, el código de identificación de 32 bits del dispositivo se carga en esta sección de desplazamiento.
Sin embargo, en el estado Shift-DR, estos datos se desplazan hacia afuera.
Ingeniería inversa con JTAG
Las líneas de señal JTAG a menudo se encuentran agrupadas, y es probable que veas uno de estos encabezados.
Cuando deseas realizar ingeniería inversa de algo similar, necesitas comenzar con lo que se conoce.
Muchos fabricantes implementan IDCODE y BYPASS, por lo que podemos aprovechar estas dos instrucciones.
Si logras identificar un posible encabezado JTAG o distribución de pines, puedes utilizar el comportamiento de los dos registros para determinar la distribución de pines.
IDCODE como registro se carga como el IR predeterminado, y como tal podemos probar una distribución de pines asumida siguiendo estos pasos:
- Asignar roles a los pines de salida potenciales como TMS, TCK, etc.
- Entrar en el Estado de Reinicio de Lógica de Prueba.
- Entrar en Seleccionar Escaneo DR, Capturar DR y Desplazar DR.
- Hacer clic en 32 valores en TDI y monitorear TDO para un valor IDCODE válido.
- Comprobar el valor IDCODE que fue desplazado para determinar si parece válido.
- Si resulta ser válido, el intento es exitoso, si no, reasignar los pines y repetir.
También puedes aprovechar el registro IDCODE, que a menudo se carga en el IR por defecto.
Debido a esto, puedes utilizar el hecho de que tanto el IR como el DR se comportan como registros de desplazamiento.
Asumiendo que la longitud común del registro es de 32 bits, puedes intentar forzar el pinout siguiendo estos pasos:
- Asignar roles a los posibles pines de salida como TMS, TCK, etc.
- Usar los valores asumidos y entrar en el estado de Test Logic Reset.
- Entrar en el estado de Shift IR.
- Desplazar un valor único de 32 bits en TDI.
- Continuar desplazando 1’s en TDI mientras se monitorea un patrón único en TDO.
- Si se descubre el patrón, el intento es exitoso; si no, elegir nuevas asignaciones para los pines y repetir el proceso.
Una vez determinado el pinout del objetivo, el siguiente paso es determinar la longitud del IR / DR.
Esto se puede hacer comenzando con IR, entrando en el estado de Shift IR e inundando la cadena con 1’s en TDI.
Puedes hacerlo usando un número grande como 1024 o 4096 y luego introducir un 0.
Una vez que esto se haya hecho, puedes continuar registrando 1’s en TDI, mientras cuentas el número de ciclos de reloj que toma antes de que aparezca un 0 en TDO.
Esto indicará la longitud del IR, y una vez que tengas eso, puedes ingresar al estado Shift DR y repetir el proceso hasta que descubras el estado del DR.