Ghidra, guía práctica: instala el descompilador de la NSA y abre tu primer programa

Ghidra es la herramienta de ingeniería inversa que la NSA, la agencia de inteligencia de Estados Unidos, publicó como código abierto en 2019. Abre un programa del que no tienes el código fuente, encuentra sus funciones y sus textos, y te muestra al lado del código máquina una reconstrucción en lenguaje C bastante legible. Es gratis, funciona en Windows, macOS y Linux, y es la pieza que usan por debajo herramientas como REA y buena parte de la ola de descompilaciones de videojuegos con IA. Esta guía va de cero a tu primer análisis, con cada paso hecho de verdad.

Cómo se hicieron las pruebas. Todo se ejecutó en un contenedor desechable de Linux (Ubuntu 26.04) con OpenJDK 21.0.12.1 y Ghidra 12.1.4, la versión estable del 21 de septiembre de 2026. El programa que analizamos lo escribimos y lo compilamos para la guía, así que se puede comparar lo que reconstruye Ghidra con el original. Las capturas son de la interfaz real, abierta en ese contenedor.

Qué es y para qué sirve

Un programa compilado es una lista de instrucciones para el procesador: números que una persona no puede leer. Un desensamblador los traduce a ensamblador, que ya se puede leer con paciencia, y un descompilador va un paso más allá e intenta reconstruir el código en C del que salió. Ghidra hace las dos cosas y añade lo que convierte el trabajo en algo manejable: encuentra solo las funciones, las cadenas de texto y quién llama a quién, y te deja poner nombres a todo a medida que vas entendiendo el programa.

Ghidra importa el programa, lo analiza para encontrar funciones, cadenas y referencias, muestra el ensamblador y el C reconstruido, y guarda en un proyecto los nombres y comentarios que tú añades, sin tocar el archivo originalQué hace Ghidra con un programa1. Importarlee el formato:ELF, PE, Mach-O…2. Analizarencuentra funciones,cadenas y referencias3. Mostrarensamblador yC reconstruido4. Anotartú renombrasy comentasTodo se guarda en un proyecto de Ghidra, no en el programaEl archivo original no se modifica nunca. El proyecto guarda el análisis y lo que túañades: nombres, tipos y comentarios. Así puedes cerrar Ghidra y seguir otro díadonde lo dejaste, o compartir el trabajo con otra persona.

Ghidra nunca modifica el archivo que analizas: todo lo que descubres queda en el proyecto. Esquema: decodigo.com.

Se usa para analizar malware, buscar fallos de seguridad en programas cerrados, entender formatos de archivo para hacer programas compatibles, preservar software antiguo y, cada vez más, como herramienta de un agente de IA. Sus alternativas más conocidas son de pago:

HerramientaPrecioLo más destacado
GhidraGratis, código abierto (Apache 2.0)Descompilador incluido para muchas arquitecturas, trabajo en equipo y scripts en Java y Python
IDA ProDe pago, con una versión gratuita limitadaEl estándar comercial durante décadas
HopperDe pago, con modo de pruebaPensado para macOS y Linux

Antes de empezar

  • Un sistema de 64 bits: Windows 10 (versión 1809 o posterior), Linux o macOS 10.13 o posterior.
  • 4 GB de memoria y 1 GB de disco como mínimo. Con programas grandes, cuanta más memoria, mejor.
  • Java 21 de 64 bits, en su versión JDK, no solo el JRE. Es el requisito que más problemas da, y lo vemos en el siguiente apartado.
  • Python 3.9 a 3.14, solo si vas a usar el depurador o los scripts en Python (PyGhidra). Para esta guía no hace falta.
Un aviso legal antes de abrir nada. La primera vez que arrancas Ghidra aparece un acuerdo de usuario que lo deja claro: la herramienta está pensada solo para un uso legal, y el software que analices puede estar protegido por derechos de autor o por su licencia. Practica con programas tuyos o con los que tengas permiso para examinar, y revisa la ley de tu país antes de desarmar algo ajeno.
Acuerdo de usuario de Ghidra, que aparece la primera vez que se abre: licencia Apache 2.0 y aviso de uso legal
El acuerdo de usuario que aparece al abrir Ghidra por primera vez. Captura: decodigo.com.

Instalar Java 21

Ghidra está escrito en Java y no lo incluye, así que hay que instalarlo antes. En Linux, desde los repositorios de tu distribución; en Debian 13 y Ubuntu 26.04 el paquete se llama igual:

sudo apt install openjdk-21-jdk

En Windows y macOS, lo más sencillo es el instalador de Eclipse Temurin 21, una distribución gratuita de Java que recomienda la propia documentación de Ghidra (también sirve Amazon Corretto 21). Elige el JDK de 64 bits. Para comprobar que está:

