Should I worry about my software being decompiled? - c#

I'm trying to create a piece of software that allows the user to login and stream a byte[] of a dll to be used for injection. For example
public static byte[] getDLL()
{
using (WebClient wc = new WebClient())
{
Uri url = new Uri("http://mysite/dll.dll");
return wc.DownloadData(url);
}
}
I successfully managed to make this in C# using visual studio. However you can easily decompile the program and make it create the dll at a specific location on your computer therefore leaking it. And there's pretty much no way that I can prevent this.
Would I be better of using a language that's harder to decompile like say C++ or C for example or am I just going to run into the same problem what ever language I use? And is it really worth the effort.

You can't prevent decompiling anything, neither C# nor C++ or anything else.
Languages like C++ require more manual work compared to eg. C#, and obfuscators can make it harder to understand the code, but everything just slows down the one doing it, instead of preventing it.
(And stuff like DLLs and encryption won't help at all for securing the code)
If it is a problem that some user of the program can see the full code, you're doing something wrong. Any secret like passwords etc. don't belong in files the user gets, but on some server controlled by you and only reachable for the user through network connections etc.

I'm not very clear about the first paragraph of your question.But here is some idea for you.
Simply De-compiling is not an issue, if outsiders cant use generated code to hijack your assembly.
As my understanding there are plenty of tools to "reasonable de-compile" or browse the .NET assemblies content.
If you use C++ or C, there are de-compilers, The source code are generated by them are not accurate and need lot of manual works.
Secondly if you used native language such as C or C++ those has plenty of vulnerabilities. you have to use all the good practices to avoid injecting kind of issues. https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=637
There are tools for avoid de-compilation. you can google Obfuscator. some famous are Dotfuscator, Secure Team.
And also you can think about the project architecture changes. such as including DLL code in to the main EXE etc...
Also you can use key generation mechanism to verify the DLL. Just after loading the DLL exe call common function in the DLL and get the one time key and verify.

Related

Is releasing app from Visual Studio safe? [duplicate]

This question already has answers here:
How can I obfuscate my c# code, so it can't be deobfuscated so easily? [closed]
(4 answers)
Closed 5 years ago.
I have provided a WPF app and changed solution configurations to "Release"
I got an .exe file from releasing. Is this secure to share? Can someone access the code of this exe file? I mean isn't there any app to convert an .exe file into code?
Please let me to know how could I protect it before sharing it.
You can decompile any assembly or executable which was compiled using a .NET-language (the same applies to Java). This is because .NET-languages are compiled into the so-called common intermediate language, which isn´t actual machine code. Thus you can easily de-compile that file into code. Depending on the tool to be used for decompilation you have a good chance to decompile the code as if it was before compilation, which means you easily understand what the developer of the programmer wrote in the code.
But in many cases you won´t really care for this so much. First there aren´t many people around that actually would read that code, or have you ever read the javascript-code of a famous website, which is even directly human-readable? Even if there are some around that are interested in reading your code, most will have some hard work to understand it anyway on the fly. This assumes some long and hard work, which most developers won´t do. You can only make it harder to read that decompiled code using an obfuscator, that kind of encrpyts your code before the compilation-process making it hard to understand the code when the exe was built.
Consider this code:
var myVariable = "Some Text";
var anotherVariable = myVariable;
DoSomething(anotherVariable);
Quite self-explanatory code, isn´t it? Now consider the following which may be produced using DotFuscator e.g.:
var a="Some Text";var b=a;hksdshd(b);
Much harder to understand what this code does, isn´t it? Basically an obfuscator just replaces all identifiers in your code by some random characters making it quite hard to guess what their intended use or meaning is. Afterwards that encrypted code is compiled as any other code into an assembly or an executable. When then someone really decompiles your program all they get are those hard to read names and fragments.
Having said this it´s quite hard to really protect your app from being read by anyone, and in most cases this isn´t what you should care for too much. Usually what you want to protect is your data, e.g. the information being stored in a database.
You may also have a look at this question, which has some closer look on obfuscation-tools.
It doesn't matter if you created your .exe file in Debug or Release mode - all executable files (.EXE) can be decompiled into code.
A decompiler is a computer program that takes an executable file as input, and attempts to create a high level, compilable source file that does the same thing.
It is therefore the opposite of a compiler, which takes a source file and makes an executable. Decompilers are considered as important tool in the process of reverse engineering.
Once such popular tool is hiew which offers to break down any exe created in any language into its high-level code.
For binaries and EXE files created using the .NET framework, there are several tools, including this one, which makes decompilation very easy and accessable.
You can prevent decompilation using Obfuscation. several tools are available, such as secureteam.net and Dotfuscator.

Is there any way for converting reference dll to non-reference dll in visual studio

I have a DLL file (cf.dll) in my project.
It has some methods for encrypting and decrypting a string To/From a file.
My "cf.dll" have some methods for:
write "mystring" ---to-->> new encrypted dll
and
read encrypted dll ---to--->> "mystring"
Now i want publish my project, but if end user use my dll in his/her visual studio (by reference to dll), he/she can decrypt my encrypted files.
Another hand i need this dll in my published project because my project use theirs methods some times.
Now my question is:
How can i change this published dll (cf.dll) to a none-reference dll, for prevent any hack by it.
Edit (more details):
What i want to do:
I want encrypt some connection strings (as a DataTable) to a file and read this file agin.
I have a dll file for doing this work. it is cf.dll. it has some methods for encrypting and decrypting.
Encryption workflow>
DatatTable ------to------>> Xml as String ------by cf.dll methods to------>> enc.dll
Decryption workflow
enc.dll ------by cf.dll methods to------>> Xml as String ------to------>> DataTable
Everything is working properly and encrypted file (enc.dll) is created.
But if the end user use my magic DLL (cf.dll) in a new project in the visual studio (by reference to it), he/she can decrypt my encrypted file (enc.dll) and hack my program.
So, i want to prevent this hack by changing my DLL (cf.dll) to a none-reference DLL OR use another safe solution.
Edit:
My Table Columns for keeping connection string data:
Server DbName DbUser DbPass FileName
But may i ask save another DataTable by this encryption mechanism. so please help me by a solution for saving any string, not only a ConnectionString.
I want a very secure encrypted file from any data. in my solution i conver each object to a string then use my dll methods for save it as a encrypted file (i can do it nice, my problem described above).
You cannot make your dll "non-reference dll", but you can hide all your classes/methods with "internal" keyword (instead of public). This means that this classes/methods can be used only inside of current dll or in DLL/EXE which were specified with InternalVisibleTo attribute. So nobody can use them directly, but you should know that this is managed code, so anybody can take a look inside of your DLL and extract your keys for decryption and write the same code as you have in your dll.
Surprisingly you can not archieve your goal by using a .NET Assembly.
You could even obfuscate your code and it would still be decompilable and reusable.
There's nothing which can prevent that. You can rise the bar, but someone - if she want's - will be able to get the information you are trying to hide.
(Have you seen copy-protection mechanisms that really work besides doing something crucial online?)
Always think of the following:
If you want to hide information from a user DO NOT DELIVER that information. Everything else is just protection through obfuscation, wich can be cracked with more or less effort.
That's a really nice question RAM.
Some solutions to your problem:
1) Don't make a separate assembly (DLL), but put the code of your DLL in your EXE and make the encryption/decryption function of your DLL "internal" (so that no-one can use it from outside the EXE). Then use a free tool like Eazfuscator to obfuscate your EXE (because, if you don't, your code will be easy to decompile and read).
2) You could put the DLL in your EXE's resources (perhaps encrypted too). Then perhaps you can find a way to get it from there and load it into memory for your app to use. But this is quite complex thing to do if you are a beginner and I'm not 100% sure if it's doable in .NET (I haven't done it myself). However, I think it's doable.
3) The fact is that, if your code executes on the client's machine, there's not much you can do to prevent people from analysing it. The best you can do is to make it a little (or much) difficult for them to do it. E.g. you can add a lock mechanism in your DLL that requires the caller to respond to a random question. If he responds correctly, you execute the decryption. If not, throw an exception, return null or, even better, return a wrong output. The random question could be an integer that your DLL will generate on initialization and the EXE should process this integer to generate a new integer based on some "secret" algorithm. Then the EXE will "feed" this into the DLL somehow and it's functionality would be "unlocked".
4) Perhaps you could use reflection to analyse the caller assembly in order to find characteristics or even the author signature (if you put one in your EXE). That way, you could execute the decryption if the EXE is signed by your private key and the signature is valid. But that's a bit complex too.
5) I think there are tools called "EXE packers" that pack your EXE and DLLs into one EXE file and protect them at some degree. I haven't used one of those yet.
6) You can move the encryption/decryption process on a web site that will ask for authentication in a complex manner, similar to the one described in (3) for the DLL. This may keep your encryption algorithm safe, but the authentication process could still be analysed and hacked.
I would suggest the 3rd solution since it's the most easy to implement. The 4th (using signed code) is the most secure one but it takes a lot of knowledge to implement it (knowledge that even I don't have right now).
Have a nice coding! :)

