Skip to Content
Nueva versión 12 disponible 🎉
ObfuscatorPaquete NuGetPipeline de compilación

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 obj nunca se procesa dos veces.

Mover el paso de ofuscación

Tres propiedades cambian el punto de inserción:

PropiedadEfecto
RunBabelAfterBuildCuando 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.
BabelAfterTargetsEjecuta el paso de ofuscación después del destino de MSBuild indicado.
BabelBeforeTargetsEjecuta 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 redefine

Redefina un destino vacío en el archivo de proyecto para ejecutar sus propios pasos en ese punto:

DestinoSe ejecutaÚselo para
ObfuscateCustomSettings, SetupObfuscate, ConfigureBabelDespués de que el paquete haya calculado sus valores predeterminados y los archivos de entrada y de salida, antes de que se ejecute BabelReemplazar propiedades calculadas como BabelInputFile, BabelOutputFile, GenerateDebug o los directorios de búsqueda.
BeforeObfuscateJusto antes de la tarea BabelOfuscar primero una dependencia, calcular ajustes a partir de las referencias resueltas, generar reglas.
AfterObfuscateJusto después de la tarea BabelCopiar 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 de ComputeFilesToPublish, quita de los archivos que se publican todos los elementos MergeAssembly y EmbedAssembly, junto con sus archivos .pdb y .xml. Establezca BabelPublishEnabled en false para conservarlos.
  • Los archivos .deps.json se actualizan. Los destinos UpdateBabelBuildDependencyFile y UpdateBabelPublishDependencyFile quitan 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. Establezca BabelUpdateDependencyFile en false para dejar los manifiestos como están.
  • Los símbolos de depuración no se publican en Release. El paquete establece CopyOutputSymbolsToPublishDirectory en false para 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 en true para 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 MSBuildCarpeta 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 .NETtools\net9.0
MSBuild de .NET Framework (MSBuild.exe)tools\net472
MSBuild de Monotools\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.

Last updated on