Wednesday 27 June 2012

Steganography: Hands-On approach

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.
As always, here are the links: .GMK file and .EXE file

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.

No comments:

Post a Comment