Could I hide the encryption key of a c# exe securely (in a way that can't be decompiled in any known way), as in C/C++?

I love c# for programming applications (I consider myself intermediate with c#, and a bit less with C/C++, but am only learning, nothing real yet in the arena), and I used to like it until i discovered "anyone" who understand MSIL (not an easy task to learn neither) could decompile my code. I don’t really care about someone decompiling my code, but my utter concern is the security for my eventual program users. I know obfuscators exist, and I even know of one or two that are really good, I hear (even if they only delay a decompiling).
For example, if I want to decrypt something using c#, some where in the code the key should be, making it a danger for anyone who use my program (someone who know someone who encrypted the file using my program could decrypt it by researching on my MSIL code, finding my key). Then, the developing of massive applications that encrypt/decrypt stuff (or OpenSSL) is insane with c#, I think, for this reason.
I mean, most users won’t know what language was used to make that exe, but a bunch of people are able to program n c#, and an elite of this people can read MSIL, and a minority of this elite would like to hack what ever is possible to hack. Of those people who like to hack, some of them can do it with perverse intentions (in a value-less world where we live that shouldn’t surprise anyone).
So, if I want to make a program that download a file from the internet, someone could interfere the transmission and do some evil, even if I use OpenSSL with c#, because somewhere in the c# file is the key. I know avoiding hacking is probably impossible, but it looks like c# is a very unsecure way.
Does it happen with Java? (Java has the same “interpreting” and “decompile” structure as C#); I mean, the fact that the key is visible in Java (with some educated eye) some where in the building file? Or does Java use some C/C++ based API that makes it harder (way harder) to decompile the file where the key is and so making it hard to get the key?
Is my only option to write my program with c/c++? Because if so, my only option is C++Builder, since its a hell to even try to watch (and less to learn) MFC/OWL code; I mean: I cant hardly think of someone who could like MFC/OWL programming. In fact, I suppose Assembly could be of more interest in the today programming world.
So, here I am, wanting to find someone who could explain me better a way to store securely crypto keys for encrypting/decrypting or to use OpenSSL with c#. Or even with Java. I would like to confirm that C/C++ is the only way of really using these features with some security for decompiling reasons (as other compiled programming languages, i.e. Delphi).
If anyone knows a site where I can find precise information about the subtle reasoning I suppose I have done (specially one that shows am wrong in my analysis), please tell me. If any one can confirm my analysis, please confirm. If anyone find any hole in my analysis, again, please tell me, and where to find more information that rule me to get a better understanding of all this.
Am sorry for making this philosophical computer programming question that long.
Thank you,
McNaddy
Could I hide the encryption key of a c# exe securely (in a way that can't be decompiled in any known way), as in C/C++?
No. You can't do that in any language.
The .NET security system is designed to protect benign users from hostile code. You are trying to protect benign code from hostile users. You simply cannot do that, so don't even try. If you have a secret, do not share it with anyone.
The purpose of crypto is to leverage the secrecy of some private key into the secrecy of a text. If that is not the security problem you face, crypto is the wrong tool. Explain the security problem you actually have and someone here can help you solve it.
So, if I want to make a program that download a file from the internet, someone could interfere the transmission and do some evil, even if I use OpenSSL with c#, because somewhere in the c# file is the key.
You don't need to store a secret key in the program just to download a file safely.
If you want to ensure that the file you downloaded is authentic and hasn't been modified in transit, you use a digital signature. The private key used to make the signature doesn't have to be (and shouldn't be) distributed with the program; all the program needs is the corresponding public key, which you don't have to hide.
If you want to prevent eavesdroppers from reading the file as it's downloaded, then you need to encrypt it, but that can be done with a temporary session key generated randomly for each download; it doesn't have to be stored anywhere. If you use HTTPS for your download, it'll do this for you.
The choice you've mentioned (embed key into executable) is bad irrespective of language you choose - it is not too hard to extract data from C/C++ and slightly easier for C#/Java.
As Jordão said - you need to figure out your story of distributing key outside the binaries. You also need to figure out what you actually trying to protect and understand possible exploits. Just using encryption of some sort in an application does not make it more secure.
You should not store cryptographic keys inside assemblies; they should normally be provided from outside, e.g. from a key-store, or derived from a secret known to a user.
You can also generate a key from a password(this means the key is no more stronger than the password though). So each time the user runs the program, they are prompted for a password, and that password is then used to generate a key. Depending on your requirements you could employ this in a variety of ways.
When the user needs to access the encrypted data, the password can be provided again and this generates the key for use during that session. Once the program is closed the key is discarded(there are techniques/APIs in C# to help ensure that sensitive data is only present in memory as short a time as possible).
For example, this is essentially what many password storing programs like Keepass or Roboform do. The user can upload and download the encrypted data to and from servers. No keys are ever stores, and instead generated on demand as the user supplies their password for that session.
With a service like Dropbox, when you register with their site, they generate the private key on their server and keep a copy there. So the user's machine and client software never store the key, but the server has a copy stored. Dropbox does this so that they can decrypt user data for many purposes, such as compression, de-duplication, compliance with law enforcement, etc.

Make an executable at runtime

Ok, so I was wondering how one would go about creating a program, that creates a second program(Like how most compression programs can create self extracting self excutables, but that's not what I need).
Say I have 2 programs. Each one containing a class. The one program I would use to modify and fill the class with data. The second file would be a program that also had the class, but empty, and it's only purpose is to access this data in a specific way. I don't know, I'm thinking if the specific class were serialized and then "injected" into the second file. But how would one be able to do that? I've found modifying files that were already compiled fascinating, though I've never been able to make changes that didn't cause errors.
That's just a thought. I don't know what the solution would be, that's just something that crossed my mind.
I'd prefer some information in say c or c++ that's cross-platform. The only other language I'd accept is c#.
also
I'm not looking for 3-rd party library's, or things such as Boost. If anything a shove in the right direction could be all I need.
++also
I don't want to be using a compiler.
Jalf actually read what I wrote
That's exactly what I would like to know how to do. I think that's fairly obvious by what I asked above. I said nothing about compiling the files, or scripting.
QUOTE "I've found modifying files that were already compiled fascinating"
Please read and understand the question first before posting.
thanks.
Building an executable from scratch is hard. First, you'd need to generate machine code for what the program would do, and then you need to encapsulate such code in an executable file. That's overkill unless you want to write a compiler for a language.
These utilities that generate a self-extracting executable don't really make the executable from scratch. They have the executable pre-generated, and the data file is just appended to the end of it. Since the Windows executable format allows you to put data at the end of the file, caring only for the "real executable" part (the exe header tells how big it is - the rest is ignored).
For instance, try to generate two self-extracting zip, and do a binary diff on them. You'll see their first X KBytes are exactly the same, what changes is the rest, which is not an executable at all, it's just data. When the file is executed, it looks what is found at the end of the file (the data) and unzips it.
Take a look at the wikipedia entry, go to the external links section to dig deeper:
http://en.wikipedia.org/wiki/Portable_Executable
I only mentioned Windows here but the same principles apply to Linux. But don't expect to have cross-platform results, you'll have to re-implement it to each platform. I couldn't imagine something that's more platform-dependent than the executable file. Even if you use C# you'll have to generate the native stub, which is different if you're running on Windows (under .net) or Linux (under Mono).
Invoke a compiler with data generated by your program (write temp files to disk if necessary) and or stored on disk?
Or is the question about the details of writing the local executable format?
Unfortunately with compiled languages such as C, C++, Java, or C#, you won't be able to just ``run'' new code at runtime, like you can do in interpreted languages like PHP, Perl, and ECMAscript. The code has to be compiled first, and for that you will need a compiler. There's no getting around this.
If you need to duplicate the save/restore functionality between two separate EXEs, then your best bet is to create a static library shared between the two programs, or a DLL shared between the two programs. That way, you write that code once and it's able to be used by as many programs as you want.
On the other hand, if you're really running into a scenario like this, my main question is, What are you trying to accomplish with this? Even in languages that support things like eval(), self modifying code is usually some of the nastiest and bug-riddled stuff you're going to find. It's worse even than a program written completely with GOTOs. There are uses for self modifying code like this, but 99% of the time it's the wrong approach to take.
Hope that helps :)
I had the same problem and I think that this solves all problems.
You can put there whatever code and if correct it will produce at runtime second executable.
--ADD--
So in short you have some code which you can hard-code and store in the code of your 1st exe file or let outside it. Then you run it and you compile the aforementioned code. If eveything is ok you will get a second executable runtime- compiled. All this without any external lib!!
Ok, so I was wondering how one would
go about creating a program, that
creates a second program
You can look at CodeDom. Here is a tutorial
Have you considered embedding a scripting language such as Lua or Python into your app? This will give you the ability to dynamically generate and execute code at runtime.
From wikipedia:
Dynamic programming language is a term used broadly in computer science to describe a class of high-level programming languages that execute at runtime many common behaviors that other languages might perform during compilation, if at all. These behaviors could include extension of the program, by adding new code, by extending objects and definitions, or by modifying the type system, all during program execution. These behaviors can be emulated in nearly any language of sufficient complexity, but dynamic languages provide direct tools to make use of them.
Depending on what you call a program, Self-modifying code may do the trick.
Basically, you write code somewhere in memory as if it were plain data, and you call it.
Usually it's a bad idea, but it's quite fun.

(C#/C++ CLI) Is it possible to protect my C++ CLI assemblies from being used in other .NET projects?

I have created a C++ CLI wrapper for native C++ code, which in turn I reference in my C# application. Is it possible to somehow protect this assembly so that it may only be used in my application without the possibility of someone else using it?
I'm a Microsoft technology developer, I'm all about selfishness :)
I have used this technique with success.
Basically, it's about protecting your assembly from being loaded by placing a link-time security demand and using the assembly strong name's public key as evidence. Only assemblies signed with your private key will be able to load it.
Yes, but this will be a losing battle against a determined attacker.
For example, you could provide an encrypted version that only accepts a particular key, as some people have suggested. But then you'll need to decrypt it on your clients, who may not have encrypted memory stores, so a determined attacker could simply read the appropriate block of memory and deserialize the result to get your original assembly.
Not perfectly. LinkDemand is only enforced in a partial trust environment. Code running with full trust can also use reflection to access private types, and generally bypass any protection you care to discuss.
Maybe you want your C++/CLI code to call Assembly::GetEntryAssembly and check it against a whitelist of approved apps for which the library is intended.
Of course, you want to minimize the amount of managed code (and attributes) involved in the checks since managed code is really easy to decompile.
Actually, mixing the occasional check into the core logic of the C++ code is the only hope you have that it won't be bypassed.

Categories