IDA es una herramienta de ingeniería inversa de última generación, utilizada habitualmente en la industria del software para analizar binarios de código cerrado. Aunque alternativas gratuitas o más económicas como Ghidra ganan popularidad, no se pueden comparar con el descompilador de IDA en cuanto a precisión y madurez. Por suerte para nosotros, IDA Free incluye ahora un descompilador x64, lo que permite hacer ingeniería inversa sin necesidad de conocimientos de lenguaje ensamblador.
El objetivo de esta entrada es mostrar cómo cualquiera puede llevar a cabo tareas sencillas de ingeniería inversa usando únicamente la deducción lógica y el conjunto adecuado de herramientas. En lugar de centrarnos en el resultado final, los pasos incluyen capturas de pantalla detalladas y comentarios para mostrar todo el proceso de razonamiento.
Requisitos previos
Descargue e instale IDA Free. Tenga en cuenta que esta edición concreta de IDA no está pensada para uso comercial, pero dado que esta guía tiene fines introductorios, no debería suponer un problema. Aunque en el trabajo tengo acceso a IDA Pro, todas las capturas se han realizado con IDA Free para evitar confusiones.
Se recomienda disponer de un equipo Windows con RDP habilitado para seguir todos los pasos, aunque es posible realizar algunas de las tareas desde otra plataforma si es necesario. Para este proyecto he utilizado una máquina virtual limpia con Windows Server 2019.
Cómo definir un objetivo
Puede parecer obvio, pero en lugar de curiosear en binarios al azar, conviene empezar con un objetivo claro en mente. En este artículo, nuestro objetivo será identificar claves de registro secretas que afectan al codificador de vídeo H.264 de RDP.
No importa cómo elija el objetivo, pero yo he escogido este porque estoy familiarizado con H.264 en RDP gracias a mi trabajo en el proyecto FreeRDP.
El servidor RDP de Microsoft es gestionado por el servicio de sistema Remote Desktop Services, llamado TermService, que utiliza termsrv.dll como punto de entrada:

Primeros pasos
Cree un nuevo directorio llamado “Reversing” en “Mis documentos” y copie en él “termsrv.dll” desde “C:\Windows\System32”. Abra IDA y haga clic en New en el cuadro de diálogo Quick Start:

Navegue hasta el directorio “Reversing”, seleccione “termsrv.dll” y haga clic en Open:

En el cuadro de diálogo Load a new file, marque “Load resources” y haga clic en OK. Esta opción no es obligatoria, pero los segmentos de recursos a veces contienen información valiosa.

Confirme que desea cargar los símbolos de depuración correspondientes haciendo clic en Yes cuando se le solicite:

Cuando aparezca la interfaz principal de IDA, espere hasta que la ventana Output, en la parte inferior, indique que “the initial autoanalysis has been finished”. Esto puede tardar unos minutos y varía mucho según el tamaño de los binarios.

¡Y ya está! Ahora puede empezar a investigar el contenido de “termsrv.dll”. Consulte este mismo procedimiento para crear proyectos de IDA con nuevos binarios en el futuro.
Ni rastro de cadenas
Strings es la vista más útil de IDA, pero lamentablemente no aparece en la configuración predeterminada. En el menú View, vaya a Open subviews y seleccione Strings:

Se añadirá la nueva vista Strings, que mostrará las cadenas de texto encontradas en cualquier parte del binario. Haga clic con el botón derecho en cualquier punto de la vista para abrir el menú contextual y seleccione Setup…:

Marque Unicode C-style (16 bits) para habilitar los literales Unicode UTF-16, muy utilizados en Windows. La longitud mínima de cadena se puede modificar si se desea (5 es el valor predeterminado). Haga clic en OK para aplicar los cambios:

La vista Strings muestra ahora muchas más cadenas que antes. Tardé años en darme cuenta de que IDA no buscaba cadenas UTF-16 de forma predeterminada, ¡y me hubiera ahorrado mucho tiempo saberlo antes!

