Often times one needs to obfuscate game assets. If a game relies on BMP files, SDL2, and vim, the first step to obfuscating the assets without the need of cryptography is already done.

SDL2 has out of the box support for Windows BMP files. The macro to load BMP files is declared in SDL_Surface.h and takes a file path string as an argument:

#define SDL_LoadBMP(file) SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1)

By dissecting the contents of SDL_LoadBMP we learn SDL_RWFromFile returns an SDL_RWops pointer. Fortunately, an alternative declaration in SDL_rwops.h exists, and it allows for a generic read from raw memory:

extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromMem(void *mem, int size);

Combining this call with SDL_LoadBMP_RW forms a new definition, SDL_LoadBMPFromMem, and it provides a facility for loading BMP files from memory:

#define SDL_LoadBMPFromMem(mem, size) SDL_LoadBMP_RW(SDL_RWFromMem(mem, size))

Thankfully, a hex dumper named xxd comes pre-installed with vim and it includes a huge time saving flag named -include for transforming a file (in this case, a BMP file) into a C style array with a size constant:

xxd -include Image.bmp

The output prints directly to stdout, printing both the unsigned char array Image.bmp and the length of the array:

unsigned char Image_bmp[] = {
...
    0xeb, 0x01, 0x40, 0x33, 0x33, 0x13, 0x80, 0x66, 0x66, 0x26, 0x40, 0x66,
    0x66, 0x06, 0xa0, 0x99, 0x99, 0x09, 0x3c, 0x0a, 0xd7, 0x03, 0x24, 0x5c,
    0x8f, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
...
};
unsigned int Image_bmp_len = 373;

Loading the BMP image is just a matter of using the newly crafted SDL_LoadBMPFromMem macro:

SDL_Surface* arrow = SDL_LoadBMPFromMem(Image_bmp, Image_bmp_len)

With xxd able to reverse BMP images, and SDL2 being able to natively load BMP images without the need of external dependencies like SDL_image, this solution is the first step to obfuscating important art assets in a lightweight fashion that would otherwise spoil a game’s plot. Yes, the game binary will bloat, and the BMP can still be reversed with an objdump of the binary, but by hiding the BMP in the binary the secret asset will be hidden to most of the players.

Of course, if the game becomes really popular, chances are it will be disassembled, and the Streisand Effect may otherwise further publicize the assets that were once obfuscated!