Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Obfuscating C++ Shared Library

I've been asked to help obfuscate a library (written in C++) which will be distributed to clients. I've already discussed why obfuscation is not necessarily a good idea, and seeing as licensing will be integrated into the software many concerns regarding copy protection are moot.

Regardless, I've been asked to research methods anyway. I've looked into header mangling (and the like) as well as HARES, but I fail to find much that I can use for a library (naturally, these things would destroy any form of API rendering the library useless).

What techniques can I apply that would work for libraries? While I would appreciate recommendations for tools (or compiler flags, etc.) that might be helpful I would like to stress that this is not a tool-focused (i.e. closable) question, but rather one focused on applicable techniques.

like image 458
ahjohnston25 Avatar asked Feb 23 '15 02:02

ahjohnston25


People also ask

What is the purpose of obfuscating code?

Obfuscation means to make something difficult to understand. Programming code is often obfuscated to protect intellectual property or trade secrets, and to prevent an attacker from reverse engineering a proprietary software program. Encrypting some or all of a program's code is one obfuscation method.

Can you reverse obfuscation?

Press F12 to open Developer Tools inside Chrome. Now switch to the Scripts tab, right-click and choose De-obfuscate source. That's it!

What is binary obfuscation?

Binary obfuscation is a technique that aims to shadow the real application code to make it difficult for an external person, who does not have access to your sources, to understand what your program has to do.

Why is compressing and obfuscating your code important?

It's essential to hide business logic and code to make it harder for attackers to gain access and start debugging and tampering with your app. (They often repackage an application with malicious code.) 3. Code obfuscation can drastically reduce file size, and download times can be reduced drastically as well.


2 Answers

I wouldn't put much energy to doing it very thoroughly, because the reverse engineer is going to win this round.

https://softwareengineering.stackexchange.com/questions/155131/is-it-important-to-obfuscate-c-application-code

Obfuscating C++ binaries is a bit of a losing battle. It depends on who you are dealing with, but if your reverse engineer is smart enough to use IDA Pro and a couple of plugins, and a good debugger then it shall all be for naught.

Obfuscation Priorities

  • Where you can give the reverse engineer useless function names.

Honestly, this doesn't help that much, since ultimately your code will have to call some kind of non obfuscated shared library to get anything done. At some point you will use the standard libary, or the STL, or even make a system call.

  • Add false pathways to confound static analysis

So that the reverse engineer can have fun with a debugger. Anti-analysis techniques are well known to the reverse engineer, and they can almost be circumvented with a debugger like ollydbg.

  • Write debugger foiling code

That reverse engineers love to play with. Again, this is an expected move, and the response is to just to step around the offending code, or to modify away the traps. Anyone with any formal training in RE will blast past this.

  • Pack most of my binary into an encryped region which is decryped by a stub just before execution.

Same answer as above. Reverse engineers train for this from day one.

  • Keep in mind the reverse engineers are looking for targeted morsals of information - very rarely are they trying to recreate the entire application. Security intensive code, code for license validation, code for home base communication, networking code. These are all prime targets - put your energy into making these thorny places to live.

  • Keep in mind that binaries from the largest corporations on the earth are routinely reverse engineered by people in their early 20's.

  • Don't leave your debugging symbols in the final binary, as those will definitely help with analysis.

  • If you are dedicated to doing this right, also focus on wasting the engineers time - time is always against the reverse engineer.

Remember, that any meaningful obfuscation might also cost you the performance gains that justified working in C++ in the first place. There are many zones in the C world (and for that matter the Java world) where meaningful obfuscation just isn't possible. Games for instance, cannot conceal their calls to the OpenGl APIs, nor can they truly prevent engineers from harvesting their shader code.

Also remember that the reverse engineer is watching your code at the assembly level most of the time. He'd rather have your function names, but he can live without it if need be. He can see what your program is doing at the most finite level possible. It is only a matter of time before he finds the critical routines.

For your purposes, find a program to mangle function names, make your boss happy, and call it a day. At least at that point, reverse engineering the software will not be trivial.

like image 160
MrSynAckSter Avatar answered Sep 23 '22 19:09

MrSynAckSter


Well really you have 2 primary vectors that you have to guard against

  1. Disassembley
  2. Debugging

My favourite method for preventing the first issue is in memory decryption, take parts of your executable code and encrypt it, have it self decrypt in memory while your library is running, you can also checksum parts of the code and compare the checksum against what is loaded in ram ( have the encrypted portions check the decrypter and vice versa )

Another neat trick is to statically link libraries that you use into your executible so they cannot be easily swapped out to try to see what your code is doing.

Now debugging checking interrupt vectors helps, another trick is to check the 'timing' between various portions of code ( for example if more than a couple of milliseconds worth of delay occurs in code that should execute significantly faster than that then it can be assumed that the code is being debugged

like image 32
Damian Nikodem Avatar answered Sep 23 '22 19:09

Damian Nikodem