Cross Assembly Renaming
Last updated
Last updated
During the obfuscation process, Babel Obfuscator renames all the symbols that are not externally visible to the assembly, which includes private and internal symbols. This means that Babel will change the names of fields, methods, classes, and other code elements that are not meant to be accessed outside of the assembly.
Babel will not rename symbols externally visible to the assembly, such as public symbols. This is because public symbols are meant to be accessed by other assemblies, and renaming them would break the application's functionality. Therefore, Babel only renames the symbols not meant to be accessed by other assemblies, ensuring that the application still works as intended.
However, Babel provides the ability to obfuscate both public and internal members across multiple assemblies. This is accomplished by fixing the names of the obfuscated symbols referenced in each assembly using XML map files.
This is because when an assembly is obfuscated, the names of its symbols are changed. Thus, any reference to these symbols made by another assembly must be updated to reflect the new names. By specifying these input and output XML map files, Babel Obfuscator can use them to fix cross-name references between all participating assemblies. This ensures that the obfuscated code works correctly and does not break due to incorrect symbol names.
It is important to keep map files private and not deploy them with the obfuscated application under any circumstances, as they can be used to reverse engineer the obfuscation and compromise the security of the application.
To setup cross assembly renaming we have to consider all the assemblies that partecipate to renaming process. Consider the main assembly application MainAssembly.dll which consumes the public interface of two external components: Library1.dll and Library2.dll. Where Library1.dll also need to access Library2.dll public interface according to the following scheme:
MainAssembly.dll
Library1.dll
Library2.dll
Library1.dll
Library2.dll
This configuration highlights the relationships between the assemblies involved in the obfuscation process. The first step is to configure Babel to obfuscate the public symbols in Library1.dll and Library2.dll. You can achieve this by adding the following assembly-level custom attribute to the source code of both libraries:
This attribute instructs Babel to obfuscate the public symbols of the specified assembly without the need for external XML rule files. Setting the Boolean parameter to true ensures that the assembly’s public interface is treated as private, allowing public member names to be safely obfuscated.
Alternatively, you can configure Babel to rename the public interface of an assembly using an XML rules file. This method provides greater flexibility and control, allowing you to selectively obfuscate parts of the public interface. Below is an example of an XML rule file named public.xml that forces the obfuscation of all public member names:
Compared to the ObfuscateAssembly attribute, the XML rule approach offers more granular control over which public symbols to obfuscate. Using the Pattern expression, you can specify which parts of the public interface should be obfuscated, allowing for tailored obfuscation strategies.
At this point, we have Library1.dll and Library2.dll configured to use either the ObfuscateAssembly attribute or the XML rule file (in this case, public.xml)
MainAssembly.dll
Library1.dll (configured with public.xml)
Library2.dll (configured with public.xml)
For each assembly that has been configured to rename its public interface, we need to enable the generation of an XML map file.
This file contains the mapping between the original symbol names and their obfuscated counterparts. The XML map file will be utilized by all assemblies participating in the obfuscation process that reference at least one assembly with a renamed public interface. This ensures proper name resolution across the obfuscated assemblies.
To obfuscate Library1.dll and Library2.dll, we use the following CLI syntax:
This first command obfuscates Library2.dll and generates an XML map file named Library2.map.xml, which contains the mapping between original symbol names and the obfuscated names.
Since Library1.dll references Library2.dll and consumes its public interface, when obfuscating Library1.dll, we must provide the Library2.map.xml file as input to ensure proper mapping of Library2.dll’s obfuscated symbols. Additionally, as we want to obfuscate the public interface of Library1.dll, we configure Babel to load the public.xml rule file and generate a corresponding XML map file for Library1.dll.
The CLI command for this step is as follows:
This ensures that Library1.dll correctly references the obfuscated symbols from Library2.dll, while also generating its own map file for subsequent use in the obfuscation process.
Finally, to obfuscate MainAssembly.dll, we need to configure Babel to load the XML map files for both Library1.dll and Library2.dll, as these assemblies are referenced by MainAssembly. This ensures that MainAssembly can correctly resolve the obfuscated symbols from its dependent libraries during the obfuscation process.
The CLI command for this step is:
This command takes in the previously generated map files (Library1.map.xml and Library2.map.xml) to ensure that the references to the obfuscated symbols in these libraries are properly handled in MainAssembly.
It’s crucial to follow the correct order when obfuscating assemblies. Libraries referenced by other assemblies, such as Library2.dll and Library1.dll, must be obfuscated first to generate the necessary map files. Then, dependent assemblies like Library1.dll and MainAssembly.dll can be obfuscated using the map files.
To configure cross-assembly renaming with MSBuild, it is necessary to specify the input and output XML map files for each assembly involved in the obfuscation project including the XML rule file. Each obfuscated assembly must generate an XML map file, which will then be provided as input to all other obfuscated assemblies that reference this target assembly.
Here's an example of how to configure cross-assembly renaming between one main assembly and two referenced assemblies arranged according to the following scheme.
MainAssembly.dll
Library1.dll
Library2.dll
Library1.dll
Library2.dll
We begin with the Library2 project, which has no dependencies. Since it doesn’t rely on any other assemblies, it can be obfuscated independently without requiring any input XML map files.
It is worth noticing that as Library1 references Library2, the obfuscation project, besides generating the XML map file with GenerateMapOutFile=true
, must also reference the mapping file generated for Library2.
As the MainAssembly project references the two libraries, Library1 and Library2, which have been obfuscated in their public interface, the Babel task needs to be configured to load the two XML mapping files generated for each library.
This ensures that any cross-referencing between Library1 and Library2 is handled correctly during the obfuscation process. Without referencing the XML map file generated for Library2, the obfuscation process for Library1 may not correctly handle cross-referencing between the two libraries, leading to potential issues at runtime. Therefore, it is essential to ensure that all necessary XML map files are generated and referenced correctly when configuring cross-assembly renaming.
In cases where the application to be configured for cross-assembly obfuscation comprises multiple components, selecting the appropriate obfuscation order can be a challenging task. However, the Babel Obfuscator provides a user-friendly interface that simplifies the process of setting up cross-assembly obfuscation.
To utilize this feature, drag and drop all the assemblies you wish to cross-obfuscate into the Input Grid. Then, right-click in the Input Grid and select "Setup Public Obfuscation" from the drop-down menu. This will enable the Babel Obfuscator to automatically generate an appropriate obfuscation order for the selected assemblies and set up the correct XML mapping files for every assembly in the obfuscation project including XML rules for enabling obfuscation of the public interface with minimal effort on your part.
To exclude an assembly from public obfuscation, you can easily do so using the Babel Obfuscator UI. Right-click on the Input Grid column header and select the "Column Chooser" from the drop-down menu, which will open the Customization dialog.
Drag and drop the "Rename Public" field into the Input Grid. Now you can uncheck the "Rename Public" checkbox for each assembly that should not have the public interface mangled. By unchecking this field, Babel will remove the obfuscation rule created to rename all public symbols exposed by the third-party assembly, effectively excluding it from the public obfuscation process.