Obfuscator for .NET Core Single Publish Files - .net-core

Is there an obfuscation tool that can work well on the exe and pdb files that result from a dotnet core single file publish?
I am using dotnet core single file publish with the command: dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true. This works great in giving me just two neat files an exe and a pdb file, which I am able to give to a client to run my application.
However, I am still concerned about its ability to be decompiled.
I tried using ILSpy and JustCompile on both the files and they luckily could not be decompiled with these tools. Is it then that my files are safe, or it is that the tools have not yet caught up?
If the latter, what obfuscation tool can I use to protect these files? I attempted to use Obfuscar which did not work specifically on the single file publish outputs, the exe and pdb.
Any suggestions on the obfuscation tools to use for this?

Disclosure: I work for the Dotfuscator team at PreEmptive.
We have tested and verified that Dotfuscator Professional handles this scenario on both .NET Core 3 and .NET 5.
Specifically, you must use Dotfuscator Professional's MSBuild integration, which is now our recommended method of using Dotfuscator Professional for new projects. However, Dotfuscator will not update .pdb files on .NET Core or .NET 5, so you will not be able to debug builds which use Dotfuscator (e.g., Release builds). You should not ship .pdb files to untrusted users.

You can decompile .NET Core self-contained executables if you manually unpack them:
Can .Net Core 3 self-contained single executable be decompiled?
You would have to run the obfuscator as part of the build process, before the individual assemblies are compressed into the single file. That's probably possible if you add a custom MSBuild target that executes the obfuscator, and use the BeforeTargets attribute to integrate it at the correct point in the build process. But I haven't looked at the .NET core build system in detail.

You can use Obfuscar.
Use it in obj directory after target Compile and then copy obfuscated files to directory.(replace with original files)

Related

Why when compiling .NET Core console application we end up with both dll and exe files?

I have noticed that both dll and exe files with the name of the project are created on Windows when compiling a .NET Core console application. Why is that? In full .Net framework only the exe file would be created.
Prior to .Net Core 3.0, only the dll was created (although you could still do a single file build that was platform-dependent). In these cases you had to use the command dotnet MyProject.dll to start your program.
With .Net Core 3.0, they added the exe, which is still really just a wrapper around the command above. On other operating systems it also creates an executable file, it just names it MyProject instead of MyProject.exe
If people have old scripts that still make the dotnet command, this setup doesn't break them, but if you want to just use an exe, you can do that too.

MSBuild how to create a web deploy package for .NET Core apps without producing zip file

So what I'm trying to do is build a .NET Core app with MSBuild, and have it create the web deploy folder but without automatically putting it in a zip file. I can do this for .NET Framework apps by using /p:WebPublishMethod=Package and /p:PackageAsSingleFile=false, it creates the same folder structure but without adding it to a zip file. However with a .NET Core app, it seems to ignore this flag and always zips up the final package.
The reason I do not want it zipped up is I need to add a number of "custom" files to the build before I can deploy it. I can't add the files during the build itself because we have a number of different clients, and they all share the same "base" software, and then the client specific files need to be added afterwords. So I want to build the "base" software, then be able to copy the output folder, add the client specific files, and then zip up that build to be deployed to IIS. This saves a tremendous amount of time because the alternative is doing a new build for each client, even though 95% of the software is the same.
So is there a different way to accomplish this with .NET Core apps?
I've been testing with MSBuild via command line. The solution has a mix of .NET Framework and .NET Core asp.net websites. This is what i'm running:
msbuild.exe "Solution.sln" /nologo /nr:false /p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=false /p:SkipInvalidConfigurations=true /p:PreBuildEvent="" /p:PostBuildEvent="" /p:BasePackageLocation="C:\Temp\BuildOutput" /p:platform="any cpu" /p:configuration="release"
This works for the .NET Framework websites, but the .NET Core websites continue to be zipped up
And just a note that the BasePackageLocation is a custom property that sets the PackageLocation to "$(BasePackageLocation)\$(MSBuildProjectName)\" so that each website is put in its own sub-directory
So is there a different way to accomplish this with .NET Core apps?
Sorry but the answer could be negative. This is one issue about publishing .net core projects, it has been reported to Product Team, there might be a long way to go before the fix.
For web deploy package mode in .net core, you'll get WebApplication.deploy.cmd in the same folder where the .zip exists, many commands in the xx.cmd are associated with the xx.zip, so it's not recommended to manually do something to unzip it.
I suggest we can track the issue there(DC) and I will update the answer if there's any update or fix :)

In a cross-platform .NET Core executable, how can I specify paths to native dependencies / where do I put them?

