Referencia
Solución de problemas
Síntoma → causa → solución para los problemas comunes tras la ofuscación: miembros ausentes, serialización, enlace de XAML, reflexión, SmartScreen, nombres seguros y más.
La mayoría de los problemas se reducen a una cosa — algo que se resolvía por nombre en tiempo de ejecución fue renombrado. Esta página asigna síntomas a soluciones. Si el tuyo no está aquí, contáctanos con la excepción y tu configuración.
Cómo encontrar rápido al culpable (bisección)
Cuando una compilación protegida se comporta mal, acótalo desactivando las pasadas de una en una y volviendo a probar:
- Renombrado desactivado (
"renameIdentifiers": false) — si el problema desaparece, es un nombre que se resuelve en tiempo de ejecución → presérvalo (ver abajo). Esta es con diferencia la causa más común. - Flujo de control desactivado (
"controlFlowObfuscation": false) — si eso lo soluciona, cuéntanoslo con el método; el flujo de control preserva el comportamiento por diseño, así que queremos verlo. - Cadenas desactivadas (
"encryptStrings": false) — rara vez es la causa; las cadenas se descifran a valores idénticos.
La pasada que “lo soluciona” te indica la categoría. Luego vuelve a activarla y aplica una exclusión específica en lugar de dejar la pasada desactivada.
Errores en tiempo de ejecución
| Síntoma | Causa | Solución |
|---|---|---|
MissingMethodException / MissingFieldException / TypeLoadException en tiempo de ejecución | Un miembro encontrado por reflexión/nombre fue renombrado | Presérvalo: exclude, [System.Reflection.Obfuscation] o preservePublicApi. Consulta Mantener tu app en funcionamiento. |
Type.GetType("MyApp.Foo") devuelve null | El tipo fue renombrado | Preserva ese tipo (exclude), o cambia el código a typeof(Foo) (identidad, segura ante el renombrado). |
| JSON/XML tiene nombres de campo extraños, o la deserialización devuelve nulos | Los nombres de las propiedades del DTO fueron renombrados | Preserva los DTO (los atributos se autodetectan; de lo contrario, exclude). |
| WPF/MAUI: errores de enlace en el registro, interfaz en blanco o muerta | El modelo de vista o los miembros enlazados fueron renombrados | Preserva los modelos de vista + los miembros enlazados; mantén preservePublicApi. |
| DI: “unable to resolve service” / el registro por convención no encuentra nada | El escaneo de ensamblados por nombre alcanzó tipos renombrados | Preserva los tipos escaneados, o registra por tipo. |
| EF Core: columnas incorrectas / discrepancia de migración | Los nombres de las propiedades de las entidades fueron renombrados | Preserva las entidades, o usa HasColumnName explícito. |
TypeInitializationException que menciona una prueba de Nebula | El ensamblado se compiló con una licencia de prueba | Recompila con una licencia de pago — las compilaciones de prueba avisan y se detienen tras la fecha de prueba por diseño. |
Distribución y firma
| Síntoma | Causa | Solución |
|---|---|---|
| “Windows protegió su PC” / “Editor desconocido” (SmartScreen) | El instalador/exe aún no está firmado con firma de código | Firma con un certificado Authenticode, o instala a través de Microsoft Store (firmado por Microsoft). La reputación también se construye con el tiempo. Consulta Instalación. |
| El antivirus marca un binario recién ofuscado | Los binarios nuevos/sin firmar no tienen reputación | Fírmalo (Authenticode), envía un informe de falso positivo al proveedor si es necesario. |
| Un ensamblado con nombre seguro no se carga / “firma no válida” | La ofuscación reescribió el ensamblado después de firmarlo | Deja que Nebula lo vuelva a firmar: establece strongNameKeyFile (la firma ocurre tras la ofuscación). |
| Una compilación de archivo único no está protegida contra manipulación | El auto-hash de la anti-manipulación no hace nada en un paquete de archivo único (sin ruta en disco) | Es lo esperado — usa flujo de control + cifrado de cadenas ahí, o distribuye en varios archivos para conservar la anti-manipulación. |
Compilación / CI
| Síntoma | Causa | Solución |
|---|---|---|
| La integración con la compilación no hace nada en una máquina de desarrollo | NebulaObfuscate no está establecida ahí (por diseño) | Establécela solo en el agente de compilación — consulta MSBuild y CI. |
| “build integration is a licensed feature” | La edición Free es solo CLI/interfaz gráfica | Proporciona una licencia en la máquina de compilación (NEBULA_LICENSE, licenseFile o NebulaLicenseFile). |
| Salida distinta de cero / error de configuración en CI | Configuración incorrecta o input ausente | Comprueba el código de salida y el registro; valida las rutas en nebula.config.json. |
Leer un fallo ofuscado
Una traza de pila de producción llena de nombres renombrados puede traducirse de nuevo con el mapa de símbolos de la compilación:
nebula deobfuscate --map protected/MyApp.symbols.json --input crash.txt
Consulta Desofuscar trazas de pila. Guarda el *.symbols.json de cada compilación de versión exactamente para esto.
Diagnosticar por qué un método no se aplanó
El flujo de control deja un método sin aplanar solo cuando no puede demostrar que la transformación sea segura (nunca emite IL roto). Para ver por qué, establece la variable de entorno y ejecuta la CLI:
NEBULA_CF_DEBUG=1
Imprime, por método, si cada ámbito se aplanó o por qué se omitió — útil cuando esperabas que un método específico (p. ej. una comprobación de licencia) se aplanara.
Rendimiento
El renombrado y el cifrado de cadenas tienen un coste de ejecución insignificante. El aplanado del flujo de control añade algo de sobrecarga por método transformado, así que para las rutas calientes acótalo con controlFlowInclude/controlFlowExclude o una controlFlowIntensity más baja en lugar de aplanarlo todo.