Encrypted PrimitiveOther

The Encrypted Primitive module implements a compile time C/C++ primitive data type encryption and obfuscation to hide your static C/C++ types. More...

Detailed Description

TL;TR

The Encrypted Primitive module implements a compile time C/C++ primitive data type encryption and obfuscation to hide your static C/C++ types such as char, int, long, long long, etc.

Every encrypted primitive uses unique generated keys and primes in every single software build. This sort of protection guarantees a high hurdle and wall against potential attackers, since the protection is unique by primitive and build.

Problem: primitives.

There are many magic values stored in primitive data types. One example is a simple 32 bit checksum or file header magic constants. There are many more examples - almost anything you can think of is possible here.

int main(int argc, char**)
{
    int checksum = 0xDEADBEEF;
    if (Parse() == checksum) {
        Do();
    }
}

As you can see - in this code we compare a function result to a magic checksum.

How is this code an issue?

While you can do this - or similar things - and it is absolutely fine - it is easy for attackers to automatically extract this checksum and perhaps this is just the missing piece of information to emulate / crack your logic.

Solution: encrypted primitives.

As discussed earlier in this page we provide a compile-time obfuscation to all kinds of primitive data types.

This compile-time primitive obfuscation brings the following advantages:

  • Compiler generates code on the stack and it is obfuscated on the stack.

  • Even if you don't change your primitive data value content the obfuscated buffer will change on every single compilation of your software.

  • It gives an extra hurdle to attackers since the generated code makes common disassemblers and attackers busy.

Below is a minimal example that shows how to use antispy SDK - Encrypted Primitive module.

#include <antispy/libantispy.h>

int main(int argc, char**)
{
    ANTISPY_ENCRYPTED_VALUE(int, checksum, 0xDEADBEEF);
    if (Parse() == checksum) {
        Do();
    }
}

We have changed one line of code that changes the declaration and initialization of the primitive and everything else just works 'as is', though the code that the compiler is about to generate is totally different since the number is put on the stack - obfuscated and requires a de-obfuscation when accessed.