Obfuscate strings in your program C

Posted on
Crackproof your software Anti-Reversing

The first step in breaking software protection in any cracker manual would be to search for all the strings inside the binary. The strings in your binary can be helpful for various reasons:
- it can actually store the serial / license key;
- it may point to the serial checking function by presenting a user with validity check message;
- it may hint what packers/protectors were used on the binary;
- it may disclose compiler/linker used to create the program;
- it may reveal the protection mechanism used, e.g. if you try to query the machine’s current time for time limited trials or looking for a specific license file to open.
In short – looking for strings in the software is the easiest step available even to the least knowledgeable person. In few posts I will try to look and summarize various ways we can obfuscate the strings inside the binary. This, I would say, lifts the difficulty level of cracking your software from 0 to ½ level.
So first the easy cases – compiled languages. Let’s start with C/C++ and first way to do it is to use wonderful preprocessing macros of the compilers.
Pros:
- easy to implement;
- mangles printable characters to unprintable/special ones;
- better than none.
Cons:
- uses char and integer interchangeably, so the resulting mangled value should be less than 255 and no Unicode;
- strings while stored inside binary mangled have to be de-mangled just before using them (true of any obfuscated strings that interact with the user) so using a live debugger discloses them in memory.
The process is three-step:
1) mangle strings before storing them with the help of macro which does arithmetic reversible manipulation, then store them in initialized/global variable storage;
2) de-mangle strings in place just before using them again with the macro function by reversing the mathematical function used to mangle;
3) after using the string mangle it back in memory.
The code follows:

#include <stdio.h>
#define HIDE_LETTER(a)   (a) + 0x50  // add 50 to each letter as an integer before storing
#define UNHIDE_STRING(str)  do { char * ptr = str ; while (*ptr) *ptr++ -= 0x50; } while(0)
#define HIDE_STRING(str)  do {char * ptr = str ; while (*ptr) *ptr++ += 0x50;} while(0)
int main()
{   // store the "secret password" as mangled byte array in binary
	char str1[] = { HIDE_LETTER('s') , HIDE_LETTER('e') , HIDE_LETTER('c') , HIDE_LETTER('r') ,
	HIDE_LETTER('e') , HIDE_LETTER('t') , HIDE_LETTER(' ') , HIDE_LETTER('p') , HIDE_LETTER('a') , 
	HIDE_LETTER('s'),HIDE_LETTER('s') ,HIDE_LETTER('w') ,HIDE_LETTER('o') ,HIDE_LETTER('r')
	,HIDE_LETTER('d'),'\0' }; 

	UNHIDE_STRING(str1);  /* unmangle the string in-place, after finishing the variable str1 
	will hold the actual string*/
	printf("Here goes the secret we hide: %s", str1);
              HIDE_STRING(str1);  //mangle back string stored in a global variable str1

    return 0;
}

Running radar2/Hiew/strings –e on our compiled binary with and without string hiding gives this:
With obfuscation:

yurisk@ubuntu:~/Desktop$ rabin2 -z -qq  HideStrings.exe | grep -i password 
yurisk@ubuntu:~/Desktop$ 
yurisk@ubuntu:~/Desktop$ rabin2 -z -qq  HideStrings.exe | grep -i secret  
Here goes the secret we hide: %s  
yurisk@ubuntu:~/Desktop$ strings -a HideStrings.exe | grep -i secret  
Here goes the secret we hide: %s  
yurisk@ubuntu:~/Desktop$ strings -a HideStrings.exe | grep -i password  
yurisk@ubuntu:~/Desktop$  

Hiew listing of all strings Alt+F6 Without obfuscation:

yurisk@ubuntu:~/Desktop$ rabin2 -z -qq  HideStrings.exe | grep -i password  
secret password  
yurisk@ubuntu:~/Desktop$ rabin2 -z -qq  HideStrings.exe | grep -i secret  
secret password  
Here goes the secret we hide: %s  
yurisk@ubuntu:~/Desktop$ strings -a HideStrings.exe | grep -i secret  
secret password  
Here goes the secret we hide: %s  
yurisk@ubuntu:~/Desktop$ strings -a HideStrings.exe | grep -i password  
secret password  

Hiew listing of all strings Alt+F6