I'm looking into binary obfuscation for an exectuable binary written in C++. I realize preventing cracks is impossible, but making it slightly harder would be nice.

No matter how complex the actual license scheme is, I can't think of a way to validate it that doesn't ultimately boil down to:

if (doVeryComplexLicenseValidationCheck())
    //execute code

...which would be trivially easy to bypass by any competent cracker. But obviously there are many copy protection systems out there that have been very difficult for people to crack...so what are they doing that I'm missing? Is there a way to obfuscate a simple branch like that, that's much more difficult to bypass?

  • 1
    Did you watch the YouTube series „live overflow“? That might help. Despite the painstakingly obvious German accent, there’s parts on exactly what you are asking for C: youtu.be/qS4VWL5R_OM – Tobi Nary Sep 24 '18 at 18:19
  • Some systems decrypt their own code on the fly using a key computed by the complicated copy protection scheme. But there are a lot of ideas and most are used in tools which are proprietary and not documented (to make it harder to crack them). – allo Sep 25 '18 at 8:36

Here are some tips that may help you, but just remember that any one with a good understanding of assembler will found it.

Lets imagine your program is like you describe:

int main() {

    if (myCheck()) {
            std::cout << "License pass\n";

And here is the disassembler of the code.

00000000004006d3 <main>:
4006d3:       55                      push   %rbp
4006d4:       48 89 e5                mov    %rsp,%rbp
4006d7:       e8 da ff ff ff          callq  4006b6 <_Z7myCheckv>
4006dc:       84 c0                   test   %al,%al
4006de:       74 0f                   je     4006ef <main+0x1c>
4006e0:       be d1 07 40 00          mov    $0x4007d1,%esi
4006e5:       bf 40 10 60 00          mov    $0x601040,%edi
4006ea:       e8 b1 fe ff ff          callq  4005a0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
4006ef:       b8 00 00 00 00          mov    $0x0,%eax
4006f4:       5d                      pop    %rbp
4006f5:       c3                      retq

So by adding asm statements in your code you can make it more difficult.

#define OPS1 "xor \%rbx,\%rbx\n"
int main() {
    __asm__ volatile (
            "push %rax\n"
            "xor %rax,%rax\n"
            "pop %rax\n"

    if (myCheck()) {
            std::cout << "License pass\n";
    __asm__ volatile (OPS1);

And here is the output

4006d3:       55                      push   %rbp
4006d4:       48 89 e5                mov    %rsp,%rbp
4006d7:       50                      push   %rax
4006d8:       48 31 c0                xor    %rax,%rax
4006db:       58                      pop    %rax
4006dc:       e8 d5 ff ff ff          callq  4006b6 <_Z7myCheckv>
4006e1:       84 c0                   test   %al,%al
4006e3:       74 0f                   je     4006f4 <main+0x21>
4006e5:       be e1 07 40 00          mov    $0x4007e1,%esi
4006ea:       bf 40 10 60 00          mov    $0x601040,%edi
4006ef:       e8 ac fe ff ff          callq  4005a0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
4006f4:       48 31 db                xor    %rbx,%rbx
4006f7:       b8 00 00 00 00          mov    $0x0,%eax
4006fc:       5d                      pop    %rbp
4006fd:       c3                      retq

This case is really really easy, but if you have a good understanding of templates, assembler you complicate a bit the code generated.

  • I fail to see how that would "make it more difficult". Inserting random instruction sequences doesn't change the fact that there's a single license-checking function, and it may interfere with the normal operations of the compiler. – duskwuff Oct 24 '18 at 22:29
  • This is just an example, you can put the random instructions inside the function on whatever place you want, of course any one with some experience on assembler will get the result but depending on the code that you put this can be a hard work. – camp0 Oct 25 '18 at 14:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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