Pulse Alt+T, escriba “H264” y pulse Intro para buscar esa subcadena concreta en todas las cadenas de termsrv.dll. La ventana Output, en la parte inferior, debería indicar “String H264 not found”.
¿Cómo te llamas?
Así que “H264” como cadena no está presente en termsrv.dll, pero quizá se pueda encontrar en nombres de funciones o símbolos. En el menú View, vaya a Open subviews y seleccione Names:

La vista Names funciona igual que la vista Strings. Pulse Alt+T, escriba “H264” y pulse Intro para buscar la palabra clave en todos los nombres de símbolos. Por desgracia, seguimos sin obtener resultados para “H264”, lo que indica que termsrv.dll puede no ser el lugar correcto donde buscar.
¿Es este el final del camino? En absoluto. La ingeniería inversa se parece mucho a la pesca: puede llevar tiempo pescar un pez, pero resulta emocionante cuando finalmente ocurre. Probemos con un cebo distinto: Process Explorer, de la Sysinternals Suite. Descargue y ejecute la herramienta en el servidor RDP, y busque un proceso llamado “svchost.exe” con los subprocesos “rdpclip.exe” y “rdpinput.exe”:

Todos los servicios de sistema de Windows se ejecutan dentro de procesos “service host” (svchost), lo que dificulta distinguirlos entre sí. La columna Command Line de Process Explorer resulta bastante útil; en su defecto, se puede usar el cmdlet de PowerShell Get-CimInstance para encontrar el ID de proceso de un servicio determinado:
Get-CimInstance -Class Win32_Service -Filter "Name LIKE 'TermService'"
ProcessId Name StartMode State Status ExitCode
--------- ---- --------- ----- ------ --------
1072 TermService Manual Running OK 0
Lo importante es que podemos ver una lista de las DLL cargadas en el servidor RDP junto con termsrv.dll. Ampliemos nuestra área de búsqueda para incluir varias DLL que empiezan por “rdp” y copiémoslas en el directorio de nuestro proyecto “Reversing”:

Aunque es posible tener varias instancias de IDA abiertas a la vez, no lo recomiendo, ya que es fácil perderse. En el menú File, seleccione Close. En el cuadro de diálogo Save database, seleccione Pack database (Store) y haga clic en OK:

Ahora tenemos nuevos ficheros que examinar, y he decidido investigarlos en el siguiente orden:
- rdpserverbase.dll
- rdpbase.dll
- rdpcorets.dll
- rdpcore.dll
- rdpnano.dll
Para cada uno de estos ficheros, repito todo el proceso:
- Crear un nuevo proyecto de IDA
- Buscar la cadena “H264”
La cadena “H264” aparece varias veces en rdpserverbase.dll y en rdpbase.dll, pero sin nada relevante. Finalmente damos en el clavo al buscar “H264” en rdpcorets.dll:

No solo vemos numerosas referencias a “H264”, sino que algunas cadenas apuntan claramente a claves de registro. Decidimos centrarnos en rdpcorets.dll y cerrar el resto de proyectos de IDA.
En busca de funciones
Ahora que hemos encontrado las cadenas, podemos empezar a buscar las funciones que las utilizan. Haga doble clic en la cadena que parece ser una ruta de clave de registro llamada “H264Encoding”:
Software\Policies\Microsoft\Windows NT\Terminal Services\H264Encoding
El símbolo correspondiente se selecciona automáticamente y se muestra en la pestaña IDA View-A. Muchas veces, las cadenas no tienen un nombre propio en el binario, así que IDA les genera uno. En este caso, nuestra cadena se llama “aSoftwarePolici_0”. Haga clic con el botón derecho sobre el nombre del símbolo y seleccione Jump to xref to operand…:

Aparece una lista de funciones que utilizan este símbolo de cadena concreto. “SetH264EncodingParametersFromRegistry” parece una buena opción, así que haga doble clic en ella:

La vista de IDA muestra ahora la función “SetH264EncodingParametersFromRegistry” desensamblada, con instrucciones de ensamblador comentadas:

