Are C++/CLI apps more secure than C# apps? - c#

Is it true that the applications that are written in C++/CLI with /clr switch are more complicated for the crackers than C# applications? Does C++/CLI generate applications that are in general more complicated to disassembly and crack?
I know that it is a matter of the way that you are doing to code, but I am asking about the general case of difficulty that faces crackers.

If you're mixing native and managed code, yes it's more difficult, because they would be required to know x86 assembly to read your code. Still doable, but more difficult than pure managed code.
If you're compiling only managed code (which you can do in C++/CLI), it's all compiled down to MSIL and can be disassembled easily with .Net Reflector. Managed code is all the same when its compiled, it's fairly easy to reconstruct C# code (or F#, etc..) from managed C++/CLI code that's been compiled down to its MSIL form.
You're better off obfuscating your code, if you want it to be more difficult to crack.
Dotfuscator Community Edition is included with VS2010. That will change certain class, method, field and property names to random characters. More robust features are included in pay editions of these kinds of software, where it would actually change the program's structure a bit to make it even more difficult to read. There are other techniques to prevent disassembly, but they're too many to list here.
Side Note
That doesn't necessarily make your code secure. Say, for example, you're trying to impose usage limits on an application you wrote. Maybe you use a file in an obscure place and/or a registry key to keep track of how many times the program was used. You want to prevent the program from being used more than 30 times before they buy it. I could open up Process Monitor, load your program, find the file and registry key you keep track of this information and reset it each time I want to bypass your limits. That didn't require any cracking whatsoever.
Your security is only as good as you make it, decompiling isn't everything.

It's entirely possible, but I would like to stress that "difficult to disassemble" does not equate to "secure".
No code that you deliver to a third party, in any form, should be considered "secure". It's all crackable, and there's nothing you can do about it, so you'd be better off adopting a business model that doesn't rely on it.

In fact C# should be a bit safer against buffer overflows, which can be used to inject assembler code to the stack.

Related

Porting C++ to C#

C++ and C# are quite simmilar programming languages, in my opinion. If a C++ code needs to be ported to platform where C# is the only supported platform, how much work will need to be done?
Should I get ready, that most of the C++ code will need to be rewritten to C#? Or, because of language simmilarities, should refactoring be quite easy and straightforward?
I am aware, that it will depend on the application itself, but I am asking in general.
I have done a major port of a C++ application to C# recently. Overall I thought it was a pleasant experience. These are the steps that I took, they might or might not apply to your application.
Get the "scaffolding" in place in C#, design your architecture. This is the time to get in major architecture changes from the existing application if you choose to do so.
Get your tests in place. I can't over-emphasize this one. Since you are porting an existing application you should have a set of tests already in place that verify the correct behavior of your application. You can and should reuse these tests for your C# application. This is the one thing that gives you an edge when porting - you know (and have written) already many of the tests you want. Start porting your test project.
Put in method stubs for your C# methods that reflect the existing C++ methods. Given the framework support in C# some methods might not be needed at all anymore, or are very simplified - this is the time to decide.
Copy and paste. Yes I used copy and paste for most of the C++ code - all the flow statements basically can be reused if you are careful. Once pasted go through line by line, many things like use of pointers etc. must be rewritten to use a equivalent C# type.
Once you have re-written a method in such a way, do the obvious re-factoring given the framework support / helper classes you might have been lacking in C++ but are readily available in C#. Also naming conventions for variables etc. can be changed here, should be straightforward given the built in support for this in VS 2010.
Run your tests! Test early and often that the overall framework you have in place so far produces the exact same output as your C++ application which you can use as a reference. This is also the time to add missing tests.
Refactor, Refactor, Refactor. Every application ages, and so did your C++ application most likely. Look closely at the underlying design and simplify and remove as much as possible. Verify at each step by running your tests.
First thing first, this is porting and not refactoring. Also I think it's an extremely bad idea.
It is true that you could (with a lot of work) port C++ to unsafe C#, but saying that the syntax is very similar is a bit of a stretch. In fact, following the same line of reasoning you could port C++ to any other C derived language, and it would be equally painful.
Again, if you do it expect a shedload of rework. It's more than likely gonna take you more than re-coding it from scratch using the existing code as mere model, which is in my opinion a better and less messy option.
Just compile the C++ code with the /clr compiler option. That will translate the code to IL, it can execute on most any .NET enabled platform. There are very few C++ constructs that cannot be translated, it would have to use non-standard compiler extensions like __fastcall.
However, I suspect that you will find out that the platform requires verifiable code. Which is the common reason why a platform would restrict code to a .NET compliant language. I cannot guess at this since you didn't mention the execution environment. Native C++ translated to IL is not verifiable due to pointer manipulations. If that's the case then you are looking at a pretty drastic rewrite.
I'd be interested to know where C# is the "only supported platform".
The problem of rewriting in a new language can be whether you need to rewrite every single part of the code and cannot use any of the old code at all. Sometimes it is best, even when doing a rewrite, to make it more of a refactor: rewrite some parts of the code, move others. The existing code is known to work and can be tricky to reproduce. And it takes time. There needs to be a good reason to do a full rewrite.
.NET supports a version of C++, and Visual Studio also comes with Visual C++ to build standard C++, so consider whether or not you can make this a phased transformation, and whether or not you really have to rewrite the whole thing.
Porting C++ code to C# will not be that hard, assuming that all your dependent libraries have existing C# counterparts. Lack of dependencies is the most likely pitfall. The core concepts of your program, such as inheritance, heap, references, data structures, should be fairly easily translatable.
This is assuming that you don't invoke any specific low level behaviour such as custom memory management, because C# does not really support that kind of thing and you could have a serious problem there.

