VERSIONSHINWEISE

Was ist neu in Babel.

Änderungen an der Engine, den Lizenzverwaltungstools und dem Desktop-Arbeitsbereich, aus den Versionshinweisen des Produkts.

Veröffentlicht am 2. August 2026

Version 11.8.0.0

Babel Obfuscator

Verbesserungen

  • FIPS-Hosts — verwaltete AES-Verschlüsselung: Neu ist ein optionaler verwalteter AES-Entschlüsseler, ausgewählt mit --use encryption=aesmanaged (oder <Use>encryption=aesmanaged</Use> aus MSBuild). Assemblies, die mit Code- (MSIL-), Zeichenfolgen-, Wert-/Array- oder Ressourcenverschlüsselung geschützt sind, starten jetzt auch auf Hosts, deren kryptografischer Plattformanbieter unbrauchbar ist — vor allem Linux-Container mit defektem OpenSSL-FIPS-Zustand, wo die eingefügte Entschlüsselungslaufzeit bisher im Typinitialisierer eine OpenSslCryptographicException auslöste, bevor überhaupt Anwendungscode lief. Der Obfuscator verschlüsselt auf dem (intakten) Build-Host weiterhin mit dem Plattformanbieter und erzeugt denselben Geheimtext; nur der eigenständige Entschlüsseler in der Assembly ändert sich. Unterstützt unter .NET Framework und .NET (Core); netstandard und Mono behalten ihr bisheriges Verhalten. Siehe die Dokumentationsseite FIPS Compliance. Beachten Sie den Durchsatz des verwalteten Entschlüsselers von rund 40 MB/s: Kombinieren Sie ihn nicht mit Codeverschlüsselung und cache=false auf Methoden im heißen Pfad.
  • Leistung — große Assemblies: Drei heiße Pfade, die die Verschleierung sehr großer, code- und attributlastiger Assemblies dominierten, wurden neu geschrieben; die Ausgabe ist nachweislich byte-identisch mit 11.7.0:
    • Das Umbenennen benutzerdefinierter Attribute (RenameTypeAttributes) läuft jetzt indiziert statt in O(Typen × Attribute). Eine attributlastige Assembly von 41 MB mit rund 69.000 Typen (z. B. Microsoft.Graph), deren Umbenennungsphase zuvor nie fertig wurde, ist jetzt in etwa 20 s durch.
    • FindCallVertices im Aufrufgraphen läuft in O(Knoten) statt O(Knoten × Signaturen) — 7- bis 11-mal schneller bei DevExpress.XtraEditors / Spire.Pdf.
    • Die Gruppierung virtueller Member in der Umbenennungsphase wird nach Namen in Buckets sortiert (2074 ms → 17 ms bei DevExpress.XtraEditors). Insgesamt verkürzt das eine Verschleierung mit allen Features bei einer 7,9 MB großen DevExpress-Assembly um rund 24 %.
  • Dynamische Erkennung der Ziellaufzeit: Neu ist die dynamische Erkennung der Ziellaufzeitversion für verschleierte Assemblies.
  • Beispiel für die Bindung an einen Hardware-Dongle: Neu ist eine lauffähige, plattformübergreifende Referenzimplementierung, die zeigt, wie sich eine mit Codeverschlüsselung geschützte .NET-Anwendung an einen Hardware-Lizenz-Dongle (KEYLOK, SafeNet Sentinel, Wibu CodeMeter, Marx CrypToken, …) binden lässt, sodass ausgetauschte oder nachgebaute Dongle-DLLs den Schutz nicht umgehen können.
  • [Neu] Die Warnung OB0009 meldet einen Demomodus-Fall, der sich bisher aus der Ausgabe nicht diagnostizieren ließ: Werden Map-Dateien angegeben, ist die assemblyübergreifende Verschleierung aber nicht lizenziert, wird die Map übersprungen und Verweise auf umbenannte externe Symbole behalten ihre ursprünglichen Namen — die Assembly scheiterte dann erst zur Laufzeit mit einer TypeLoadException. Das wird jetzt schon beim Build gemeldet.

