The Encrypted Buffer module implements a compile time C/C++ buffer encryption and obfuscation to hide your static C/C++ buffers such as encryption keys, primes, initialization vectors or any sort of static resources.

Every encrypted buffer uses unique generated keys with every single build. This sort of protection gurantees a high hurdle and wall against potential attackers, since the protection is unique by buffer and build.

Encrypted Buffer Example

#include <antispy/libantispy.h>

void decrypt_database_with_key(const char* d, size_t size) {
  for (int i = 0; i < size; i++) {
    printf("0x%x ", d[i] & 0xFF);
  }
}

int main(int, char **) {
  // The key is encrypted at compile time.
  auto key = OBUFFER("\x00\x10\x20\x30", 4);

  // This generates a unique decryption routine on the stack to pass the decrypted
  // buffer to 'decrypt_database_with_key'.
  decrypt_database_with_key(static_cast<::std::basic_string<char>>(key).c_str(), 4);
  return 0;
}

Encrypted Buffer Assembly Output

Using the OBUFFER macro here makes sure the given buffer is encrypted at compile time.

The resulting type is an antispy buffer which provides all functions and operators to cast the data to plain std::string and char* types on the stack. Combine this technique with Flow Obfuscation and Anti-Debugging so you can protect the usage of static buffers even more.

mov     r8d, dword ptr cs:aJcj         ; "åûåÂ"
mov     [rsp+78h+var_54], r8d
xor     r8b, 86h                       ; decrypt 1st -> 0x00
movzx   edx, byte ptr [rsp+78h+var_54+1]
xor     dl, 86h                        ; decrypt 2nd -> 0x10
movzx   ecx, byte ptr [rsp+78h+var_54+2]
xor     cl, 86h                        ; decrypt 3rd -> 0x20
movzx   eax, byte ptr [rsp+78h+var_54+3]
xor     al, 86h                        ; decrypt 4th -> 0x30
mov     byte ptr [rsp+78h+var_58], r8b
mov     byte ptr [rsp+78h+var_58+1], dl
mov     byte ptr [rsp+78h+var_58+2], cl
mov     byte ptr [rsp+78h+var_58+3], al
mov     qword ptr [rsp+78h+var_40+8], 0Fh
mov     qword ptr [rsp+78h+var_40], 4
mov     eax, [rsp+78h+var_58]
mov     dword ptr [rsp+78h+var_50], eax
mov     byte ptr [rsp+78h+var_50+4], 0
movups  xmm0, [rsp+78h+var_50]
movups  [rsp+78h+var_30], xmm0
movups  xmm1, [rsp+78h+var_40]
movups  [rsp+78h+var_20], xmm1
xor     edi, edi
lea     rbx, [rsp+78h+var_30]
db      66h, 66h
nop     word ptr [rax+rax+00000000h]

As you can see in the compiled binary and assembly output the buffer is decrypted just before it is used. Here, we see a simple XOR which is one of multiple encryption / decryption algorithms we support.

For production use we recommend to use more advanced techniques that are shipped including antispy or implementing your homebrew encryptor or decryptor.

If you protect that code block with Control Flow Obfuscation and Anti-Debugging techniques the attacker has almost no chance to easily extract the decrypted buffer since it is not present in the binary.

Example Binaries

You want to have a look at the result in your favorite Disassembler? Please request example binaries here.