Skip to Content
Nuova versione 12 disponibile 🎉
ObfuscatorPacchetto NuGetPipeline di build

Pipeline di build

Dove il pacchetto esegue Babel all’interno della pipeline di MSBuild, come spostare quel passo, i target a cui puoi agganciarti, che cosa succede in pubblicazione e come vengono selezionati gli strumenti di build.

Dove viene eseguito l’offuscamento

Per impostazione predefinita il pacchetto esegue Babel subito dopo CoreCompile, sull’assembly che il compilatore ha appena scritto nella cartella intermedia, $(IntermediateOutputPath)$(TargetFileName), cioè la cartella obj. Ogni passo successivo della build lavora quindi sull’assembly offuscato: la copia in bin, la generazione di .deps.json, gli assembly satellite e, in pubblicazione, il trimming, la creazione del bundle a file singolo, la compilazione ReadyToRun o NativeAOT e il confezionamento in un APK o in un bundle dell’app.

Questo ordine è il motivo per usare il pacchetto nei progetti in stile SDK. L’SDK .NET riscrive l’IL dopo la compilazione, e Babel deve vedere l’assembly prima che ciò avvenga; un assembly preso da bin o dalla cartella di pubblicazione ha già attraversato quei passi. Collocare a mano il task dopo CoreCompile è una soluzione fragile, perché la sequenza esatta dei target dipende dal tipo di progetto e dalla versione dell’SDK. Il pacchetto risolve il problema per te.

Altre due regole mantengono reattivo l’IDE:

  • Le build in fase di progettazione vengono saltate. Visual Studio e gli analizzatori di codice eseguono continuamente build in background; il pacchetto non vi inserisce il passo di offuscamento.
  • L’offuscamento viene eseguito solo quando è stato eseguito il compilatore. Una build incrementale che trova l’assembly aggiornato salta anche Babel, così l’assembly giĂ  offuscato in obj non viene mai elaborato due volte.

Spostare il passo di offuscamento

Tre proprietĂ  cambiano il punto di inserimento:

ProprietĂ Effetto
RunBabelAfterBuildQuando è true, Babel viene eseguito alla fine della build, dopo la copia dell’output in bin, ed elabora $(TargetPath) invece dell’assembly intermedio.
BabelAfterTargetsEsegue il passo di offuscamento dopo il target MSBuild indicato.
BabelBeforeTargetsEsegue il passo di offuscamento prima del target MSBuild indicato.

Impostarne una qualsiasi disabilita il posizionamento predefinito dopo CoreCompile. Con BabelAfterTargets o BabelBeforeTargets Babel elabora comunque l’assembly intermedio; se il target scelto viene eseguito dopo la copia dell’output, fai puntare BabelInputFile e BabelOutputFile a $(TargetPath).

Un uso tipico è un’applicazione Windows Forms con risorse localizzate, in cui Babel deve essere eseguito dopo la generazione degli assembly satellite per poter elaborare anche quelli:

<PropertyGroup> <BabelAfterTargets>CoreGenerateSatelliteAssemblies</BabelAfterTargets> </PropertyGroup>

Tutto ciò che viene eseguito tra la compilazione e il passo di offuscamento spostato vede l’assembly non offuscato. Mantieni il posizionamento predefinito per i progetti pubblicati con trimming, a file singolo o con AOT, e per qualsiasi progetto in cui un passo dell’SDK riscrive l’IL dopo la compilazione.

Sequenza dei target e punti di estensione

Il passo di offuscamento è il target ObfuscateBuild. Prima prepara la configurazione del task Babel, poi lo esegue:

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

Ridefinisci un target vuoto nel file di progetto per eseguire i tuoi passi in quel punto:

TargetQuando viene eseguitoUsalo per
ObfuscateCustomSettings, SetupObfuscate, ConfigureBabelDopo che il pacchetto ha calcolato i suoi valori predefiniti e i file di input e di output, prima dell’esecuzione di BabelSovrascrivere le proprietà calcolate, come BabelInputFile, BabelOutputFile, GenerateDebug o le cartelle di ricerca.
BeforeObfuscateSubito prima del task BabelOffuscare prima una dipendenza, calcolare le impostazioni dai riferimenti risolti, generare le regole.
AfterObfuscateSubito dopo il task BabelCopiare altrove il file map o il file di log, eseguire un controllo sull’assembly offuscato.

CoreObfuscate pubblica due output che puoi leggere in AfterObfuscate: la proprietà BabelExitCode e l’elemento @(BabelCommandLineArgs), che contiene la riga di comando quando BabelProvideCommandLineArgs è true.

Sovrascrivere la configurazione del task

Il pacchetto configura il task Babel a partire dal progetto: le cartelle di ricerca ricavate dai riferimenti, la chiave con nome sicuro, il PDB, il file di regole. Quando i valori predefiniti non vanno bene, correggili in BeforeObfuscate. L’esempio seguente forza la generazione dei simboli di debug e sostituisce le cartelle di ricerca con la cartella di output:

