Versione 11.6.0.0
Babel Obfuscator
Rilasciata il 20 febbraio 2026
Miglioramenti
- Babel UI - navigazione delle regole: Migliorato il caricamento delle regole con il parsing XML asincrono e una maggiore reattività dell'interfaccia con insiemi di regole di grandi dimensioni. Aggiunta una navigazione intelligente delle regole con overlay di avanzamento e possibilità di annullare, corretti alcuni problemi di sicurezza tra thread e ottimizzata la logica di espansione dei nodi delle regole per evitare il blocco dell'interfaccia durante le operazioni sull'albero.
- Attributi generici (C# 11): Aggiunto il supporto alla lettura e alla scrittura di attributi personalizzati con parametri di tipo generici (ad esempio
MyAttribute<double>). PortatoGenericParameterResolverdall'upstream di Mono.Cecil per risolvereElementType.Varnelle firme dei costruttori degli attributi. RisolveNotImplementedException: Unknown primitive typedurante l'elaborazione di assembly .NET 9.0 che usano attributi generici. - Vincolo generico ByRefLike (.NET 9): Aggiunti
GenericParameterAttributes.AllowByRefLikeConstraint(0x0020) e la corrispondente proprietàGenericParameter.AllowByRefLikeConstraintper supportare il vincolo genericoallows ref struct. - Convenzione di chiamata Unmanaged: Aggiunta
MethodCallingConvention.Unmanaged(0x9) per supportare i puntatori a funzionedelegate* unmanaged. - Attributo AggressiveOptimization: Aggiunti
MethodImplAttributes.AggressiveOptimization(0x0200) e la corrispondente proprietàMethodDefinition.AggressiveOptimization.
Correzioni di bug
- WriteCompressedInt32: Riscritto l'algoritmo di codifica ECMA-335 degli interi con segno compressi per allinearlo a
System.Reflection.Metadata. L'implementazione precedente produceva codifiche errate per alcuni valori negativi (ad esempio -9076), il che poteva corrompere i metadati durante la scrittura di assembly con determinati valori costanti o blob di attributi personalizzati. - Risoluzione tra metodi di istanza e statici: Corretto
MetadataResolver.GetMethodperché confronti il flagHasThis, così un metodo statico e uno di istanza con lo stesso nome e gli stessi tipi di parametri non vengono più considerati identici. Questo è necessario per la corretta risoluzione dei membri di interfaccia statici astratti o virtuali (C# 11). - Refuso in AggressiveOptimization: Corretto il refuso
AggressiveOptimizatios→AggressiveOptimizationin Mono.Cecil e nel codice del plugin dell'offuscatore. - Sovrascrittura di MaxStackSize (crash su Android/ARM64): Risolto il comportamento di
CodeWriter.ComputeHeader()in Mono.Cecil, che sovrascriveva incondizionatamentebody.max_stack_sizecon il valore calcolato, scartando le correzioni apportate dagli algoritmi di offuscamento del flusso di controllo (goto +3, switch +1/2, if +1). Su CoreCLR ARM64 (ad esempio .NET 10 Android) questo causava una corruzione dello stack frame che si manifestava come valori di parametro null nei metodi offuscati. La correzione conserva il maggiore tra il valore calcolato e quello corretto dall'algoritmo, in linea con il comportamento già presente inReplaceCodeWriter. - ControlFlowIfAlgorithm senza correzione di MaxStackSize: L'algoritmo di scrambling degli if era l'unico algoritmo di flusso di controllo a non correggere
MaxStackSizenel proprioEndMethod. Aggiunta la correzione+1per tenere conto del patternldc.i4.0/ldc.i4.1+brtrue/brfalseche inserisce nei punti di diramazione. - ControlFlowGotoAlgorithm, salto condizionale all'indietro (crash su Android): L'algoritmo di scrambling dei goto inseriva predicati opachi dopo
lastInstructioncon un salto condizionale all'indietro (bgt/blt/beq) versofirstInstruction.Next. Su .NET Android (interprete/JIT CoreCLR x86_64) questi salti condizionali all'indietro venivano interpretati come back-edge di un ciclo, causando una generazione di codice errata che si manifestava con valori di parametro null. In particolare, era la combinazione IF+GOTO a innescare il problema, perché il salto condizionale all'indietro del GOTO finiva in mezzo ai pattern di diramazione trasformati dall'IF. La correzione ristruttura il predicato opaco collocandolo trafirstInstructione l'istruzione successiva, in modo che tutti i salti siano solo in avanti. Questo elimina il salto condizionale all'indietro mantenendo la stessa forza di offuscamento (i decompilatori continuano a non poter determinare quale percorso in avanti venga preso senza valutare il predicato opaco). - Flusso di controllo su .NET Android/iOS: Risolto il fatto che
ControlFlowAddMethodToken(token) eControlFlowStackUnderflow(underflow) non venivano disattivati per gli assembly .NET Android e iOS. Queste funzionalità non sono supportate su MonoVM, ma venivano disattivate solo per gli assembly Xamarin legacy (MonoAndroid/Xamarin.iOS). Gli assembly .NET Android/iOS moderni (ad esempionet10.0-android) sono classificati come.NETCoreAppe aggiravano quindi la logica di disattivazione specifica per Mono. Il codice mortoldtokeninserito dall'opzione token poteva far compilare male i metodi al JIT di MonoVM, con parametri null a runtime. - Metodi sensibili allo stack con DynamicProxy (.NET 10): Risolto il comportamento di
Assembly.GetExecutingAssembly()eAssembly.GetCallingAssembly()che restituivano l'assembly sbagliato quando DynamicProxy è attivo. Questi metodi usano un percorso interno dello stack (StackCrawlMark) per determinare l'assembly chiamante. Quando venivano sottoposti a proxy tramite un delegate, i frame aggiuntivi facevano risolvere al runtime di .NET 10 un assembly diverso (ad esempioSystem.Private.CoreLib) conLocationvuota, facendo restituire null aPath.GetDirectoryName(Assembly.GetExecutingAssembly().Location). La correzione esclude i metodi sensibili allo stack dall'elaborazione di DynamicProxy, preservando le chiamate dirette.
Babel Licensing
Correzioni di bug
- Babel UI: Risolto il problema per cui le chiavi delle licenze node-locked non venivano rigenerate quando cambiava la data di scadenza della licenza di attivazione padre, così la chiave di licenza firmata conservava date di scadenza obsolete pur essendo aggiornati i record nel database.
- Servizio Babel Licensing: Risolto il problema per cui la chiave di licenza ASCII non veniva rigenerata con le date di scadenza aggiornate quando la data di scadenza di una licenza di attivazione veniva modificata tramite il Management Controller, così la chiave firmata restava obsoleta pur essendo il database aggiornato correttamente.
- Accesso concorrente all'archivio delle licenze: Aggiunta una logica di ritentativo per la lettura e la scrittura dell'archivio delle licenze, in modo da gestire i conflitti di lock sui file quando più processi vi accedono contemporaneamente, evitando gli errori intermittenti "License component not available".