Fehlerbehebungen

  • Avalonia — Ressourcenverschlüsselung: Behoben, dass verschleierte Avalonia-Anwendungen beim Start mit einer FileNotFoundException auf avares://-Assets und XAML abstürzten, wenn die Ressourcenverschlüsselung aktiv war. Avalonia legt sämtliches XAML und alle Assets einer Assembly in einem einzigen !AvaloniaResources-Blob ab, den sein Asset-Loader direkt liest und dabei den von Babel eingefügten Entschlüsselungs-Hook umgeht. Dieser Blob bleibt jetzt unverschlüsselt (alle anderen Ressourcen werden weiterhin verschlüsselt), sodass Avalonia-Anwendungen sich mit aktiver Ressourcenverschlüsselung vollständig verschleiern lassen. WPF ist nicht betroffen. Für eine Avalonia-Anwendung als Einzeldatei verwenden Sie das Einbetten von Assemblies, nicht das Zusammenführen.
  • WPF — Zusammenführen von Theme-Wörterbüchern: Behoben, dass Steuerelement-Themes verloren gingen, wenn Assemblies zusammengeführt wurden, die beide ein BAML-Ressourcenwörterbuch unter demselben Pfad enthalten (typischerweise themes/generic.baml). Kollidierende ResourceDictionary-Streams neutraler Kultur bleiben jetzt unter eindeutigen Namen erhalten und werden über ein synthetisiertes Wörterbuch per MergedDictionaries eingebunden, wobei der Vorrang der Suche in der primären Assembly erhalten bleibt.
  • MAUI/XAML — x:-Sprachprimitive: Behoben, dass der XAML-Umbenenner das Präfix x: von Sprachprimitiven in x:TypeArguments entfernte (z. B. x:Double → Double). Das führte in .NET-MAUI-Release-Builds für iOS, die XAML zur Laufzeit laden, zum Absturz mit XamlParseException ("Type Double not found").
  • Umbenennung — selbstbezügliche Typverweise: Behoben, dass ein umbenannter Typ selbstbezügliche TypeReferences (im eigenen Modul) mit dem alten Namen zurückließ, was bei der Typinitialisierung eine System.TypeLoadException auslöste. IL-Weaver wie ArxOne.MrAdvice — und C#-Top-Level-Anweisungen über den internen Program-Typ — erzeugen ldtoken-Aliase, die sich danach nicht mehr auflösen ließen. Die Korrektur der TypeRefs im eigenen Modul läuft jetzt für jeden umbenannten Typ.
  • Umbenennung — Umschreiben von PropertyChanged-Zeichenfolgen: Behoben, dass das Umschreiben von ldstr nach der Umbenennung (das OnPropertyChanged("PropName") funktionsfähig hält) auch unbeteiligte, über Zeichenfolgen adressierte API-Argumente änderte — XAML-Steuerelementsuchen, Wörterbuchschlüssel, eigene Registrierungen — und zwar bei jedem Typ, der von einer INotifyPropertyChanged-Basisklasse erbt. Das Umschreiben beschränkt sich jetzt auf erkannte PropertyChanged-Senken. Gemeldet zu 8.7, reproduziert auf 11.7.
  • Kontrollfluss — Host-Typen mit externen Abhängigkeiten: Behoben wurden sporadische FileNotFoundException-Fehler zur Laufzeit (etwa SSIS 0xC0011008), verursacht dadurch, dass Dispatcher- und Switch-Flattening-Hilfsmethoden des Kontrollflusses in Typen abgelegt wurden, die beim Laden eine externe Assembly nachziehen. Die Auswahl des Host-Typs verwirft jetzt Typen mit Wertfeldern (rekursiv geprüft, einschließlich generischer Argumente und verschachtelter Werttypen) sowie Typen mit Basis- oder Schnittstellentypen außerhalb des Moduls oder der Kernbibliothek, und sie verwirft generische Host-Typen.
  • Lizenzverwaltung — ungültige Lizenz fiel stillschweigend in den Demomodus: Behoben, dass eine ausdrücklich angegebene, für die laufende Version aber ungültige Lizenzdatei weder beachtet noch gemeldet wurde: Der Lauf lief stillschweigend im Demomodus weiter und erzeugte eine zeitlich begrenzte Assembly ohne die lizenzierten Features, was meist erst viel später auffiel. Eine ausdrücklich angegebene Lizenz muss jetzt für dieses Produkt und diese Version gültig sein, sonst bricht Babel mit Error: the license provided is not valid for Babel Obfuscator <version>. ab und endet mit LicensingFailure (1, unter --strict-exit 40), ohne eine Assembly zu erzeugen. Ein Lauf ganz ohne Lizenz startet wie bisher den Demomodus mit eingeschränktem Funktionsumfang.
  • Testlizenzen unter Linux: Lizenzen mit einer Testbeschränkung auf Laufzeit oder Instanzenzahl konnten auf Linux-Hosts nicht validiert werden, auch beim NuGet-Task von Babel Obfuscator in Linux-Containern. Einzelheiten stehen in den Release Notes zu Babel Licensing 11.8.0.0.

