14

In the Java world, sometimes it seems to be a problem, but what about C++? Are there different solutions?

I was thinking about the fact that someone can replace the C++ library of a specific OS with a different version of the same library, but full of debug symbols to understand what my code does. Is it a good thing to use standard or popular libraries?

This can also happen with some dll library under Windows replaced with the "debug version" of that library. Is it better to prefer static compilation? In commercial applications, I see that for the core of their app they compile everything statically and for the most part, the DLLs (dynamic libraries in general) are used to offer some third party technologies like anti-piracy solutions (I see this in many games), GUI library (like Qt), OS libraries, etc.

Is static compilation the equivalent to obfuscation in the Java world? In better terms, is it the best and most affordable solution to protect your code?

6
  • 5
    Remember, whatever you do, someone with too much time will be able to deobfuscate/decompile it
    – Zavior
    Jul 1, 2012 at 15:54
  • 24
    Many compilers come with a /O obfuscation switch. Some even have multiple levels of obfuscation, up to /O3 ;)
    – MSalters
    Jul 1, 2012 at 22:24
  • 1
    @MSalters No, g++ has -O3 ;) Aug 3, 2012 at 10:34
  • 2
    Just in case anyone isn't familiar with typical compiler options: compiler options /O, /O3, -O, -O3 are more typically optimization levels, not obfuscation levels, although optimization can cause some amount of obfuscation. Generally, obfuscation-by-optimization is not enough to defeat reverse engineering. Feb 1, 2021 at 5:17
  • 1
    Your program in the end must be simple enough to be understood by something as dull as a CPU. That makes it simple enough to be understood by (some) humans. I'm sure there's something to learn here?
    – tofro
    Mar 23, 2022 at 14:19

4 Answers 4

36

Don't Waste Your Time on Losing Battles

As noted in many other similar answers for C++ and other languages, this is mostly useless.

Further Reading

Selected reads on the topic (not all are C++ specific, but the general principles apply):

StackExchange Answers

Papers

Famous Quotes on Obfuscation:

Then finally, there is that question of code privacy. This is a lost cause. There is no transformation that will keep a determined hacker from understanding your program. This turns out to be true for all programs in all languages, it is just more obviously true with JavaScript because it is delivered in source form. The privacy benefit provided by obfuscation is an illusion. If you don’t want people to see your programs, unplug your server. - Douglas Crockford


Never?

I'm not saying you should never obfuscate and that there aren't any good reasons for it, but I seriously question the need for it in most cases, and its cost-effectiveness.

Furthermore, there are situations where obfuscation is a de-facto requirement. For instance, if you write viruses, obviously obfuscation (and a dynamic one, preferrably) is as good a thing for your program's survival as it's ability to replicate. However, this hardly constitutes a "common" case...

3
  • We once used a hardware dongle where there was a licensing requirement to obsfurcate all the dongle function calls - and they supplied a tool to do it. Always made me a little suspicious about the quality of their 'protection' ! Jul 2, 2012 at 4:06
  • @MartinBeckett: a tad weird indeed.
    – haylem
    Jul 2, 2012 at 7:23
  • On Java/Kotlin, obfuscation provides a bit of code-security, but also shrinks the names, so the output file would be a bit smaller in the end. On C/C++ I don't know how much this helps though, because on C/C++ I think the output is quite small and relatively more unreadable than on what you get from Java/Kotlin. Mar 9, 2021 at 12:50
5

No, this is not worth the effort, and I think it's completely unnecessary. The functions you call can probably be guessed by the functionality you provide.

The reason obfuscators exist for Java is because the mapping between Java byte code and Java source code is fairly well defined, and the names of all functions and member variables are stored in the byte code (regardless of whether they are public, private, or protected) so a Java byte code interpreter can present some generic Java which shows the structure of the original source fairly well for unobfuscated source.

C++ compiles directly to machine language. It can be disassembled, but assembly language is fairly tedious to deal with. Decompilation is much tricker because of all the changes optimizers make to the code during compilation.

0