java -version
salidaopenjdk version "21.0.12.1" 2026-08-18 LTS
OpenJDK Runtime Environment Temurin-21.0.12.1+1 (build 21.0.12.1+1-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.12.1+1 (build 21.0.12.1+1-LTS, mixed mode)

Lo que importa es el 21 del principio. Si sale otro número, o un «command not found», sigue leyendo: el error que da Ghidra está más abajo.

Descargar y verificar Ghidra

Ghidra se descarga de su página de versiones en GitHub. Es un ZIP de unos 570 MB. Desde la terminal:

curl -LO https://github.com/NationalSecurityAgency/ghidra/releases/download/Ghidra_12.1.4_build/ghidra_12.1.4_PUBLIC_20260921.zip

Antes de abrirlo, comprueba que el archivo es el original. La página de la versión publica su huella SHA-256, y basta con calcular la del archivo descargado y compararlas:

sha256sum ghidra_12.1.4_PUBLIC_20260921.zip
salidaddac49f903da9d5bac833e5cc79395098b9c33cfd3279be5f31bd00387d2d4db  ghidra_12.1.4_PUBLIC_20260921.zip

Coincide con la publicada. En Windows, la misma comprobación se hace en PowerShell con Get-FileHash .\ghidra_12.1.4_PUBLIC_20260921.zip, y en macOS con shasum -a 256. Si no coincide, no lo abras: descárgalo otra vez, y siempre del repositorio oficial, porque con la fama de estas herramientas circulan copias falsas.

Ghidra no tiene instalador: se descomprime y ya está.

unzip ghidra_12.1.4_PUBLIC_20260921.zip
cd ghidra_12.1.4_PUBLIC

No necesita permisos de administrador, no toca el registro de Windows ni crea accesos directos, y para quitarlo basta con borrar la carpeta. En macOS, la protección Gatekeeper puede bloquear sus componentes nativos, que no están firmados; la documentación oficial recomienda quitar la marca de cuarentena del ZIP antes de descomprimirlo:

xattr -d com.apple.quarantine ghidra_12.1.4_PUBLIC_20260921.zip

Arrancar Ghidra

Desde la carpeta descomprimida:

./ghidraRun          # Linux y macOS
ghidraRun.bat        # Windows

La primera vez aparece el acuerdo de usuario que vimos arriba; después, la ventana del proyecto y un «consejo del día» que se puede desactivar. En nuestra prueba, el arranque tardó unos 35 segundos la primera vez y unos 3 las siguientes.

El error más frecuente: un Java que no sirve

Si tienes una versión antigua de Java, o solo el JRE, Ghidra no arranca. Lo probamos con Java 17 JRE:

salida con Java 17 JREWARNING: JAVA_HOME environment specifies unsupported java version: /opt/java/openjdk
ERROR: Unable to prompt user for JDK path, no TTY detected.
Please refer to the Getting Started document's Troubleshooting section.

En un escritorio normal, en lugar del error, Ghidra te pide la ruta de un JDK válido; dentro de un contenedor o por SSH no puede preguntar y se detiene. La solución es instalar el JDK 21 y, si tienes varios Java, decirle cuál usar con la variable JAVA_HOME, que tiene prioridad sobre el resto.

Tu primer análisis

Para ver qué hace Ghidra con un programa necesitamos uno. Este es un comprobador de claves, el típico ejercicio para practicar: acepta una clave de ocho caracteres si la suma de sus dígitos, dividida entre 7, da resto 3.

#include <stdio.h>
#include <string.h>

static int suma_digitos(const char *s) {
    int total = 0;
    for (; *s; s++) {
        if (*s >= '0' && *s <= '9') {
            total += *s - '0';
        }
    }
    return total;
}

int comprobar(const char *clave) {
    if (strlen(clave) != 8) {
        return 0;
    }
    return suma_digitos(clave) % 7 == 3;
}

int main(int argc, char **argv) {
    if (argc < 2) {
        puts("uso: ./licencia CLAVE");
        return 1;
    }
    if (comprobar(argv[1])) {
        puts("Clave correcta");
        return 0;
    }
    puts("Clave incorrecta");
    return 2;
}
gcc -O1 -o licencia licencia.c
./licencia 12345678
./licencia 00000003
salidaClave incorrecta
Clave correcta

Ahora, imagina que no tienes licencia.c, solo el ejecutable. Es la situación real, y lo que vamos a hacer es averiguar con Ghidra qué clave acepta.

Crear un proyecto e importar el programa

Ghidra trabaja con proyectos. En la ventana principal: File → New Project, elige Non-Shared Project (un proyecto solo para ti), una carpeta y un nombre. Después, File → Import File (o arrastra el ejecutable a la ventana): Ghidra reconoce solo el formato, aquí un ELF de Linux para x86 de 64 bits, y muestra un resumen. Al abrir el programa te propone analizarlo; acepta con las opciones por defecto, que son las adecuadas para empezar.

Ventana del proyecto de Ghidra con dos programas importados: licencia y licencia-sin-simbolos
El proyecto «Licencias» con dos programas importados: el normal y una copia sin símbolos que usaremos más adelante. Captura: decodigo.com.

El CodeBrowser

Con doble clic en el programa se abre el CodeBrowser, la ventana donde se hace casi todo:

El CodeBrowser de Ghidra con el árbol del programa a la izquierda, el desensamblado en el centro y el código C reconstruido de main a la derecha
A la izquierda, el árbol del programa (secciones) y el de símbolos (funciones, importaciones). En el centro, el Listing: direcciones, bytes y ensamblador. A la derecha, el descompilador con el C de la función en la que está el cursor; aquí, main. Captura: decodigo.com.

Los dos paneles grandes van sincronizados: haz clic en una línea del C y se marca su ensamblador, y al revés. Para moverte, lo más rápido es la tecla G (Go To), que acepta una dirección o un nombre:

Diálogo Go To de Ghidra con el nombre de la función comprobar escrito
El diálogo Go To, que se abre con la tecla G. Captura: decodigo.com.

Empezar por los textos

En un programa real no sabes cómo se llaman las funciones, pero casi siempre hay textos que el programa muestra. Window → Defined Strings los lista todos, y el filtro de abajo los busca:

Ventana Defined Strings de Ghidra filtrada por Clave, con los tres mensajes del programa y sus direcciones
Las cadenas del programa filtradas por «Clave». Con doble clic en una se salta a su dirección, y desde ahí a la función que la usa. Captura: decodigo.com.

«Clave correcta» lleva directamente a main, y main llama a una función llamada comprobar para decidir qué mensaje sale. Esa es la que nos interesa.

Leer el descompilado y ponerle nombres

Así reconstruye Ghidra la función comprobar:

// ---- comprobar @ 00101180

bool comprobar(char *param_1)

{
  char cVar1;
  size_t sVar2;
  int iVar3;
  bool bVar4;

  sVar2 = strlen(param_1);
  bVar4 = false;
  if (sVar2 == 8) {
    cVar1 = *param_1;
    if (cVar1 == '\0') {
      iVar3 = 0;
    }
    else {
      iVar3 = 0;
      do {
        if ((byte)(cVar1 - 0x30U) < 10) {
          iVar3 = iVar3 + -0x30 + (int)cVar1;
        }
        param_1 = param_1 + 1;
        cVar1 = *param_1;
      } while (cVar1 != '\0');
    }
    bVar4 = iVar3 % 7 == 3;
  }
  return bVar4;
}

Se entiende, pero cuesta: las variables se llaman iVar3 o cVar1 porque los nombres originales no existen en el programa compilado. El trabajo de verdad empieza aquí, poniendo nombres a medida que entiendes qué hace cada cosa. Haz clic en una variable y pulsa L:

Diálogo Rename Local Variable de Ghidra renombrando iVar3 como suma
Renombrar una variable con la tecla L. Captura: decodigo.com.
El descompilador de Ghidra mostrando la función comprobar antes y después de renombrar sus variables
La misma función antes y después de renombrar cinco variables: clave, c, longitud, suma y valida. Captura: decodigo.com.

Con nombres, se lee casi como el original: si la clave no mide 8 caracteres, no vale; si los mide, recorre cada carácter, y si es un dígito (c - 0x30 menor que 10, porque 0x30 es el código del carácter «0») lo suma; la clave vale si la suma entre 7 da resto 3. Ya podemos fabricar una clave válida: 00000003 suma 3, y 3 entre 7 da resto 3. Es exactamente la que funcionó arriba.

¿Y la función suma_digitos? En el original había dos funciones, y Ghidra solo muestra una. No es un fallo: al compilar con -O1, el compilador decidió copiar el cuerpo de suma_digitos dentro de comprobar, y la función dejó de existir en el ejecutable. Por eso el bucle está dentro. Es algo que verás a menudo: el código compilado no siempre conserva la forma del original.

Sin símbolos: lo normal en programas reales

Nuestro ejecutable conservaba los nombres de sus funciones porque nadie los había quitado. Los programas que se distribuyen suelen pasar antes por strip, que los elimina. Con la copia sin símbolos, Ghidra pone a cada función un nombre a partir de su dirección:

// ---- FUN_00101212 @ 00101212

undefined8 FUN_00101212(int param_1,long param_2)

{
  int iVar1;
  undefined8 uVar2;

  if (param_1 < 2) {
    puts("uso: ./licencia CLAVE");
    uVar2 = 1;
  }
  else {
    iVar1 = FUN_00101180(*(undefined8 *)(param_2 + 8));
    if (iVar1 == 0) {
      puts("Clave incorrecta");
      uVar2 = 2;
    }
    else {
      puts("Clave correcta");
      uVar2 = 0;
    }
  }
  return uVar2;
}

Es main, pero se llama FUN_00101212, y comprobar pasa a ser FUN_00101180. Las funciones se renombran igual que las variables, con L sobre su nombre. Los textos, en cambio, siguen ahí, y por eso empezar por las cadenas suele ser la mejor estrategia.

Sin ventanas: analyzeHeadless

Ghidra trae analyzeHeadless, que importa y analiza programas desde la terminal, sin interfaz. Sirve para analizar muchos archivos de golpe, en un servidor o dentro de un script, y es lo que usan por debajo herramientas como REA.

mkdir proyectos
./support/analyzeHeadless proyectos Licencias -import licencia \
    -scriptPath scripts -postScript Descompila.java

La orden crea el proyecto Licencias en la carpeta proyectos, importa el programa, lo analiza y, al terminar, ejecuta un script. Este, en Java, imprime el C de cada función:

// Imprime el código C que reconstruye el descompilador para cada función del programa.
// @category decodigo
import ghidra.app.decompiler.DecompInterface;
import ghidra.app.decompiler.DecompileResults;
import ghidra.app.script.GhidraScript;
import ghidra.program.model.listing.Function;

public class Descompila extends GhidraScript {
    @Override
    public void run() throws Exception {
        DecompInterface dec = new DecompInterface();
        dec.openProgram(currentProgram);
        for (Function f : currentProgram.getFunctionManager().getFunctions(true)) {
            if (f.isThunk() || f.isExternal()) continue;
            DecompileResults r = dec.decompileFunction(f, 30, monitor);
            if (!r.decompileCompleted()) continue;
            println("// ---- " + f.getName() + " @ " + f.getEntryPoint());
            println(r.getDecompiledFunction().getC());
        }
        dec.dispose();
    }
}
salida, solo las líneas del informeINFO  REPORT: Analysis succeeded for file: file:///g/w/licencia (HeadlessAnalyzer)
INFO  REPORT: Save succeeded for: /licencia (Licencias:/licencia) (HeadlessAnalyzer)
INFO  REPORT: Import succeeded (HeadlessAnalyzer)

Tardó 7.6 segundos, y el C que imprime es el mismo que vimos en la interfaz. El proyecto queda guardado, así que después se puede abrir con ghidraRun para seguir a mano: es lo que hicimos para las capturas de esta guía.

Ghidra con un agente de IA: REA

Tres formas de usar Ghidra: con su interfaz gráfica, con analyzeHeadless desde la terminal o a través de un agente de IA con REA; las tres usan el mismo motor de análisis y descompilaciónEl mismo motor, tres formas de usarloCon ventanasghidraRunexplorar a mano,renombrar, comentarDesde la terminalanalyzeHeadlesspor lotes y conscripts, sin pantallaCon un agente de IAREA + Claude, Codex…el agente pregunta,Ghidra respondeGhidra: cargadores, análisis automático y descompiladorel resultado es el mismo, uses la vía que uses

Ghidra se puede usar a mano, desde la terminal o como herramienta de un agente de IA. Esquema: decodigo.com.

REA conecta agentes como Claude Code, Codex o Cursor con desensambladores, y para los programas nativos (C, C++, Swift…) necesita uno: Ghidra es la opción gratuita. Basta con decirle dónde está, con la variable GHIDRA_INSTALL_DIR. Sin ella, rea doctor lo marca como pendiente:

rea doctor  - name: ghidra
    ok: false
    classification: missing_analysis_engine
    detail: GHIDRA_INSTALL_DIR is not set
    remediation: Set GHIDRA_INSTALL_DIR to an extracted Ghidra 12.1.x release directory.
export GHIDRA_INSTALL_DIR=/opt/ghidra_12.1.4_PUBLIC
rea doctor
rea doctor, solo la parte de Ghidra  - name: ghidra
    ok: true
    detail: /opt/ghidra_12.1.4_PUBLIC
  - name: ghidra-platform
    ok: true
    detail: linux
  - name: ghidra-architecture
    ok: true
    detail: x64
  - name: ghidra-installation
    ok: true
    detail: /opt/ghidra_12.1.4_PUBLIC/Ghidra/application.properties
  - name: ghidra-version
    ok: true
    detail: 12.1.4
  - name: ghidra-headless
    ok: true
    detail: /opt/ghidra_12.1.4_PUBLIC/support/analyzeHeadless
  - name: ghidra-native_decompiler
    ok: true
    detail: "/opt/ghidra_12.1.4_PUBLIC/Ghidra/Features/Decompiler/os/linux_x86_64/decompile reports elf x86_64, which matches linux/x64"
  - name: ghidra-java
    ok: true
    detail: 21.0.12.1; 64-bit; JDK; /opt/java/openjdk; accepted a 64-bit full JDK 21 or newer

Comprueba la carpeta, la versión, el modo sin ventanas, el descompilador nativo y el Java. Con todo en verde, REA ya puede usar Ghidra, por ejemplo para descompilar una función concreta. Probamos REA 6.7.0 con nuestro programa:

rea decompile ./licencia comprobar --provider ghidra --filter-output normalized_result
salidabool comprobar(char *param_1)

{
  char cVar1;
  size_t sVar2;
  int iVar3;
  bool bVar4;
  
  sVar2 = strlen(param_1);
  bVar4 = false;
  if (sVar2 == 8) {
    cVar1 = *param_1;
    if (cVar1 == '\0') {
      iVar3 = 0;
    }
    else {
      iVar3 = 0;
      do {
        if ((byte)(cVar1 - 0x30U) < 10) {
          iVar3 = iVar3 + -0x30 + (int)cVar1;
        }
        param_1 = param_1 + 1;
        cVar1 = *param_1;
      } while (cVar1 != '\0');
    }
    bVar4 = iVar3 % 7 == 3;
  }
  return bVar4;
}

nfidence: observed
thority: shipped-artifact

Es el mismo C, ahora en manos de un agente que puede renombrar, buscar referencias y explicarte el programa con pruebas. Para que el cambio sea permanente, añade la línea export a tu ~/.bashrc o ~/.zshrc, o configura la variable en Windows.

Actualizar y desinstalar

Para actualizar, descarga la versión nueva y descomprímela en otra carpeta, nunca encima de la anterior: la documentación lo desaconseja expresamente. Tus proyectos son carpetas aparte y los abre la versión nueva. Para desinstalar, borra la carpeta de Ghidra. Su configuración y su registro se guardan aparte, en Linux en ~/.config/ghidra/ghidra_12.1.4_PUBLIC; puedes borrarla también si no vas a volver a usarlo.

Ojo con la próxima versión. Ghidra 12.2 está a punto de salir y, según su historial de cambios, pedirá Java 25. Cuando actualices, instala también el JDK 25 (en Debian 13 y Ubuntu 26.04, openjdk-25-jdk). Lo contamos en la noticia de Ghidra 12.2.

Resumen

Quiero…Cómo
instalar Javasudo apt install openjdk-21-jdk o Eclipse Temurin 21 (JDK, 64 bits)
descargar Ghidrael ZIP de la página de versiones de GitHub, y comprobar su SHA-256
instalarlodescomprimir; en macOS, antes, xattr -d com.apple.quarantine
abrirlo./ghidraRun o ghidraRun.bat
analizar un programaFile → New Project, File → Import File, aceptar el análisis
ir a una función o direccióntecla G
ver los textos del programaWindow → Defined Strings
renombrartecla L sobre la variable o la función
analizar sin ventanassupport/analyzeHeadless con -import y -postScript
usarlo con REAexport GHIDRA_INSTALL_DIR=… y rea doctor
desinstalarloborrar su carpeta y ~/.config/ghidra

Si quieres seguir, la propia instalación trae en docs/GhidraClass los cursos oficiales, de principiante a avanzado y con ejercicios, y en docs/CheatSheet.html una chuleta con los atajos de teclado. Además incluye 327 scripts de ejemplo en Java y Python, repartidos en las carpetas ghidra_scripts. Y para usar Ghidra a través de un agente de IA, la guía práctica de REA.

Las pruebas se ejecutaron el 19 de octubre de 2026 con Ghidra 12.1.4, OpenJDK 21.0.12.1 (Eclipse Temurin), gcc 15.2.0 y REA 6.7.0 en un contenedor desechable de Ubuntu 26.04; las salidas y las capturas son de esa ejecución. Requisitos e instrucciones de instalación según la guía Getting Started de Ghidra 12.1.4.

Fuente: NationalSecurityAgency/ghidra en GitHub