.NET 6 obfuscation

Viewed 2246

I'm trying to obfuscate an .exe file obtained after compiling my .NET 6 project with the "Produce a single file" option, the problem is that no obfuscator works on it, I wanted to know if anyone knows why?

Thanks in advance for your answer

3 Answers

You have to obfuscate main application dll, which is located in the "obj\Release\net6.0-windows\win-x64" folder and copy obfuscated dll to the path.

Here is a working example using Obfuscar. These lines are located in the .csproj file.

    <Target Name="Obfuscation" AfterTargets="AfterCompile" Condition="'$(PublishProtocol)'!=''">
        <Exec Command="&quot;$(Obfuscar)&quot; obfuscar.xml" />
    </Target>
    <Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(PublishProtocol)'!=''">
        <Exec Command="COPY &quot;C:\Users\Application\obj\Release\net6.0-windows\win-x64\Obfuscated\Application.dll&quot; &quot;C:\Users\Application\obj\Release\net6.0-windows\win-x64\Application.dll&quot;" />
    </Target>

After that, when you publish single file exe, your application code inside the archive will be obfuscated.

Skater Obfuscator protects .NET 6 assemblies. It supports .NET 6 projects where the publish output is a DLL file (Framework-dependent deployment). When the publish output is an EXE file that calls .NET 6.0 DLL (Self-contained deployment) the final DLL has to be obfuscated as well. There are two types of .NET 6.0 apps can be built:

Framework-dependent deployment. As the name implies, framework-dependent deployment (FDD) relies on the presence of a shared system-wide version of .NET 6 on the target system. Because .NET 6 is already present, your app is also portable between installations of .NET 6. Your app contains only its own code and any third-party dependencies that are outside of the .NET 6.0 libraries. FDDs contain .dll files that can be launched by using the dotnet utility from the command line. For example, dotnet app.dll runs an application named app.

Self-contained deployment. Unlike FDD, a self-contained deployment (SCD) doesn't rely on the presence of shared components on the target system. All components, including both the .NET 6 libraries and the .NET 6 runtime, are included with the application and are isolated from other .NET 6 applications. SCDs include an executable (such as app.exe on Windows platforms for an application named app), which is a renamed version of the platform-specific .NET 6 host, and a .dll file (such as app.dll), which is the actual application. The .NET 6 app development is following the Self-Contained Deployment (SCD) concept. Let’s take a look at what the final binaries were compiled in the output folder of the WindowsFormsApp project. dot_net_6 You can see two main assemblies presented inside the output folder: WindowsFormsApp.exe WindowsFormsApp.dll This pair of files represents the .NET 6 Self-Contained Deployment (SCD) concept. The final output for that Windows Forms app includes the WindowsFormsApp.exe executable, which is a renamed version of the platform-specific .NET 6 host, and the WindowsFormsApp.dll library file, which is the actual application. So, the WindowsFormsApp.exe executable is the app’s starter with necessary predefined .NET 6 utilities compiled inside the exe. Ideally the exe file is cross-platform executable. The executable is binary file compiled in machine codes. This file is cannot be decompiled and do not need to be obfuscated.

Finally, you have to concentrate on WindowsFormsApp.dll assembly protection. Read instructions how Skater secures .NET 6 source codes

When you publish a .NET application as a single file, the actual code is located in the DLL file. The EXE file is just a launcher.

Returning to the obfuscation, the idea is to obfuscate the assembly right after it is placed to the intermediate directory by a compiler. E.g. if you use ArmDot you just write:

<Target Name="Protect" AfterTargets="AfterCompile" BeforeTargets="BeforePublish">
    <ItemGroup>
        <Assemblies Include="$(ProjectDir)$(IntermediateOutputPath)$(TargetFileName)" />
    </ItemGroup>
    <ArmDot.Engine.MSBuildTasks.ObfuscateTask
    Inputs="@(Assemblies)"
    ReferencePaths="@(_ResolveAssemblyReferenceResolvedFiles->'%(RootDir)%(Directory)')"
    SkipAlreadyObfuscatedAssemblies="true"
    />
</Target>

The same approach can be used with any obfuscator. The key thing is to use the following path: $(ProjectDir)$(IntermediateOutputPath)$(TargetFileName).

After that, the obfuscated assembly (DLL) is published.

Related