Änderungen

  • Toolchain zur Selbstverschleierung: Das NuGet-Paket von Babel Obfuscator (sowie die Binärdateien babel, lic, HardwareId und Babel.Win) werden jetzt mit dem verwalteten AES-Algorithmus selbst verschleiert, sodass die ausgelieferten Werkzeuge auch auf Hosts mit defektem FIPS starten.

Babel Licensing

Verbesserungen

  • FIPS-Hosts — robuster Start: Babel Licensing übersteht jetzt FIPS-aktivierte Hosts, deren Container keinen zertifizierten OpenSSL-FIPS-Anbieter mitbringt (etwa ein RHEL-Host mit einem Ubuntu-basierten .NET-Container, dotnet/dotnet-docker#5849). Dort scheiterte die Lizenzprüfung bisher mit BabelLicenseException: Internal error — das Identitäts-Hashing von IsolatedStorage in .NET brach in SHA1.Create mit error:03000086 ab. Der Lizenzspeicher weicht jetzt auf einen verwalteten Dateispeicher aus, wenn sich IsolatedStorage nicht initialisieren lässt, ersetzt die AES-/DES-Cipher der Plattform im verschlüsselten Datumsspeicher durch bit-kompatible BouncyCastle-Cipher (vorhandene Speicherdateien bleiben in beide Richtungen lesbar) und verfolgt Daten nur noch im Arbeitsspeicher, wenn gar kein Speicher nutzbar ist — die Lizenzprüfung rührt damit den Krypto-Stack des Betriebssystems nicht mehr an. Ist der Babel Licensing-Dienst mit dem verwalteten AES-Algorithmus von Babel Obfuscator verschleiert (--use encryption=aesmanaged), startet auch der verschleierte Dienst auf Hosts mit defektem FIPS.
  • Aktivierungslizenzen — Weitergabe von Features beim Validieren: Wird einer Aktivierungslizenz ein Feature hinzugefügt, erreicht es bereits aktivierte Clients jetzt beim nächsten Validieren, statt eine vollständige Deaktivierung und Neuaktivierung zu erfordern. Sowohl der Aktivierungs- als auch der Validierungspfad bauen die maschinengebundene Lizenz aus der übergeordneten Lizenz (Features, Felder, Beschränkungen, Daten) plus der Hardwarebindung über einen gemeinsamen Helfer auf und signieren sie neu.

Fehlerbehebungen

  • gRPC-UserKey-Authentifizierung: Behoben, dass nach der Sicherheitshärtung in 11.7.0 sämtliche gRPC-Anmeldungen per UserKey fehlschlugen. GrpcAuthenticator.AuthenticateAsync ignorierte seinen Benutzernamen-Parameter und sendete stets die im Konstruktor erfasste Client-ID, wodurch UserKey-Anmeldungen auf den Identitäts-Login mit zwei Argumenten geleitet wurden. Eine optionale Brücke EnableLegacyUserKeyFallback (standardmäßig aus) lässt Betreiber mit vielen bereits ausgerollten Clientanwendungen die Kompatibilität wiederherstellen, ohne neu zu verteilen, während Neuinstallationen auf dem korrigierten Weg bleiben.
  • JSON-Schlüssel in Webhook-Payloads: Behoben, dass Webhook-Payloads für Lizenzen, Bestellungen und Berichte einbuchstabige JSON-Schlüssel (p, q, r, …) lieferten, wenn der Licensing-Dienst mit Symbolumbenennung verschleiert ist. Die Payloads verwenden jetzt benannte DTOs, die jeden Schlüssel über [JsonPropertyName] festnageln (camelCase), sodass der Webhook-Vertrag gegen Symbolumbenennung und Zeichenfolgenverschlüsselung immun ist.
  • Testlizenzen — Linux-Hosts ohne Shared-Memory-Bereich: Behoben, dass eine Lizenz mit einer Testbeschränkung auf Laufzeit oder Instanzenzahl mit Object reference not set to an instance of an object durchfiel, sodass IsValid false zurückgab, während dieselbe Lizenz unter Windows und macOS korrekt validierte. Gemeldet für Linux-Container. Application.StartTime und Application.InstanceCount lasen den Shared-Memory-Bereich bedingungslos, der aber nur gefüllt wird, wenn er sich öffnen lässt; ließ er sich nicht anlegen, lösten beide Member eine Ausnahme aus, und TrialRestriction.Validate scheiterte mit einem nichtssagenden Fehler. Der Bereich gilt jetzt als optional, und die beiden Werte fallen auf prozesslokale Werte zurück — Startzeit des Prozesses und die vorhandene Ersatzzählung der Prozesse — statt eine Ausnahme auszulösen. Eine auf null gesetzte Erstellungszeit wird genauso behandelt, da sonst jede Testlaufzeit als bereits abgelaufen erschiene. Keine Regression: In 11.6.0, 11.7.0, 11.7.0.3 und 11.8.0 war das Verhalten identisch.
  • Linux — Bindung der POSIX-Semaphor-Bibliothek: Behoben wurde die eigentliche Ursache des vorigen Fehlers: Der Shared-Memory-Bereich ließ sich auf einem glibc-Linux-Host nie öffnen. Die ihn absichernden sem_*-Einsprungpunkte wurden aus librt importiert — einen Namen, den die .NET-Laufzeit als librt.so und liblibrt.so sucht, nie aber als den installierten Soname librt.so.1; der unversionierte Symlink liegt dem Entwicklungspaket bei, das Container-Images nicht enthalten. Jeder Aufruf scheiterte daher mit einer DllNotFoundException an der Bindung. Das brach nicht nur Testbeschränkungen, sondern degradierte auf allen Linux-Hosts stillschweigend Application.StartTime und Application.InstanceCount zu prozesslokalen Werten. Der Import verwendet jetzt den Soname, und ein DllImportResolver probiert zusätzlich libpthread.so.0, libc.so.6 und die musl-libc-Namen — damit sind glibc vor und nach der Zusammenlegung von sem_* in libc mit Version 2.34 sowie musl abgedeckt. Prozessübergreifende Instanzzählung und die gemeinsame Anwendungsstartzeit verhalten sich unter Linux jetzt so wie seit jeher unter Windows. Hosts mit Alpine/musl waren nicht betroffen. SharedMemory.Open meldet einen nicht verfügbaren Bereich außerdem zurück, statt beim Aufrufer eine Ausnahme auszulösen, sodass Hosts ohne benannte Semaphore über den prozesslokalen Ersatzweg weiterarbeiten.
  • Babel Licensing-Dienst — automatisch erzeugter JWT-Signaturschlüssel: Behoben, dass jeder Aufruf mit einem ausgestellten Token mit 401 fehlschlug — und damit keine Lizenz aktivierbar war —, wenn Application:SigningKey leer blieb. Der beim Start zufällig erzeugte Schlüssel wurde nur einer abgekoppelten Kopie des Konfigurationsabschnitts Application zugewiesen, während TokenService IOptionsSnapshot<ApplicationSettings> auflöst und erneut aus der Konfiguration bindet; Tokens wurden also mit einem Schlüssel aus Auffüll-Leerzeichen signiert und gegen den erzeugten Schlüssel geprüft. Das Dienstprotokoll machte die Diagnose schwer, weil es unmittelbar vor dem 401 eine erfolgreiche Authentifizierung meldete. Der erzeugte Schlüssel wird jetzt über PostConfigure<ApplicationSettings> angewendet, sodass jede gebundene Optionsinstanz mit demselben Schlüssel signiert und prüft. Ein ausdrücklich konfigurierter Schlüssel bleibt die empfohlene Einstellung für den Produktivbetrieb: Ein erzeugter Schlüssel ändert sich bei jedem Neustart und wird nicht zwischen Instanzen geteilt.