1

I know that this question came up a few times before, but i could not find an answer for our simple case:

Is there a free tool which compiles a small .NET C# application into a native executable?

What i found so far are expensive tools which strip down the .NET framework and compile it into the executable, but thats no neccessarry in our case. Installing the .NET framework is no problem, we just want to precompile a C# project so that a user can not decompile the IL code for security reasons. A .NET obsucator is not enough, as we have sensitive code sections.

Mono-AOT is not an option, as it needs to have mono installed on the target machine from what i undersood.

Ngen.exe seems to be the closest to what we need, but how can we distribute the output file? it seems to include the IL code as well, as it says "whenever an NGen-generated image is run in an incompatible environment, .NET framework automatically reverts to using JIT".

Are there any practical workflows for this scenario?

EDIT2: I really wonder why this question was closed...

The SOLUTION is mkbundle from the Mono project:

I found a shell script which compiles a .NET application with Mono's mkbundle to a standalone native executable and modified it to the latest versions, as of May 2013 you can just use the script as follows:

https://gist.github.com/tebjan/5581296

1.) Install cygwin and make sure you select the following packages: - gcc-mingw - pkg-config - mingw-zlib1 - mingw-zlib-devel

2.) Install the Mono release package: "Mono for Windows, Gtk#, and XSP"

3.) Download the script and place it besides your Application and modify it to fit your environment (read the comments in the file carefully).

4.) Open cygwin and navigate to the output folder of your application where the executable and the scipt lies, e.g. YourProject/bin/Release

5.) Execute the script with the command: ./mkbundle_cygwin.sh

Troubleshooting: If your bundled executable does not work, make sure the original .NET application works on mono. You can test that by calling mono.exe and pass your .NET app to it or by installing XamarinStudio and running your project from there (make sure you set mono as runtime).

thalm
  • 2,738
  • 2
  • 35
  • 49
  • 2
    What makes you think sensitive bytes can't be located in native code? – Ben Voigt May 13 '13 at 17:31
  • Native code can be decompiled the same way that managed IL can. What are you trying to protect against? – dlev May 13 '13 at 17:32
  • @dlev: No, decompilation of native code (while possible) is pretty different from IL. But it's not the code he's trying to protect anyway, it's data. – Ben Voigt May 13 '13 at 17:32
  • @BenVoigt You're right, I missed the bit about "sensitive bytes". And I should have used the word "disassembled" or something like that. – dlev May 13 '13 at 17:34
  • 4
    The appropriate solution to your problem is simply not to store sensitive information in code. It doesn't belong there, and fundamentally there is no way of preventing someone from accessing that data so long as your program can access it. Appropriate solutions will depend on the specifics of your data. Perhaps you should have a web service that handles that bit of data? That's probably one of the few possible solutions that can *actually* prevent the data from being accessed. Virtually any other solution can make it harder, but never impossible. – Servy May 13 '13 at 17:40
  • 1
    You should explain in more detail what kind of information you think you need to store in the code, so that someone might be able to suggest a better solution - if, however, you need to store e.g. decryption keys for decrypting DRM'ed data on the client machine, you're out of luck - a sufficiently determined attacker _will_ be able to find the keys, no matter how native and obfuscated the code is. The best you can do is to make it hard to find (however, once someone finds the keys, you're probably out of luck again...) – Aasmund Eldhuset May 13 '13 at 17:44
  • i feared this would happen... ;) the bytes are only there to access the usb dongle. and it's not as clear bytes in the code but different constants of a calculation to generate the needed bytes on runtime. i want to disconnect the data from the code which calculates the result... a .net decompiler just gives me the code to calc the result, thats what i want to prevent. – thalm May 13 '13 at 18:04
  • 2
    *a .net decompiler just gives me the code to calc the result, thats what i want to prevent* It's much worse than that. A .NET Decompiler makes it possilbe to change the program to remove the dongle checking completely. – Conrad Frix May 13 '13 at 18:29
  • @ConradFrix Yes, but fortunately thats not what someone would want with this application, as it's used to configurate dongles. The usage of the configurated dongles is another software and all native code. – thalm May 13 '13 at 18:51
  • @thalm It doesn't matter that it's native code. That may make it a bit harder, but it'll still be possible to just edit out the check that verifies the dongle. – Servy May 13 '13 at 18:58
  • @thalm Must the calculation that you're performing on those bytes be done by the program? It really sounds like that's something that should be done on a server somewhere in which no clients will have access to the code. – Servy May 13 '13 at 18:59
  • Hello friends, please consider to delete your comments which are not constructive to the problem of compilling a .NET application to a native application and click on reopen the question. i found the solution and i want to answer to my question... thanks. – thalm May 15 '13 at 01:12

2 Answers2

1

For your particular case, it seems like the simplest approach would be to put the magic bytes into a separate native DLL, and have the managed code use p/invoke to retrieve them. This meets the two requirements you have mentioned:

  • separate the magic data from the code that uses it
  • keep the magic data out of .NET assemblies
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • after hours of research about ngen and other tools, we have to reconsider this. but with pInvoke/dllimport one can just use the calls in our native .dll (which he again finds in our .NET assembly) and get the results... similar problem i think? – thalm May 13 '13 at 19:00
  • 1
    @thalm: Yes, but the native DLL can check the signature of the calling assembly, make sure it is signed with your private key. – Ben Voigt May 13 '13 at 19:05
  • interesting idea... looks doable. i will try this... – thalm May 13 '13 at 19:07
  • These functions may help with that: http://msdn.microsoft.com/en-us/library/aa964998.aspx – Ben Voigt May 13 '13 at 19:09
  • I found that mkbundle is a very good solution and added it to my question text, i cannot answer myself as this question was closed. – thalm May 15 '13 at 03:48
  • @thalm: Did you read [the documentation for mkbundle](http://linux.die.net/man/1/mkbundle) It says "Notice that the produced image still contains the CIL image and no precompilation is done." It provides convenience, not protection against someone snooping inside your code. It also says "Important: Since the Mono runtime is licensed under the LGPL, even if you use static you should transfer the component pieces of the mkbundle to your users so they are able to upgrade the Mono runtime on their own. If you want to use this for commercial licenses, you must obtain a proprietary license for Mono" – Ben Voigt May 15 '13 at 04:41
  • yes i read that, its not perfect but close enough. the output file is a monolithic native exe which contains all data as gzip. so its by far less obvious as before. one has to know quite a bit to extract the IL data sections and decompile them. Licensewise, not thoroughly checked so far... – thalm May 15 '13 at 06:17
  • @thalm: An attacker can let the mono bundle code extract the IL for them. But yeah if it's gzipped it's going to be less obvious. – Ben Voigt May 15 '13 at 06:26
0

There are commercial obfuscators that produce a pretty good result, try Esiriz .NET Reactor at the max settings.

Of course somebody will be able to reverse it eventually but I am pretty sure is the best thing you can do if you really need to hide your things.

eried
  • 398
  • 5
  • 15