Obfuscate .NET exe after ILMerge merging with .dll dependencies - with ConfuserEx - c#

I have a product 'prod.exe' which I would like to obfuscate. 'prod.exe' has two dependencies: 'common1.dll' and 'common2.dll'.
I can obfuscate 'prod.exe' fine using ConfuserEx.CLI.exe listing its dependencies in the '.crproj' settings file.
I would also like to obfuscate the dlls 'common1.dll' and 'common2.dll'. Of course if I was to obfuscate these dlls on their own then my product wouldn't be able to reference them, so I need to do it at the same time as I obfuscate the product.
I can't find any obvious way to do this using ConfuserEx, but a potential solution I've attempted is first merging the exe and its dependent dlls using ILMerge and then obfuscating the resulting merged exe with ConfuserEx. Merging works just fine, but when I try to run the merged exe through ConfuserEx I get an error:
Failed to resolve dependency of prod.exe
This error happens whether or not I provide ConfuserEx paths to the dependent dlls. Although the dependencies are within the binary of prod.exe ConfuserEx can't find them.
Any help solving this problem would be greatly appreciated, whether that's a method to obfuscate an exe and it's dependencies separately or do it on a merged binary like I've attempted.
Cheers

It appears the ConfuserEx merges dependencies into the target by default removing the need for use of ILMerge.

Related

How to create a dll that includes all the others?