Aunque a algunos expertos avanzados en ingeniería inversa les gusta este tipo de vista, resulta bastante difícil de leer, sobre todo sin conocimientos de lenguaje ensamblador. Pulse F5 para descompilar la función y obtener un pseudocódigo legible. Cuando IDA solicite confirmación, haga clic en Yes para continuar:

La función descompilada se muestra ahora en todo su esplendor. Tenga en cuenta que, dado que se pierde mucha información en el momento de la compilación, IDA solo puede reconstruir automáticamente ciertos elementos y hacer conjeturas fundamentadas sobre el resto. Este ejemplo concreto se ha descompilado sorprendentemente bien, pero la mayoría de las funciones presentarán bastantes imprecisiones.

Descompilar una función resulta emocionante, pero ¿hemos encontrado la correcta? “EnableQPSingleStep” y “VideoDetectorRectDisplayMode” son claramente claves de registro, pero tienen nombres que no dicen mucho salvo a quien conozca bien los aspectos internos del códec H.264. Puede hacer clic con el botón derecho en un nombre de función o una constante de cadena dentro del pseudocódigo para encontrar más referencias cruzadas a ellos. Probemos con la función “RegOpenKeyExW” y veamos adónde nos lleva:

Como era de esperar, “RegOpenKeyExW” se utiliza en muchos otros lugares relacionados con claves de registro, la mayoría de los cuales no tienen relación con H.264. Sin embargo, podemos identificar algunas de las funciones de la lista anterior de referencias cruzadas de la cadena “H264Encoding”, así que pasemos a la función “CreateOutputAvc”:

¡Ahora sí que estamos hablando! Podemos ver los siguientes nombres de claves de registro que apuntan a funciones de grabación de H.264 en el servidor RDP:
- RecordPath
- EnableRecord264
- EnableRecordYUV

Probemos ahora con la función “CreateCompressorOutputAvc” para ver si encontramos algo más. Se parece a la función anterior, pero con algunas claves de registro distintas:
- RecordPath
- EnableRecordRGB
- EnableRecordRdp264

Sin duda estamos avanzando por buen camino, pero aún no hemos visto ninguna función que utilice los valores de las claves de registro. Los constructores de clases o las funciones de inicialización suelen ser buenos puntos de partida, así que probemos con “OutputAvc::OutputAvc”:

El resultado descompilado de este constructor de OutputAvc es más complejo y contiene más imprecisiones, pero aun así podemos ver que crea ficheros con un formato de nombre específico. Podríamos seguir así durante horas, así que detengámonos y veamos si podemos actuar con la información que ya tenemos.
Recopilando información
Cuando se empieza a usar IDA, un problema con el que se topa la mayoría de la gente es encontrar mucha más información de la que puede procesar. Debe considerar su objetivo principal como la “misión principal” del juego, y todo lo demás como “misiones secundarias”. Si se dispersa demasiado en tangentes, perderá de vista su objetivo inicial.
La mejor forma de recopilar información es usar su editor de texto favorito para ir pegando todo tipo de pistas a medida que las encuentre. No intente organizarlas demasiado; no merece la pena. A menudo se descubre el verdadero valor de una información concreta solo después de haberla relacionado con otra cosa.
Volvamos a nuestras funciones de interés para las claves de registro de H.264 en RDP y elaboremos una lista adecuada. Tenemos los nombres, pero no los tipos, así que consultemos la documentación de la API para RegQueryValueExW.
El parámetro de salida lpType contiene el tipo tal como se define en Registry Value Types, pero lamentablemente no disponemos de los valores numéricos de cada uno. Este es un problema habitual que se puede resolver utilizando una copia de las cabeceras del Windows SDK. En este caso, solo se utilizan dos tipos: REG_SZ (1) y REG_DWORD (4).
El único tipo de cadena (REG_SZ) es “RecordPath”; todas las demás claves de registro son numéricas (REG_DWORD) con un valor de 1 o 0. Tenga en cuenta que, dado que “RecordPath” es de tipo “REG_SZ” y no “REG_EXPAND_SZ”, no puede contener variables de entorno como “%SystemRoot%”. Obtenemos así la siguiente lista de claves de registro con comentarios:
HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services\H264Encoding
- RecordPath: ruta completa a un directorio de salida para la grabación
- Enable264Log: habilita el registro (log) de H.264; debe establecerse en 1
- EnableRecordYUV: habilita el volcado de captura YUV sin procesar (¡muy voluminoso!)
- EnableRecordRGB: habilita el volcado de captura RGB sin procesar (¡muy voluminoso!)
- EnableRecord264: habilita el volcado del flujo de bits H.264 sin procesar
- EnableRecordRdp264: habilita el volcado del flujo H.264 de RDP sin procesar
Poniéndolo a prueba
Ahora que hemos recopilado información valiosa, intentemos utilizar las claves de registro para confirmar que realmente funcionan. Abra el editor de registro (regedit.exe) y cree la clave de registro “H264Encoding”. Cree el directorio “C:\Windows\Temp\RdpRecording” y configure el valor de la clave “RecordPath” en consecuencia. Cree y establezca en 1 el resto de valores de las claves de registro para habilitar todos los tipos de grabación.

