Stumbling upon Steganography (Inspiration behind this post):
Have you heard about the site called 300 Mechanics?
Well, I guess, many have heard about it. It’s on the first
page of Google search for terms like “game mechanics” and it’s quite a class of
its own. I have hunted this website often for game ideas and though I am not a
great admirer of turn-based and card mechanics (which is a considerable portion
of the mechanics posted there), there is a lot of food for your thoughts.
And there was this one post, about saving game save files as
images.
I liked the idea, though I wanted to generalize the idea
like this : Saving any file as image (not just changing the extension, actually
making a picture out of it) and restoring the original file from that image
alone.
Now, you are going to shoot me, I know: This is almost what Steganography is, though the original file is hidden in another innocent
picture.
But unfortunately, until one of my friend (to whom I
described the idea) told me about this “Steganography” thing, I believed it was
one of my new ideas and I was super-excited about it.
So, here it is: It is not really an original idea, so I
decided to make a “How-to” tutorial on it using Gamemaker ...
Concept Briefing: Saving the file as image
Once
you get started, you can easily see how easy the concept is:
Let’s
say there is a file “xx.xxx”. At first, somehow we need to draw it to the
screen and save the screenshot. This screenshot will be our stand-alone image
(instead of the file) and we can restore our original file from this image
(using the algorithm I will describe later).
The process we will use |
So,
lets come to the most important term here: “somehow”.
How
exactly are we going to draw a file to the screen?
Here
is my approach:
At
first, read the file byte by byte (so, it doesn’t matter what type of file it
is as every format is similar in binary) and return in decimal format (for e.g.
“A” should be read as 65, its ASCII value and not as the binary equivalent of
65 ).
[Now.
Let’s talk about RGB colours a bit. Every colour in RGB format (HSV format is
also possible) consists of a value of Red, green and Blue (in the range 0-255)
because red, green and blue are three primary colours and every colour can be
made using a variation of these.]
Our
primary task, now, is to convert this number returned in ASCII format to a
unique colour, which is to be drawn on the screen. One of the facts, which
might appear astonishing at first, is that extended ASCII table has 256 values
(0-255) and range of value of red, green and blue each in RGB format is also
0-255. [This is probably due to the fact each of them is allotted one byte (8
bits) of memory space. So, there are (2^8)=256 possible values.] So, now we
have to choose any one-to-one function which has equal range of domain and
co-domain to convert ASCII value to RGB value. For sake of simplicity, we are
choosing a easy relation between the two: Blue value of RGB=ASCII value of the
character, Green value=0 and Red value=0. What it simply means is that we use
the ASCII value as the blue value in RGB colour format and we use the value 255
for both red and green in the RGB colour.
Now
for each byte of data, we have one specific colour. Next, we decide to draw these
colours on the screen. It is quite simple: Just as in notepad, we start from
the top-left corner of the screen by
drawing a pixel with the colour corresponding to the ASCII value of the first
byte and then we move towards right (1 pixel at once) by considering the next
byte of data and so on. There is just one thing- Similar to text wrapping, we
have to use a wrapping function so that this drawing function moves to the next
line when it is about to go out of view.
So,
here we have our file drawn to the screen. The final task is to take a snapshot
of this drawn screen and save it as the stand-alone picture instead of the
file. Our next section deals with how to restore the original file from it.
Concept Briefing: Restoring the original file from the screenshot
The actual process of Steganography |
We
are almost finished with our steganography tutorial. This part is easier than
the earlier and shorter too.
So,
we already have our screenshot. Let’s get the original file back from it…
Here,
we need to have a function which will help us pick any colour from the screen
and tell its red, green and blue values. Fortunately, Gamemaker has the
draw_getpixel() and colour_get_blue()
functions to help us with this situation.
Initially,
we need to clear the screen and load the screenshot as the background.
Then,
we will need to start from the top-left corner of the screen [(0,0) in
Gamemaker], pick the colour at that point,
get its blue value, convert it to its ASCII equivalent (which is actually equal
to the blue value here),write the character equivalent of this ASCII value to a
“new” file, move towards the right one
pixel at a time and continue this process until there is only the background
left. [Also, we will need to use the aforementioned wrapping function to make
sure that we move to the next line of the screen when the colour-picking
function is about to go out of view.] To identify the background, I used black colour
as the background. As the R, G and B values of black are 255,255,255
respectively, we can easily identify the black colour by getting just the red
or green value (as we are using red=0 and green=0 for our drawn points).
So,
when this whole process completes, we will have the content of our original
file back in the “new” file. Just make sure to give it the same extension as
your original file to access it properly.
Problems and suggested improvements:
Two
most important drawbacks of this tutorial is that it will support only small
files (about 350KB) and the process is very slow in Gamemaker.
To
increase the file size limit, there is an easy solution: use surface
(applicable with Gamemaker only) to draw instead of the screen, because the
maximum possible dimension of any surface is much more than the screen size.
There will still be a limit in the file size because surfaces do have
dimensional constraint (due to memory constraint), but still it is a lot
higher. Also, you may use multiple surfaces wisely to get rid of this drawback.
Theoretically, this problem can be solved.
The
sloppy performance you’ll experience is only due to the slow performance of the
draw_getpixel() function. Unless you can re-create a faster version of this
function with an external DLL or extension written in a faster programming
language, you’ll have to live with it.
Few Facts:
What we just did isn't real steganography, it's just a part. Steganography involves the removal of a particular sequence of pixels of an image with other pixels which contain the hidden data. We created this pixels which contain the hidden data, but we didn't do the removal part. The removal part isn't that hard, and you can easily try that. Also most of the times, a password is used to vary the sequence of removed pixels.