text is visible in compiled script

Hi

I only started looking at c++ yesterday..

I've written a simple script that downloads files from different URL's and writes them to the correct locations on my Linux PC.

I've compiled the script using :
[code]g++ test.cpp -o new -lcurl[code]

If I cat the file I can see the individual URL's in the output. They are bit obscure but you can still make out whats going on.

I also run a system command from the script, and again that is quiet easy to read if you cat the compiled script.

I want to give this to a couple of colleagues, but I'd like to make it hard for the casual user to see the actual URL's or system command.

Any way to stop that ? or to hide / obscure the plain text ?

Thanks :D
If you're viewing the finished binary as a plain text file, you might see the string constants stored in the file, as you see. The compiler has to store these values somewhere, so they end up unencrypted in the output binary.

What you're looking for is encryption. For the simplest of cases, you can use bitwise-xor encryption. In your code, you use the encrypted version and decrypt the strings before you use them. A decryption function:

1
2
3
4
5
6
7
void decrypt(char* buffer, const char* key, size_t bufsize)
{
    for(size_t i = 0; i < bufsize; ++i)
    {
        buffer[i]= ^= key[i];
    }
}


The good thing about bitwise-xor encryption, is that the decryption and encryptions functions are exactly the same. Now for an example:

1
2
3
4
5
6
7
8
int main()
{
    char encrypted[] = {106, 77, 102, 105, 104}; //"hello" encrypted using the key
    const char key[] = {2, 40, 10, 5, 7}; //Our key
    decrypt(encrypted, key, 5); //Decrypt our string
    std::cout << encrypted << std::endl; //Prints "hello"
    return 0;
}


You simply use the encrypted values in your binary, which will then be stored in the resulting executable. Then just before you use the values, you decrypt them. Note that this isn't a very good security measure (anyone with a disassembler can pause the code just after the decryption function, showing the decrypted string), but the strings surely won't show up in the resulting executable directly.
Last edited on
Thanks for the reply.
I've added this in to test with and I get an error when I try to compile it :

1
2
test.cpp: In function ‘void decrypt(char*, const char*, size_t)’:
test.cpp:23:20: error: expected primary-expression before ‘^=’ token


Any ideas ? Thanks

There is a simple syntax error typo'd on that line. Take a look at the provided code and see if you can figure it out.
Last edited on
Thanks sorted that !

changed
1
2
3
        buffer[i]= ^= key[i];
to
        buffer[i] ^= key[i];


When I run this I get:
hello{�


Why do I get the extra characters ?
Thanks
Do you know the difference between these two:
1
2
char foo[] = {'w', 'o', 'r', 'l', 'd' };
char bar[] = "world";
Possibly :)

foo[] is an array and bar[] a string ?
What does that mean for the two of them?
One is a string of characters, the other is an array of individual letters.
What are the sizes of foo[] and of bar[] ?
the same, i think
Think again.
Last edited on
hmmmmmmm................
They both act the same basically, I guess the array needs an explicit null termination sequence.
I've compiled the script using :
g++ test.cpp -o new -lcurl


@TomT

Just some advice not related to your problem, always compile with the warning level set high:

g++ -std=c++14 -Wall -Wextra -pedantic-errors test.cpp -o new -lcurl

Warnings are a good thing, they tell you where you may have problems with your code.

Good Luck !!
Another hint:
the output (that produces mysterious characters) is calling one of these functions: http://www.cplusplus.com/reference/ostream/ostream/operator-free/
Good. Do you understand the (minute) difference of the solutions?

Recap:
1
2
3
char foo[] = {'w', 'o', 'r', 'l', 'd' };
char bar[] = "world";
std:.string gaz = "world";

The foo is an array of characters.
The bar is an array of characters.
The gaz is a std::string object.

The foo is initialized with an array of characters. The initilizer array has 5 characters and thus the foo has 5 elements.
The bar is initialized with an array of characters. The initilizer array has 6 characters and thus the foo has 6 elements.
The gaz is initialized with an array of characters. The initilizer array has 6 characters but string stores only the first 5 non-null elements.

1
2
3
std::cout << gaz;
std::cout << bar;
std::cout << foo;

The string gaz has its own output operator that correctly outputs the 5 characters of "world".
The bar outputs exactly "world", because there is a null character after the 'd'.
We have no idea what prints after the 'd' of foo, because those memory locations can have anything.

In other words, the "world" is a shorthand for writing {'w', 'o', 'r', 'l', 'd', 0 }

The array used in Shadowwolf's program did not include a terminating null. Hence, it does print random characters after the hello.


The use of std::string cunningly avoids many issues that one encounters with plain array.
Last edited on
Thanks for this explanation.
That make sense.. sort of :)
Thanks for the advise on this query.

I've used: http://create.stephan-brumme.com/hide-strings-executable/ which works well, but the resulting code ends up hard to read as I'm referenceing encoded values in an array and then writing them using decode(arr[1])

eg:

std::cout << decode(arr[1]);
not :
std::cout << gaz;

This gets hard work when the code is encoded URLs, paths and files etc.

is there a neater, easier to read why to do this with out making the strings fully visible ?

I'm not looking for total security, just the ability to make the code harder to decompile or read the strings from.

Thanks :)

Topic archived. No new replies allowed.