<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 è anche il punto in cui eseguire un secondo task Babel su una dipendenza prima che venga offuscato l’assembly principale, come fa l’esempio Pubblicare un’app .NET per rinominare l’interfaccia pubblica di un pacchetto NuGet con la ridenominazione cross-assembly.

Un target AfterObfuscate può raccogliere gli artefatti prodotti da Babel, per esempio il file map da copiare in una cartella condivisa usata dall’esempio Test unitari:

<PropertyGroup> <GenerateMapOutFile>true</GenerateMapOutFile> <BabelMapOutFile>$(IntermediateOutputPath)$(TargetFileName).map.xml</BabelMapOutFile> </PropertyGroup> <Target Name="AfterObfuscate"> <Copy SourceFiles="$(BabelMapOutFile)" DestinationFolder="$(SolutionDir)MapOut" /> </Target>

Pubblicazione

Poiché l’offuscamento avviene prima dei passi di pubblicazione, dotnet publish e i profili di pubblicazione di Visual Studio producono un output offuscato senza configurazione aggiuntiva. Il pacchetto aggiunge tre adattamenti:

  • Gli assembly uniti e incorporati vengono rimossi dall’insieme dei file da pubblicare. Il target UpdateBabelFilesToPublish, eseguito dopo ComputeFilesToPublish, toglie dai file da pubblicare ogni elemento MergeAssembly ed EmbedAssembly, insieme ai relativi file .pdb e .xml. Imposta BabelPublishEnabled su false per mantenerli.
  • I file .deps.json vengono aggiornati. I target UpdateBabelBuildDependencyFile e UpdateBabelPublishDependencyFile rimuovono gli assembly uniti e incorporati, e il pacchetto stesso, dai manifesti delle dipendenze di build e di pubblicazione, così l’host non cerca assembly che non esistono piĂą come file separati. Imposta BabelUpdateDependencyFile su false per lasciare invariati i manifesti.
  • I simboli di debug non vengono pubblicati in Release. Il pacchetto imposta CopyOutputSymbolsToPublishDirectory su false per la configurazione Release, a meno che non lo imposti il progetto, perchĂ© i file PDB danno a un attaccante i nomi dei file e i numeri di riga del codice originale. Impostalo su true per pubblicarli comunque.

La pubblicazione a file singolo, con trimming e con AOT funziona con l’assembly offuscato, con due avvertenze: il controllo delle manomissioni desktop non può verificare un’immagine a file singolo, e Babel lo segnala con un avviso (vedi Rilevamento delle manomissioni), e per .NET MAUI iOS il linker va impostato su Link SDK assemblies only, come spiegato in Offuscare .NET MAUI.

Selezionare gli strumenti di build

Il pacchetto include un set di strumenti di build di Babel per ogni host MSBuild e lo seleziona in base all’host che sta eseguendo la build:

Host MSBuildCartella degli strumenti
SDK .NET 6.0, 7.0, 8.0, 9.0 o 10.0 (dotnet build, Visual Studio)tools\net6.0 … tools\net10.0, in base alla versione dell’SDK
Qualsiasi altra versione dell’SDK .NETtools\net9.0
MSBuild di .NET Framework (MSBuild.exe)tools\net472
MSBuild di Monotools\Mono

La cartella selezionata è esposta come BabelTaskDir, e BabelPackageDir punta alla radice del pacchetto estratto. Per forzare un set di strumenti diverso, imposta BabelTaskDir nel file di progetto:

<PropertyGroup> <BabelTaskDir>$(BabelPackageDir)tools\net8.0\</BabelTaskDir> </PropertyGroup>

Impostalo nel file di progetto o in Directory.Build.targets, non in Directory.Build.props: il file .props del pacchetto viene importato dopo Directory.Build.props e sovrascriverebbe il valore.

Per eseguire un Babel installato al di fuori del pacchetto, per esempio lo strumento da riga di comando estratto da un pacchetto zip babel_net*, imposta BabelPath sulla sua cartella e, se serve, BabelExe sul nome dell’eseguibile (babel.exe o babel.dll).

Server di build

Nel pacchetto non c’è nulla che dipenda da un computer specifico, quindi un progetto che produce una build offuscata sul PC di uno sviluppatore la produce anche su qualsiasi agente in grado di ripristinare il pacchetto e di raggiungere una licenza. Gli esempi coprono i servizi più comuni:

  • GitHub Actions: pacchetto su GitHub Packages, chiave di licenza da un segreto del repository.
  • Azure DevOps: pacchetto su un feed Azure Artifacts, chiave di licenza da una variabile segreta della pipeline.
  • AppVeyor: pacchetto sul feed dell’account, chiave di licenza da una variabile cifrata.
  • Test unitari: test degli assembly offuscati nella stessa pipeline.

Gli agenti e i container Linux eseguono la build tools\netX.0 di Babel. Gli host con una configurazione FIPS di OpenSSL non funzionante richiedono le impostazioni descritte in ConformitĂ  FIPS.

Last updated on