At the moment of creating a project of type "Library of Classes, usually one can generate a dll when compiling, but how could I generate a dll without losing others that I already have included?
I explain with an example: It turns out that Nuget downloaded an S22.Imap dll with the one I worked with, later I generated the dll in the traditional way that I explained in the beginning, but when I wanted to work with dll in another computer, I got errors that were not I found functions that contained the S22.IMAP dll. So to solve this problem, I had to copy the dll of my project, S22.IMAP in an additional way in a specific path of the other computer.
My question is:
How could you generate a dll that includes the ones included in the project you were working with?
All the referred 3rd party dlls (S22.Imap.dll in your example) will be copied to the output folder together with your own dll file (let's say a.dll) when you build your project. That means you should always copy them together (S22 + a.dll) to the place you want to refer them, on another computer/folder/place.
If you really want to make them only one file (although it is not recommended), you can set the S22 one as some "nested resource". Then you will get only one a.dll file and the S22 one is inside the a.dll. See below page for some reference:
Embedding one dll inside another as an embedded resource and then calling it from my code
AND, ILMerge is some tool that can help you do so.
In general, you don't. A DLL is a dynamic linked library, and you would normally only combine static libraries during a build. Here is an answer on the difference between static and dynamic linking.
Typically you would include all the DLLs you need in the installer package. If you use Visual Studio to create the installer, it can detect the dependencies for you. When you run the installer, all of the necessary DLLs are deployed. Nearly all commercial .NET software follows this pattern.
It is possible to merge an assembly into another assembly using a tool called ILMerge. This would be a very unusual thing to do, and could cause issues with intellectual property and code signing, so it is not recommended.

Is there an easy way to modify a decompiled file without having to deal with its dependencies?

I managed to decompile a c# file (using dotpeek) and I want to edit a couple of simple things (using visual studio).
The problem is this file has many dll dependencies even though the edits are necessary only on the main exe.
Obviously if you try to build an exe on vs without having the references and dependencies in place the compiler will complain. Are there any solutions to this?
You cannot build without the dependencies; however, there is no need to decompile the dependencies. Just add the DLLs themselves as reference to the project.
This is always fine if the decompiled assembly depends on other DLLs; however, if the other DLLs depend on the decompiled assembly, this will only work if the assemblies are not signed, i.e. if they are not using strong names. The purpose of signing is precisely to disallow such hacks.
No, you can't build without the dependencies because the compiler has to check that types match and have the indicated members etc.

C# - Are there disadvantages for all projects to share the same output path?

In a Visual Studio C# solution, are there any disadvantages for all projects to share the same output path? I'd like to do this because we use dependency injection and the files don't get copied automatically (since they are not referenced). Will this cause me any problems?
(This is related to: C# - Copy dlls to the exe output directory when using dependency injection with no references?)
We are doing this on our current project. We have about 30 projects output to the same bin folder and we have not had any problems.
There's a potential problem if you have two different projects depending on different versions of the same assembly. If I have project A depending on X.dll version 1, and project B depending on X.dll version 2, you're not going to be able to place both versions of X.dll into the same output folder (without a rename). Admittedly, the chances of these aren't high, but they're not zero.
The point of having multiple projects is to produce multiple assemblies. Assemblies are a deployment mechanism in .Net. If you always plan to bundle all the output dlls into one package, then I do not see disadvantages in this approach.
However, if you are planning to deploy Assemblies A,B,C separately from Assemblies D,E,F for one reason or another, keeping the output directories separate will ensure that the correct assemnbly and only its dependencies are in the output folder. It will be easier to then just write a script that correctly bundles those Assemblies into the correct packaging that you want.
Generally not a disadvantage, I find it quite beneficial to have a single output location for my target assemblies. When VS sorts the projects for compilation by determining dependencies, it will overwrite an existing instances of compiled assemblies that have been built earlier in the build order.
Saves me having to hunt round for the compiled assemblies when everything is built.
Some instances where you may have issues is if you have two projects with references to external assemblies that are of different versions, you may end up with an assembly bundled without the incorrect version of a dependency...
You may run into issues w/TeamBuild or whatever automated build process that you are using if you are planning on deploying your assemblies in different ways (core package vs. add ons, etc.)
How you customize your build scripts will be different (not necessarily disadvantageous) depending on how much customization you've done to your csproj files.
One big disadvantage with this approach is often you will run into access violation issues if your startup project holds references to any dlls that other projects reference during the build, even if copy local = false. I run into this issues everyday now. I would suggest having a project with all the needed references and copy local = true for those references. This will also help with making an installer.

The .NET equivalent of static libraries?

I'm building a tool in managed code (mostly C++/CLI) in two versions, a 'normal user' version and a 'pro' version.
The fact that the core code is identical between the two versions has caused me a little trouble as I want to package the resulting tool as a single assembly (DLL) and I don't want to have to include the .cpp files for the common code in the projects of the two versions of the tools. I'd rather have a project for the common code and a project for each version of the tool and have each version of the tools project depend on the common code and link it in as desired.
In unmanaged C++ I'd do this by placing the common code in a static library and linking both versions of the tool to it. I don't seem to be able to get this to work in C++/CLI. It seems that I'm forced to build the common code into a DLL assembly and that results in more DLL's than I'd like.
So, in summary, I can't work out how to build the common code in one project and link it with each of the final product projects to produce two single DLL assemblies that both include the common code.
I'm probably doing something wrong but I tried to work out how to do this using netmodules and whatever and I just couldn't get it to work. In the end the only way I got it working was to tell the linker to link the build products of the common code assembly rather than the results which works but is a bit of a hack IMHO.
Anyway, does anyone have any suggestions for how I SHOULD be solving this problem?
Edited: I guess I should have mentioned the fact that the assemblies generated are not 100% managed code, they contain a mix of managed and unmanaged code as is, probably, quite common with assemblies produced with C++/CLI...
If you are annoyed at all the DLLs, download ILMerge. I use this to bundle together multiple DLL's into an easy-to-use .EXE for my clients.
If I'm understanding this correctly, you have a solution which contains two projects. One project for the "normal" user and one project for the "pro" user. Visual Studio allows you to add a "link" to another file source from another project. If your "pro" version has the real core code file, and in your "normal" version you add existing -> find the file in the "pro" project, and click the down arrow by the Add button and select "Add as Link". Now you have single file that is literally the same between two projects.
As said, ILmerge is one way. Personally, if you're bundling some exe with a lot of DLLs, I favor Netz.
You could use modules. You can link them into an assembly using the assembly linker, al.exe.
That's the downside of the .Net compilation process, you can't have things like static libraries and the header files that hold them together, everything is held in one big dll file and the only way to share information is to either build a common dll and reference it from other assemblies or to duplicate the code in each dll (possibly by copying/linking .cs files between projects).
Note that the 2nd way will declare different types, even though they have the same name. This will bite you on the ass with stuff like remoting (or anything that requires casting to specific shared interfaces between processes).
Remotesoft Salamander will hook you up. It's basically a native compiler and linker.
When using mono (or cygwin is an option) mkbundle may also be a valid choice.

C#: How to include dependent DLLs?

I am using a 3rd party API which is defined in 2 DLLs. I have included those DLLs in my project and set references to them. So far so good.
However, these DLLs have at least one dependent DLL which cannot be found at runtime. I copied the missing DLL into the project and set the 'Copy to output' flag but without success.
What should I be doing here to tell the project where it should find the dependent DLL?
Clarification
I tried adding a reference to the missing DLL but as it wasn't recognised as a .Net component. In desperation, I added it directly to the output folder but without success.
Finally, I installed the API on the PC and it all worked. The installation sets the PATH variable and the DLL is found in the installation folder. But how to tell the project to look in one of its internal folders?
It sounds like you need to better understand the third-party library and how it uses its own dependencies. If the installation of the API solves the problem, but copying the files manually does not, then you're missing something. There's either a missing file, or some environment variable or registry entry that's required. Two things that will really help you in this is the depends tool (which is part of the C++ installation) and procmon, which will tell you all the registry keys and files that get used at runtime.
If you're lucky, it's just a file that you're missing. If that's all it is, you can use the "Build Events" section of the project to copy the needed files to the right location on a successful build. If not, you're going to have to solve this some other way - either by requiring the API be installed, or rolling your own installation project.
How are you deploying? Just flat files? If so, it should work as long as the file ends up in the project output directory. Does it?
If you are using another deployment, you will need to tell that engine to include it. This is different for each of msi/ClickOnce/etc.
You can either slowly add the downstream dependencies as references to your project. This is cumbersome, and somewhat fragile
Or your could use a tool like "Depends.exe" from microsoft to inspect your top level assemblies and get a reference list to the dependencies.

Categories

Resources