6

So I made an application with visual 2012 that loades images and shaders (plain text). But really, I don't want people to open the images and shaders and mess around. How can I compress all this external files into a single or multiple files but still readable by the executable?

marcg11
  • 720
  • 2
  • 10
  • 20
  • [zlib](http://en.wikipedia.org/wiki/Zlib) – masoud May 19 '13 at 19:11
  • 1
    Are you trying to prevent people taking your images and shaders to use for other purposes, or people modifying them so that your program looks or behaves differently? Or both? The former requires some sort of encryption or obfuscation while the latter only requires validation. In addition, both tasks are effectively impossible against a determined attacker unless you have tamper-proof hardware support so another question is how difficult do you want to make it? Discouraging a casual user won't be hard but a serious hacker is another story. – rhashimoto May 23 '13 at 13:56
  • Hi thanks for answering. I'm happy with a simple one, just so they don't get the images, shaders, models, etc easily. – marcg11 May 23 '13 at 15:49

3 Answers3

5

This question is difficult to answer authoritatively because without tamper-proof hardware it is essentially impossible to secure content against a sophisticated hacker. But given the clarification that a simple deterrent is good enough, how about just embedding your content as resources in the executable? Note that there are tools freely available to extract resources from .exe files.

Alternatively you could encrypt each file and decrypt it when your application loads it. The encryption could be as simple as xor-ing each byte with a known constant byte or you could use a real encryption algorithm like one from the Microsoft CryptoAPI. Using a real algorithm will improve obfuscation but still won't be truly secure.

Here's a simple program that uses this RC4 implementation (which is easier to use than CryptoAPI) to encrypt or decrypt a file and write it to stdout:

#include <algorithm>
#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>

// insert RC4 implementation here

int main(int argc, char *argv[]) {
   const std::string password = "no more secrets";
   const std::string filename = argv[1];

   // Read file into a buffer.
   std::ifstream f(filename.c_str(), std::ios::in | std::ios::binary);
   std::vector<char> buffer;
   f >> std::noskipws;
   std::copy(
      std::istream_iterator<char>(f), std::istream_iterator<char>(),
      std::back_inserter(buffer));

   // Initialize the key from a password.
   rc4_key key;
   prepare_key((unsigned char *)password.data(), (int)password.size(), &key);

   // Encrypt or decrypt (same operation).
   rc4((unsigned char *)&buffer[0], (int)buffer.size(), &key);

   // Write result to stdout.
   std::cout.write(&buffer[0], buffer.size());

   return 0;
}

Note that this is not a secure way to use RC4 and the RC4 algorithm itself is no longer considered secure.

Community
  • 1
  • 1
rhashimoto
  • 15,650
  • 2
  • 52
  • 80
  • Strictly speaking, it's irresponsible to refer to a simple xor as "encryption". – Iron Savior May 23 '13 at 23:10
  • 1
    @IronSavior I tried to bend over backwards to say this is not secure. There is a whole spectrum of encryption algorithms - some are (believed) secure and some are not. XOR is an example of a substitution cipher - I would disagree that substitution ciphers are not a primitive form of encryption. – rhashimoto May 24 '13 at 00:24
  • Can you provide some code for encrypting and decrypting files? How would it work? – marcg11 May 24 '13 at 07:17
  • You have an article plus sample code here: http://msdn.microsoft.com/en-us/library/ms867086.aspx – Simon Mourier May 24 '13 at 12:05
  • @marcg11 Basically you would read a file into a buffer, then apply encryption or decryption on the buffer. I added an example to my answer. – rhashimoto May 24 '13 at 14:05
  • Thanks, but is there another rather than windows? – marcg11 May 24 '13 at 14:13
  • @marcg11 What do you mean? The code I posted does not use any Windows API. – rhashimoto May 24 '13 at 14:16
  • So with this code provided, i read an image, encrypt it and save it to a file .xxx, then use this file to decrpyt, right? Oh and howcome encrypt and decrypt are the same? – marcg11 May 24 '13 at 16:24
  • @marcg11 Yes, you would encrypt and save the files beforehand, then read and decrypt the encrypted files at runtime. Why are the encrypt and decrypt operations the same for RC4? RC4 works by generating a pseudo-random stream of bytes which is XORed with the input data. Encrypt and decrypt are the same operation because XOR is its own inverse. See http://en.wikipedia.org/wiki/RC4#Description. – rhashimoto May 24 '13 at 16:43
2

Check out http://en.wikipedia.org/wiki/PAK_(file_format)
There is a library on SourceForge for Quake2 pak files: http://sourceforge.net/projects/paklib/
However, I recomend going directly to the source: https://github.com/id-Software/Quake-2/blob/master/qcommon/files.c

ctn
  • 2,887
  • 13
  • 23
2

Encode the files into your executable in source code. Create an array with each byte of the file encoded one byte at a time. It is a very simple technique to include data in an executable.

Lars
  • 626
  • 7
  • 8