I've been using p/invoke to call some native dependencies in a cross-platform web app on .NET Core. This only works because I've specifically installed and ldconfiged those dependencies.
Ideally I'd like to be able to run dotnet publish --self-contained against the appropriate platform and have that command include all the so files it needs, whereever they need to be, without ldconfig. I don't know if this is possible.
So my questions are:
Where does .NET core look for native dependencies if you do not use ldconfig? Does it matter if its a web app?
If the answer to (1) is not "nowhere," how can I include these dependencies when I do dotnet publish?
The self-contained option is meant to create a portable publish option. The output folder would contain all required native and any set up required to run in the specified platform without the need of installations. All dll dependencies must be in the bin folder.

Can I shrink a dotnet publish package

I have recently started developing using dotnet core (as opposed to old fashion plain .net) to create a number of small utility console applications.
The development is fine and it has come to the point I want to publish them.
I am using the CLI and as I am only interested in Win 10 deployments, tried
dotnet publish -c release -r win10-x64
It worked and built me a "publish" folder where everything seemed to work, though the "publish" folder is huge (~70mb) compared to the size of the app (~500 lines of code).
As I am only going to deploy to Win10 machines is there a way to package this so I don't need all the .NET files? I thought that was what the -r option was for but that does not seem to have achieved much.
It depends on how you want to deploy your app/who is going to use them.
The -r flag creates a self-contained app. This causes the publish command to include the necessary .NET Core DLL's for the specified platform (and platform specific nuget packages if they are avaiable), which means anyone can use the app without having to install .NET Core runtime.
If you remove the -r flag then publish will only include the DLL's for you app. But this means whoever wants to use your app must first install the .NET Core runtime.
You can see the difference by using the -o flag to write the publish output to different directories e.g.
dotnet publish -c release -r win10-x64 -o ./publish-win10
or
dotnet publish -c release -o ./publish-any
Now go and have a look at what has been written to ./publish-win10 and ./publish-any folders and you can the difference.
If you are installing them onto a system where the .NET Core runtime is already present then you can just distribute the DLL and save a lot of space. However if you want to be able to distribute the app without the end user having to worry about having the .NET Core runtime installed then the -r flag to create a self-contained distribution is the way to go, but results in the 'package' including the necessary .NET Core assemblies.
AFAIK the -r flag does not affect how you app is compiled, just what runtime DLL's are included as part of the publish command. So you always get the same DLL for your code if you publish it for win10-x64 or with, or without, the -r flag so your app DLL will run on any (.NET Core compatible) platform, but I am happy to be corrected on that point.
Unlike .NET 4.x which you are used to where building is the standard to create an output, .NET Core (And .NET 5) considers building and publishing to be very different.
The huge (70MB) size is because the publisher is assuming that your target does not have any form of the .NET Framework installed, so is bundling it in with your project.
You can change your publish line to
dotnet publish -r win-x64 --self-contained false
Just by itself, this will create the .NET Core standard - A .dll (Your application), a .exe (That runs the application), some .json files for settings, and a .pdb file for debugging symbols.
To alter the application to the .NET Framework standard output that you are used to, open the .csproj file in a text editor, and below the
<TargetFramework>netx.x</TargetFramework>
line, add
<PublishSingleFile>true</PublishSingleFile>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
And rerun the publish command. This will result in a single .exe and a single .pdb in the publish directory (The .pdb file which you can safely delete).
Note: Since you have included --self-contained false, the target will need the specified version of the .NET Framework (The one specified in your .csproj file) installed. Whilst many versions of the .NET Framework are currently installed on most Windows 10 Devices (Generally located at C:\Windows\Microsoft.NET\Framework or C:\Program Files\dotnet\), the .NET Core / .NET 5 Runtimes aren't yet as common (Although will likely be distributed through Windows Update in the near future), so may require a once-off download if the recipient of your .exe does not have it.
Whilst the .NET Core / .NET 5 resultant binaries ARE larger (Although by around 150kb - Not 50MB), they run significantly faster than their .NET Framework 4.x counterparts.

Was the ability to run a .NET Core app from source code removed?

In previous versions of what is now .NET Core, using the dnx toolchain, it was possible to run an application straight from source code, without compiling to a DLL on disk. This capability was also present on Azure, allowing you to edit code on the server and have those changes reflected in the live site.
The new dotnet CLI run command seems to automatically create the familiar bin and obj folders with compiled DLLs in them, and the publish process from Visual Studio to Azure now no longer includes the C# source, just the DLL.
Is it no longer possible with the new CLI and other tools to run .NET Core code without creating a DLL on disk?
Short David Fowler response:
Dynamic compilation is gone in RC2. It only exists for views now. There are no plans to bring it back.
Why?
Architectural challenges and changes require to implement it on both .NET Framework and .NET Core. We did it with dnx and there were some problems (like some things being completely broken with in memory assemblies) that we chose to just avoid.

Resources