Pipeline de compilación
En qué punto del pipeline de MSBuild ejecuta Babel el paquete, cómo mover ese paso, los destinos en los que puede intervenir, qué ocurre al publicar y cómo se seleccionan las herramientas de compilación.
Dónde se ejecuta la ofuscación
De forma predeterminada, el paquete ejecuta Babel justo después de CoreCompile, sobre el ensamblado que el compilador acaba de escribir en la carpeta intermedia, $(IntermediateOutputPath)$(TargetFileName), es decir, la carpeta obj. Todos los pasos posteriores de la compilación trabajan entonces con el ensamblado ofuscado: la copia a bin, la generación de .deps.json, los ensamblados satélite y, al publicar, el recorte, el empaquetado en un único archivo, la compilación ReadyToRun o NativeAOT y el empaquetado en un APK o en un bundle de aplicación.
Este orden es la razón para usar el paquete en los proyectos de estilo SDK. El SDK de .NET reescribe el IL después de la compilación, y Babel tiene que ver el ensamblado antes de que lo haga; un ensamblado tomado de bin o de la carpeta de publicación ya ha pasado por esos pasos. Colocar la tarea a mano después de CoreCompile es frágil, porque la secuencia exacta de destinos depende del tipo de proyecto y de la versión del SDK. El paquete lo resuelve por usted.
Otras dos reglas mantienen la agilidad del IDE:
- Las compilaciones en tiempo de diseño se omiten. Visual Studio y los analizadores de código ejecutan continuamente compilaciones en segundo plano; el paquete no inserta en ellas el paso de ofuscación.
- La ofuscación solo se ejecuta cuando se ha ejecutado el compilador. Una compilación incremental que encuentra el ensamblado actualizado omite también Babel, de modo que el ensamblado ya ofuscado de
objnunca se procesa dos veces.
Mover el paso de ofuscación
Tres propiedades cambian el punto de inserción:
| Propiedad | Efecto |
|---|---|
RunBabelAfterBuild | Cuando es true, Babel se ejecuta al final de la compilación, después de que la salida se haya copiado en bin, y procesa $(TargetPath) en lugar del ensamblado intermedio. |
BabelAfterTargets | Ejecuta el paso de ofuscación después del destino de MSBuild indicado. |
BabelBeforeTargets | Ejecuta el paso de ofuscación antes del destino de MSBuild indicado. |
Al establecer cualquiera de ellas se desactiva la ubicación predeterminada después de CoreCompile. Con BabelAfterTargets o BabelBeforeTargets, Babel sigue procesando el ensamblado intermedio; si el destino elegido se ejecuta después de que la salida se haya copiado, haga que BabelInputFile y BabelOutputFile apunten a $(TargetPath).
Un uso típico es una aplicación Windows Forms con recursos localizados, en la que Babel debe ejecutarse una vez generados los ensamblados satélite para poder procesarlos también:
<PropertyGroup>
<BabelAfterTargets>CoreGenerateSatelliteAssemblies</BabelAfterTargets>
</PropertyGroup>Todo lo que se ejecuta entre la compilación y el paso de ofuscación desplazado ve el ensamblado sin ofuscar. Mantenga la ubicación predeterminada en los proyectos recortados, de archivo único y publicados con AOT, y en cualquier proyecto en el que un paso del SDK reescriba el IL después de la compilación.
Secuencia de destinos y puntos de extensión
El paso de ofuscación es el destino ObfuscateBuild. Primero prepara la configuración de la tarea Babel y después la ejecuta:
ObfuscateBuild
├─ ObfuscateSettings
│ ├─ ObfuscateDefaultSettings renaming defaults, license lookup, babelRules.xml, search directories
│ ├─ ObfuscateFrameworkSettings selects the assembly to process (obj, or $(TargetPath))
│ ├─ ObfuscateSetupBabelFiles BabelInputFile / BabelOutputFile, GenerateDebug when a PDB exists
│ ├─ ObfuscateCustomSettings empty, yours to redefine
│ ├─ SetupObfuscate empty, yours to redefine
│ └─ ConfigureBabel empty, yours to redefine
└─ Obfuscate
├─ BeforeObfuscate empty, yours to redefine
├─ CoreObfuscate runs the Babel task
└─ AfterObfuscate empty, yours to redefineRedefina un destino vacío en el archivo de proyecto para ejecutar sus propios pasos en ese punto:
| Destino | Se ejecuta | Úselo para |
|---|---|---|
ObfuscateCustomSettings, SetupObfuscate, ConfigureBabel | Después de que el paquete haya calculado sus valores predeterminados y los archivos de entrada y de salida, antes de que se ejecute Babel | Reemplazar propiedades calculadas como BabelInputFile, BabelOutputFile, GenerateDebug o los directorios de búsqueda. |
BeforeObfuscate | Justo antes de la tarea Babel | Ofuscar primero una dependencia, calcular ajustes a partir de las referencias resueltas, generar reglas. |
AfterObfuscate | Justo después de la tarea Babel | Copiar el archivo map o el de registro a otro lugar, ejecutar una comprobación sobre el ensamblado ofuscado. |
CoreObfuscate expone dos salidas que puede leer en AfterObfuscate: la propiedad BabelExitCode y el elemento @(BabelCommandLineArgs), que contiene la línea de comandos cuando BabelProvideCommandLineArgs es true.
Reemplazar la configuración de la tarea
El paquete configura la tarea Babel a partir del proyecto: los directorios de búsqueda a partir de las referencias, la clave de nombre seguro, el PDB, el archivo de reglas. Cuando los valores predeterminados no sirvan, ajústelos en BeforeObfuscate. El ejemplo siguiente fuerza la generación de los símbolos de depuración y sustituye los directorios de búsqueda por la carpeta de salida:
<Target Name="BeforeObfuscate">
<!-- Override computed properties -->
<PropertyGroup>
<GenerateDebug>true</GenerateDebug>
</PropertyGroup>
<!-- Replace the Babel search directories -->
<ItemGroup>
<BabelSearchDirectories Remove="@(BabelSearchDirectories)" />
<BabelSearchDirectories Include="$(TargetDir)" />
</ItemGroup>
</Target>BeforeObfuscate es también el lugar para ejecutar una segunda tarea Babel sobre una dependencia antes de que se ofusque el ensamblado principal, como hace el ejemplo Publicar una aplicación .NET para renombrar la interfaz pública de un paquete NuGet con el renombrado entre ensamblados.
Un destino AfterObfuscate puede recoger los artefactos que ha producido Babel, por ejemplo el archivo map, destinado a la carpeta compartida que usa el ejemplo Pruebas unitarias:
<PropertyGroup>
<GenerateMapOutFile>true</GenerateMapOutFile>
<BabelMapOutFile>$(IntermediateOutputPath)$(TargetFileName).map.xml</BabelMapOutFile>
</PropertyGroup>
<Target Name="AfterObfuscate">
<Copy SourceFiles="$(BabelMapOutFile)" DestinationFolder="$(SolutionDir)MapOut" />
</Target>Publicación
Como la ofuscación tiene lugar antes de los pasos de publicación, dotnet publish y los perfiles de publicación de Visual Studio generan una salida ofuscada sin configuración adicional. El paquete añade además tres adaptaciones:
- Los ensamblados combinados e incrustados se quitan del conjunto de publicación. El destino
UpdateBabelFilesToPublish, que se ejecuta después deComputeFilesToPublish, quita de los archivos que se publican todos los elementosMergeAssemblyyEmbedAssembly, junto con sus archivos.pdby.xml. EstablezcaBabelPublishEnabledenfalsepara conservarlos. - Los archivos
.deps.jsonse actualizan. Los destinosUpdateBabelBuildDependencyFileyUpdateBabelPublishDependencyFilequitan los ensamblados combinados e incrustados, y el propio paquete, de los manifiestos de dependencias de compilación y de publicación, de modo que el host no busca ensamblados que ya no existen como archivos independientes. EstablezcaBabelUpdateDependencyFileenfalsepara dejar los manifiestos como están. - Los símbolos de depuración no se publican en Release. El paquete establece
CopyOutputSymbolsToPublishDirectoryenfalsepara la configuración Release salvo que el proyecto la establezca, porque los archivos PDB proporcionan a un atacante los nombres de archivo y los números de línea del código original. Establézcala entruepara publicarlos de todos modos.
La publicación en un único archivo, recortada y con AOT funciona con el ensamblado ofuscado, con dos salvedades: la comprobación de manipulación de escritorio no puede verificar una imagen de archivo único, y Babel lo advierte (consulte Detección de manipulación), y en .NET MAUI para iOS el enlazador debe establecerse en Link SDK assemblies only (enlazar solo los ensamblados del SDK), como se explica en Ofuscar .NET MAUI.
Selección de las herramientas de compilación
El paquete incluye un conjunto de herramientas de compilación de Babel por cada host de MSBuild y lo selecciona según el host que ejecuta la compilación:
| Host de MSBuild | Carpeta de herramientas |
|---|---|
SDK de .NET 6.0, 7.0, 8.0, 9.0 o 10.0 (dotnet build, Visual Studio) | tools\net6.0 … tools\net10.0, según la versión del SDK |
| Cualquier otra versión del SDK de .NET | tools\net9.0 |
MSBuild de .NET Framework (MSBuild.exe) | tools\net472 |
| MSBuild de Mono | tools\Mono |
La carpeta seleccionada se expone como BabelTaskDir, y BabelPackageDir apunta a la raíz del paquete extraído. Para forzar otro conjunto de herramientas, establezca BabelTaskDir en el archivo de proyecto:
<PropertyGroup>
<BabelTaskDir>$(BabelPackageDir)tools\net8.0\</BabelTaskDir>
</PropertyGroup>Establézcala en el archivo de proyecto o en Directory.Build.targets, no en Directory.Build.props: el archivo .props del propio paquete se importa después de Directory.Build.props y sobrescribiría el valor.
Para ejecutar un Babel instalado fuera del paquete, por ejemplo la herramienta de línea de comandos extraída de un paquete zip babel_net*, establezca BabelPath en su carpeta y, si es necesario, BabelExe en el nombre del ejecutable (babel.exe o babel.dll).
Servidores de compilación
Nada en el paquete es específico de un equipo, de modo que un proyecto que se compila ofuscado en el PC de un desarrollador se compila ofuscado en cualquier agente que pueda restaurar el paquete y acceder a una licencia. Los ejemplos cubren los servicios habituales:
- GitHub Actions: paquete en GitHub Packages, clave de licencia tomada de un secreto del repositorio.
- Azure DevOps: paquete en una fuente de Azure Artifacts, clave de licencia tomada de una variable secreta del pipeline.
- AppVeyor: paquete en la fuente de la cuenta, clave de licencia tomada de una variable cifrada.
- Pruebas unitarias: pruebas de los ensamblados ofuscados en el mismo pipeline.
Los agentes y contenedores Linux ejecutan la compilación tools\netX.0 de Babel. Los hosts con una configuración FIPS de OpenSSL defectuosa necesitan los ajustes descritos en Conformidad con FIPS.