Any coding security issues specific to C#?

In C++ world there is a variety of ways to make an exploitable vulnerability: buffer overflow, unsafe sting handling, various arithmetic tricks, printf issues, strings not ending with '\0' and many more. Despite most of these problems were solved in java, there are some things to talk about.
But is there any list of typical C#-specific coding vulnerabilities? (and not related to .NET platform itself)
Here are a few issues you can run into:
If you've got any sort of language interpreter (HTML, JavaScript, and SQL being the big three) then you can still have injection or XSS vulnerabilities.
P/Invoke can cause problems, especially if you're doing any custom marshalling. Even if you're calling a "safe" API through P/Invoke, your marshalling code could contain a bug that corrupts or exposes memory.
If you're doing file access then you need to make sure your files are always in acceptable directories. Be sure to sanitize against bad absolute and relative paths.
Cryptography. Good cryptographic programming is really hard, and .Net's various safety features do nothing against crypto attacks.
C# is based on .NET and .NET is supposed to be type-safe, which means none of your list of horrors applies to C# or any .NET language.
But then again, C# has an unsafe keyword and after that all bets are off.
It allows real pointers and everything that comes with them.
Not really. I'm going to make a bold statement here:
There's no such thing as a "C#-specific coding vulnerability that isn't related to the .net platform".
A program written in C++ is compiled directly into a machine executable, so the language compiler is directly responsible for the creation of the executed code, hence the way C++ can be easily capable of "creating an exploitable vulnerability".
A program written in C# however is compiled into IL, which is the only language that the .net platform works with. The .net environment creates a machine executable based on that IL code. Everything that C# can do is merely a subset of what the .net platform is capable of. This is how I can make my bold statement. Anything you could possibly do with C# that created a coding vulnerability would be one of:
1) A bug in the .net platform
or
2) Executing code outside of the .net platform
So the way your question is currently phrased leads me to believe that either you're not fully aware of the huge differences between "writing code in C" and "writing code for the .net platform" or I'm misunderstanding your question. Perhaps a bit of both! 8 )
Hope this helps!
Probably none from your list of concerns but this is the one to be careful with: void*
Don't forget, you can call any C++ from C#. I do it all the time. So all the buffer overrun issues and so on for C++ are relevant for C# as well even if you don't directly call C++ because C# calls C++ to do it's work.
Think about it. And any COM calls and Marshal calls are just as open to attack as normal. In Linux you can use _r routines and in Ver 8 up in VC++ you can use _s routines to lessen then chance of buffer overflow (requires user buffers and/or max sizes). About the only way to stop vulnerabilities is to turn off your computer and read a paper back book (unless it too has a virus).