Thinking about this, there are several different types of obfuscation. Let's start with obfuscation of source code, which is a complete waste of time; it's hard enough to understand without that! So let's instead focus on obfuscation of the delivery package, of how the code gets delivered to the user.

Minor obfuscation

Minor obfuscation exists to prevent the casual user from poking their fingers in and breaking things easily. It doesn't keep out the determined hacker, but it does have value in helping to ensure that the things you are asked to support are what you've actually delivered. The level of protection required for this sort of thing is really quite low; the delivery package merely has to not look readable and editable (without specialist tools) and that's quite good enough.

Javascript minification is an example of this, though it's not marketed as such. Nobody in their right mind would want to read and edit a minified JS file, even if it is quite technically possible to do so if you're determined/persistent enough.

Similarly with delivering Java applications. Merely packaging the code into an executable JAR will stop the majority of foolishness, even though it's got all the force of a polite “Please Keep Off The Grass” sign in a city park.

Even when delivering C++ code, stripping the unnecessary symbols from the executable will be enough to qualify as minor obfuscation. The key is that it is awkward to read the result as a user, but not a problem to execute it as a computer.

Major obfuscation

Major obfuscation is keeping the determined and knowledgeable user out. It's also a total losing game; if a computer can execute it, a person can pick it apart and work out what it does. The closest you could get would be to make the program decrypt itself continually, transforming what it does at one time into a completely different thing that it does at another time. Creating such thing would be rather difficult and still wouldn't keep a really good hacker out (though they would be really quite cross with you by the end of it at the amount of effort required to decrypt all that self-modifying code).

It's much better to think in terms of other solutions. For example, you could keep the “crown jewels” of the code on servers that you control and only permit service calls to it, making the client an essentially free giveaway that is a front-end to the valuable bits. Or you could go the more contract/legal route, and only hand over executables to organisations that formally agree to not poke around inside your code or compensate you if they do so (so that'd be some sort of NDA). The aim would be to create a strong incentive for the hacker to not hack, and for the users to keep the code away from any hackers not bound by the agreement.

But you must not assume that your code can never be cracked. With virtualisation, any program state of an execution can be examined and tracked, and anything that tries to defeat that (e.g., clock tracking to an external time source) will be much more likely to cause problems for legitimate users than hackers. (See the history of DRM for how even very determined publishers of information can't keep their systems secure once the code is in the hands of their opponents.) It's much better to focus on actually making legit users happy. The losses from the occasional crack will be as nothing compared to the extra money brought in through satisfying customers properly.

-4

It is important not to obfuscate code - neither the compiled, binary code, nor the source code.

You should release your software along with the source code, and allow users to scrutinize it, make suggestions, contribute to your codebase, or even fork it and create their own versions.

If the economic model you are working on is based on non-access to the code, or restricting the copying or use of the code, then it is a usurious artifice, likely resulting in other people having to duplicate your efforts, as well as in less robust code. Disseminating closed-source code hinders the advancement of software in general.


The above may not be universally recognized fact, but I believe it to be true. For further reading, have a look at the GNU project's philosophical section.

2
  • Sorry but you cannot make as much money off open sourcing your code all the time. Not every project is better off as open source and some people don't want their work to be copied or dissected. I'd say it depends, you can contribute some parts of your code as modularized projects to the open source community but others not due to business secrets and such. Either way, pushing the GNU agenda is not in the spirit of the question. Aug 6, 2022 at 10:42
  • @BullyWiiPlaza: "You cannot make as much money etc." <- You should not base your life on maximizing personal monetary gain. "and some people don't want their work to be ... dissected" <- Some poets don't like their poems to be dissected either; they should just not read the dissections. "Some people don't want their work to be copied" - Some people derive pleasure from tying other people up and inflicting. Ok, I can respect their personal kinks, but we should not let society work this way. Also, I kind of doubt that the copying is what bothers "some people".
    – einpoklum
    Aug 6, 2022 at 14:43

Not the answer you're looking for? Browse other questions tagged or ask your own question.