Las claves de registro de H.264 en RDP solo se utilizarán si se emplea H.264 en la conexión RDP, así que ajustemos la configuración del servidor RDP. Abra el editor de directivas de grupo (gpedit.msc) y navegue hasta la siguiente sección dentro de Computer Configuration:
Computer Configuration > Administrative Templates > Windows Components > Remote Desktop Services > Remote Desktop Session Host > Remote Session Environment
Habilite las siguientes directivas:
- Prioritize H.264/AVC 444 graphics mode for remote desktop connections
- Configure H.264/AVC hardware encoding for remote desktop connections
Habilite y establezca la directiva Limit maximum color depth en 32 bit, ya que también puede afectar a la negociación del códec.

Reinicie el servidor RDP para aplicar los cambios, conéctese mediante RDP, realice algunas acciones que generen actualizaciones de imagen y, a continuación, cierre la sesión. Vuelva a conectarse mediante RDP y abra el directorio “C:\Windows\Temp\RdpRecording” para comprobar si ha funcionado:

Los ficheros vacíos suelen ser los que está usando en ese momento el servidor RDP; solo se vuelcan al disco al finalizar la sesión, razón por la cual es necesario cerrar la sesión por completo. Dado que se trata de volcados de datos sin procesar utilizados para depuración interna, requieren cierta transformación.
Los píxeles YUV sin comprimir se pueden reproducir directamente con VLC y las opciones de línea de comandos adecuadas:
choco install vlc
cd "C:\Windows\Temp\RdpRecording"
$Env:Path += ";$Env:ProgramFiles\VideoLAN\VLC"
vlc --rawvid-fps 24 --rawvid-width 1920 --rawvid-height 1088 --rawvid-chroma I420 rdp_record_0_1920x1088_24p.yuv
De forma alternativa, el flujo de bits H.264 sin procesar se puede incrustar en un fichero de vídeo .mp4 mediante ffmpeg:
choco install ffmpeg
cd "C:\Windows\Temp\RdpRecording"
ffmpeg -i rdp_record_0_1920x1088_24p.264 -codec copy rdp_record_0_1920x1088_24p.mp4
Los nombres de fichero y parámetros concretos variarán, así que ajústelos según corresponda. Así es como debería verse cuando funciona correctamente:

Como ocurre con la mayoría de las claves de registro “secretas”, no estaban ocultas, pero tampoco estaban pensadas para usarse ni para confiar en ellas. Tampoco hay garantía de que se sigan admitiendo en el futuro.
Reflexiones finales
Sin acceso al código fuente, aún es posible obtener información valiosa sobre binarios de código cerrado utilizados en millones de dispositivos. Existe una cierta descarga de adrenalina asociada a encontrar formas de lograr cosas útiles que normalmente no están contempladas. Aunque la ingeniería inversa avanzada requiere mucho más trabajo, hay que empezar por algún sitio. Si es usted principiante en ingeniería inversa, ¿le ha resultado útil esta entrada? De ser así, ¿qué le gustaría aprender a continuación?