How do i prevent my code from being stolen?

What happens exactly when I launch a .NET exe? I know that C# is compiled to IL code and I think the generated exe file just a launcher that starts the runtime and passes the IL code to it. But how? And how complex process is it?
IL code is embedded in the exe. I think it can be executed from the memory without writing it to the disk while ordinary exe's are not (ok, yes but it is very complicated).
My final aim is extracting the IL code and write my own encrypted launcher to prevent scriptkiddies to open my code in Reflector and just steal all my classes easily. Well I can't prevent reverse engineering completely. If they are able to inspect the memory and catch the moment when I'm passing the pure IL to the runtime then it won't matter if it is a .net exe or not, is it? I know there are several obfuscator tools but I don't want to mess up the IL code itself.
EDIT: so it seems it isn't worth trying what I wanted. They will crack it anyway... So I will look for an obfuscation tool. And yes my friends said too that it is enough to rename all symbols to a meaningless name. And reverse engineering won't be so easy after all.
If you absolutely insist on encrypting your assembly, probably the best way to do it is to put your program code into class library assemblies and encrypt them. You would then write a small stub executable which decrypts the assemblies into memory and executes them.
This is an extremely bad idea for two reasons:
You're going to have to include the encryption key in your stub. If a 1337 hacker can meaningfully use your reflected assemblies, he can just as easily steal your encryption key and decrypt them himself. (This is basically the Analog Hole)
Nobody cares about your 1337 code. I'm sorry, but that's tough love. Nobody else ever thinks anyone's code is nearly as interesting as the author does.
A "secret" that you share with thousands of people is not a secret. Remember, your attackers only have to break your trivial-to-break-because-the-key-is-right-there "encryption" scheme exactly once.
If your code is so valuable that it must be kept secret then keep it secret. Leave the code only on your own servers; write your software as a web service. Then secure the server.
the generated exe file just a launcher that starts the runtime and passes the IL code to it.
Not exactly. There are different ways you can set up your program, but normally the IL code is compiled to native machine code that runs in process with the runtime.
As for the kiddies — you're deluding yourself if you think you can sell to them or anyone who uses what they redistribute. If they can't unlock your app they'll move on and find one they can or do without. They represent exactly $0 in potential sales; it makes little sense to spend too much effort attempting to thwart them because there'd be no return on your investment. A basic obfuscator might be fine, but don't go much beyond that.
Realistically, most developers face a much bigger challenge from obscurity than from piracy. Anything you do that prevents you from getting the word out about your product hurts you more than the pirates do. This includes making people pay money to get it. Most of the time a better approach is to have a free version of your app that the kiddies don't even need to unlock; something that already works for them well enough that cracking your app would just be a waste of their time, and not just a time or feature-limited trial. Let them and as many others as possible spread it far and wide.
Now I know that you do eventually need some paying customers. The key is to now use all the attention you get from the free product to upsell or promote something else that's more profitable. One option here is to also have a premium version with additional features targeted largely at a business audience; things like making it easy to deploy to an entire network and manage that way. Businesses have deeper pockets and are more likely to pay your license fees. Your free version then serves to promote your product and give it legitimacy for your business customers.
Of course, there are other models as well, but no matter what you do it's worth remembering that obscurity is the bigger challenge and that pirated copies of your software will never translate into sales. Ultimately (and of course this depends on your execution) you'll be able to make more money with a business model that takes advantage of those points than you will trying to fight them.
"...prevent scriptkiddies to open my
code in Reflector and just steal all
my classes easily."
Unfortunately, regardless of how you obscure launching, it's a matter of half a dozen commands in a debugger to dump a currently-running assembly to a file of the user's choice. So, even if you can launch your application as Brian suggested, it's not hard to get that application's components into Reflector once it's running (I can post a sample from WinDbg if someone would find it interesting).
Obfuscation tools are created from huge amounts of technical experience, and are often designed to make it difficult for debuggers to reliably attach to a process, or to extract information from it. As Brian said: I'm not sure why you're determined to preserve the IL and, if you want any meaningful protection from script kiddies, that's something you may have to change your mind on.
"They copied all they could follow, but they couldn't copy my mind, so I left them sweating and stealing a year and a half behind." -- R. Kipling
Personally I think that obfuscation is the way to go. It is simple and can be effective, especially if all your code is within an exe (I'm not sure what the concern is with "messing up the IL").
However, if you feel like that won't work for you, perhaps you can encrypt your exe and embed it as a resoource within your launcher. The simplest way to handle it would be to decrypt the exe resource and write it out too file and execute it. Once the exe has completed executing, delete the file. You might also be able to run it through the Emit functions. I have no idea how this would work, but here is an article to get you started - Using Reflection Emit to Cache .NET Assemblies.
Of course your decryption key would probably have to be embedded in the exe as well so somebody really determined will be able to decrypt your assembly anyway. This is why obfuscation is probably the best approach.
Copying my answer from this question (which is not exactly duplicate but can be answered with the same answer, hence CW):
A Windows EXE contains multiple "parts". Simplified, the .net Code (=MSIL) is only a Part of the EXE, and there is also a "real" native Windows Part inside the EXE that serves as some sort of launcher for the .net Framework which then executes the MSIL.
Mono will just take the MSIL and execute it, ignoring the native Windows Launcher stuff.
Again, this is a simplified overview.
Edit: I fear my understanding of the deep depp details is not good enough for really much detail (I know roughly what a PE Header is, but not really the details), but i found these links helpful:
NET Assembly Structure – Part II
.NET Foundations - .NET assembly structure
Appendix: If you really want to go deeper, pick up a copy on Advanced .net Debugging. The very first chapter explains exactly how the .net Assembly is loaded prior and after Windows XP (since XP, the Windows Loader is .net aware which radically changes how .net Applications are started)

Could managed code (specifically .NET) ever become 'unmanaged'?

Recently I was talking with a friend of mine who had started a C++ class a couple months ago (his first exposure to programming). We got onto the topic of C# and .NET generally, and he made the point to me that he felt it was 'doomed' for all of the commonly-cited issues (low speed, breakable bytecode, etc). I agreed with him on all those issues, but I held back in saying it was doomed, only because I felt that, in time, languages like C# could instead become native code (if Microsoft so chose to change the implementation of .NET from a bytecode, JIT runtime environemnent to one which compiles directly to native code like your C++ program does).
My question is, am I out to lunch here? I mean, it may take a lot of work (and may break too many things), but there isn't some type of magical barrier which prevents C# code from being compiled natively (if one wanted to do it), right? There was a time where C++ was considered a very high-level language (which it still is, but not as much as in the past) yet now it's the bedrock (along with C) for Microsoft's native APIs. The idea that .NET could one day be on the same level as C++ in that respect seems only to be a matter of time and effort to me, not some fundamental flaw in the design of the language.
EDIT: I should add that if native compilation of .NET is possible, why does Microsoft choose not to go that route? Why have they chosen the JIT bytecode path?
Java uses bytecode. C#, while it uses IL as an intermediate step, has always compiled to native code. IL is never directly interpreted for execution as Java bytecode is. You can even pre-compile the IL before distribution, if you really want to (hint: performance is normally better in the long run if you don't).
The idea that C# is slow is laughable. Some of the winforms components are slow, but if you know what you're doing C# itself is a very speedy language. In this day and age it generally comes down to the algorithm anyway; language choice won't help you if you implement a bad bubble sort. If C# helps you use more efficient algorithms from a higher level (and in my experience it generally does) that will trump any of the other speed concerns.
Based on your edit, I also want to explain the (typical) compilation path again.
C# is compiled to IL. This IL is distributed to local machines. A user runs the program, and that program is then JIT-compiled to native code for that machine once. The next time the user runs the program on that machine they're running a fully-native app. There is also a JIT optimizer that can muddy things a bit, but that's the general picture.
The reason you do it this way is to allow individual machines to make compile-time optimizations appropriate to that machine. You end up with faster code on average than if you distributed the same fully-compiled app to everyone.
Regarding decompilation:
The first thing to note is that you can pre-compile to native code before distribution if you really want to. At this point you're close to the same level as if you had distributed a native app. However, that won't stop a determined individual.
It also largely misunderstands the economics at play. Yes, someone might perhaps reverse-engineer your work. But this assumes that all the value of the app is in the technology. It's very common for a programmer to over-value the code, and undervalue the execution of the product: interface design, marketing, connecting with users, and on-going innovation. If you do all of that right, a little extra competition will help you as much as it hurts by building up demand in your market. If you do it wrong, hiding your algorithm won't save you.
If you're more worried about your app showing up on warez sites, you're even more misguided. It'll show up there anyway. A much better strategy is to engage those users.
At the moment, the biggest impediment to adoption (imo) is that the framework redistributable has become mammoth in size. Hopefully they'll address that in a relatively near release.
Are you suggesting that the fact that C# is managed code is a design flaw??
C# can be natively compiled using tool such as NGEN, and the MONO (open source .net framework) team has developed full AOT (ahead of time) compilation which allows c# to run on the IPhone. However, full compilation is culbersome because it destroys cross-platform compatibility, and some machine-specific optimizations cannot be done. However, it is also important to note that .net is not an interpreted language, but a JIT (just in time) compiled language, which means it runs natively on the machine.
dude, fyi, you can always compile your c# assemblies into native image using ngen.exe
and are you suggesting .net is flawed design? it was .net which brought back ms back into the game from their crappy vb 5, vb 6, com days. it was one of their biggest bets
java does the same stuff - so are you suggesting java too is a mistake?
reg. big vendors - please note .net has been hugely hugely successful across companies of all sizes (except for those open source guys - nothing wrong with that). all these companies have made significant amount of investments into the .net framework.
and to compare c# speed with c++ is a crazy idea according to me. does c++ give u managed environment along with a world class powerful framework?
and you can always obfuscate your assemblies if you are so paranoid about decompilation
its not about c++ v/s c#, managed v/s unmanaged. both are equally good and equally powerful in their own domains
C# could be natively compiled but it is unlikely the base class library will ever go there. On the flip side, I really don't see much advantage to moving beyond JIT.
It certainly could, but the real question is why? I mean, sure, it can be slow(er), but most of the time any major differences in performance come down to design problems (wrong algorithms, thread contention, hogging resources, etc.) rather than issues with the language. As for the "breakable" bytecode, it doesn't really seem to be a huge concern of most companies, considering adoption rates.
What it really comes down to is, what's the best tool for the job? For some, it's C++; for others, Java; for others, C#, or Python, or Erlang.
Doomed? Because of supposed performance issues?
How about comparing the price of:
programmer's hour
hardware components
If you have performance issues with applications, it's much cheaper to just buy yourself better hardware, compared to the benefits you loose in switching from a higher-abstraction language to a lower one (and I don't have anything against C++, I've been a C++ developer for a long time).
How about comparing maintenance problems when trying to find memory leaks in C++ code compared to garbage-collected C# code?
"Hardware is Cheap, Programmers are Expensive": http://www.codinghorror.com/blog/archives/001198.html

Obfuscation at source-code level more effective than obfuscators?

Learning from my last question, most member names seem to get included in the Project Output.
Looking at some decompilers like 9rays, Salamander, Jungle, many obfuscating techniques seem to have been already defeated, there's this one particularly scary claim:
Automatically removes string encryptions injected by obfuscators ~ Salamander
So is manual, source-code level obfuscating more effective than post-compile / mid-compile lathered, 'superficial' obfuscation by well known (easily defeated??) obfuscating programs?
Obfuscating source-code is going to be self-defeating in terms of maintenance.
If your project is so 'secret', I guess you have two choices:
Place the 'secret' proprietry code behind a service on a server that you control
Code it in a language so not easy to decompile such as C/C++
Maybe, debatably, but you'll destroy maintainability to do so.
Is this really worth it?
Actually this just comes down to security through obscurity, i.e. it's not security at all it's just an inconvenience. you should work fromt he assumption that any party interested enough will decompile your code if they can access it. It's not worth the pain you'll inflict on yourself to make it very slightly more time consuming for the evil haxxors. Deal with the real security problems of access.
As people stated obfuscation is about raising the bar. If you obfuscate your assembly you will stop a casual developer whose just curious but you won't stop a slightly motivated person from reverse engineering.
If you want to raise the bar a little further many obfuscation tools let you use non-printable characters as member names. use reflector on itself to have a look. This will stop a lot more people, I might look at obfuscated code to understand it, but if I can't read it, I'm not going to go through the pain of dumping it to IL, and renaming all the members manually, no motiviation for me to waste that much time.
However for some people there is a motiviation so you need to go another step if your business requirements nessecitate it. But no matter what you do if the computer can read it, there will be someone out there who can read it too. The goal is to reduce the number of people who can read it or would be motivated to read it.
There are also some tricks which you can use to make reflector break (Obfuscator from PreEmptive breaks reflector in some cases but of course you can still read the IL). I had an interesting conversation once with a developer of an obfusction tool and I won't be able to do it justice but he had a way to make reflector completly break by having the code jump dynamically around. For example one moment in your function a then you'd jump to the middle of function b. Doign this cause PEVerify to raise errors so they never actually implemented it but kind of neat idea.
annakata is correct. Really all you can do is make it more difficult (and costly) for the person to reverse engineer the software.
My company identified several areas in which we wanted to make it as difficult as possible for reverse engineering. For example our files are a binary format which each object in our hierarchy responsible for saving itself and reading back the correct version. This means for a person to read our files they would have replicate our entire hierarchy in the code they create to read our files. In addition much of the information in the Job file is useful without the corresponding bit in the shop standards files. So they have to do the work twice in order to understand what the job file is saying.
Several critical areas (dongle protection, communication with our metal cutting machines) reside in Win32DLL. Which means that they would have to know assembly and how to make DLL that replicate other DLLs signatures in order to reverse engineer our software. Plus our design with our CAM software is that it is highly interactive with the cutting machine (information being exchanged all the time)
From the few time we heard about competitors trying to deal with our machines alone they wound up replacing the electronics with their own in order to finish the job. Major bucks to do this.
Part of the steps we took was based on our own experience with trying to deal with competition's machine and software. We took that experience and learned how to tweak our setup. Of course we have limits in that we are not going sacrifice reliability or maintenance just for the purpose of defeating reverse engineering.
For your case, you will have to ask yourself what part of your software would be of interest to your competitors and proceed from there. If you are a vertical market developer (machine control, specialized accounting, etc) I suggest using a USB dongle for software control.
Otherwise use a serial number system and accept that people are going to pirate your software and build that into your business model. The purpose of a serial number scheme is that is relatively unintrusive, and hinders causal copying plus give you a remote chance of tracking down where the copy came from.
The problem there is you will be sacrificing readability to do it. If your project is that sacred to protect, I believe it is safe to assume two things:
The project is large enough that the hit in readability will come back to bite you in the ass.
The people who want to reverse-engineer it will do so anyway. It will just take a slightly larger feat of intelligence to determine what things do (instead of just reading the member names).
I am alarmed that you're even considering code level obfuscation. Won't you be obfuscating the code for yourself too? How do you intend to ever work on it again? For the sake of maintainability this shouldn't be done.
But consider this: -
Suppose there was a script/app that you can run that would open your project and cleverly obfuscate every string/variable name in your project and you compiled it afterward while your original code is securely untouched in a separate location.
Now that's some idea.
Actually code level obfuscation is less secure than what the obfuscators out there can do. This is primarily because obfuscators can take advantage of strict CLI implementation details that are not permitted by language compilers. For instance, it is entirely legal for private fields to all have the same name - but there isn't a compiler out there that will let you do that.
you can use a technique like this : http://g.palem.in/SecureAssembly.html using this you write in .net but you embed into a c++ executable your .net executable ,

Categories