Click here to Skip to main content
16,017,351 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
Hi,


I'm working on some tools for a new game called Terra Tech(check it out ^_^).

You can create "techs", save, swap and tweet them. The save file is a png snapshot image. They put the object specifications in the image using steganography. I am trying to reverse engineer this.

Here is an image on my twitter:
https://pbs.twimg.com/media/CRJO2kqWgAEy0hn.png[^]
or just look on my tweets (new account): https://twitter.com/GreysonTyrus[^]

They use the UnityEngines Texture2D to manipulate the image and I don't want to have to build my solution in Unity. I need to recreate the behaviour

They use the png rgba values. The first char should be 'G', the next chunks will be a compressed JSON string using IonicGZip.

I know that Texture2D read the image left to right, bottom to top. I am using Hjg.Pngcs to parse the image.

I had this working at one point, but now it appears that all of the images alpha is 255 (never 254 which i would expect about 50% of the time)

Can anyone parse this image, take the last bit of each pixels rgba values, put them into a byte array and get the first byte to be 'G'(h:x047 / d: 71)?

I have a lot of code but am happy to post whatever you ask for.

Thanks ^_^
Andy

UPDATE: Quote from James: Terra tech Dev (available to contact on forums) to me:
Quote:
Hi!

In short - you're welcome to edit any files you like. You've purchased the game for your own use and we're happy to let you do whatever you want with it (within reason ;) ). BUT - if you encounter any problems with an edited save or a cheated game, we can't support you with fixes as you're playing a version that is no longer connected to ours.

If you wish to share your findings with the community - that is fine too. We only ask that you make it clear that if they tinker with the game and it breaks - we won't be supporting them with fixes.

Thanks for letting us know Andy! x



UPDATE: My Code:

UnitTest: used in place of a "Main" for debugging:
C#
    [TestClass]
    public class PngFileToolsTests
    {

        [TestMethod]
        public void GetEncodedObjectFromImage()
        {
            var location = Assembly.GetExecutingAssembly().Location;

//get the image from my twitter mentioned above, or find one
            location = @"C:\Program Files (x86)\Steam\SteamApps\common\TerraTech Beta\Cabbie.png";

            FileInfo info = new FileInfo(location);
            
            PngFileTools tool = new PngFileTools();

            var result = tool.GetCodedBytes(info);

           Assert.IsNotNull(result);

        }
    }


The Unity code uses Unities Texture2D to load the image. It is loaded into an array or Color32. This item has an r,g,b, and a byte. They use the last bit to encode the message. I don't have access to Unity Engine tools unless I run my app within Unity. I don't want to to that (why would I). I use Pngcs[^] to decode the png files. I have tried reading rows bottom to top, and top to bottom (always left to right) with no joy. My current code just takes the entire byte array of all Least Significant Bits (LSB) of all bytes read at once. Here is the code that does that:
C#
public class PngFileTools
{
    private static byte[] PixelArrayBytes(Stream fs)
    {
        var pngr = new PngReader(fs);

        int channels = pngr.ImgInfo.Channels;
        if (channels < 4)
            throw new Exception("This example works only with RGBA images");

        BitArray bits = new BitArray( pngr.ReadRowsInt().Scanlines.SelectMany(r => r.Select(c => c % 2 == 1)).ToArray());


        pngr.End();
        return bits.ToByteArray();
    }
    private static int DecodeFromBytes(byte[] carrierPixels, int offset, int numBytes, out byte[] messageBytes)
    {
        messageBytes = new byte[numBytes];

        carrierPixels.Skip(offset).Take(numBytes).ToArray().CopyTo(messageBytes, 0);

        return numBytes;
    }

    public string GetCodedBytes(FileInfo pngFileInfo)
    {
        byte[] pixelArray;

        using (FileStream fs = new FileStream(pngFileInfo.FullName, FileMode.Open))
        {
            pixelArray = PixelArrayBytes(fs);
        }
        return CodedBytes(pixelArray);
    }
    public string GetCodedBytes(Stream pngFileInfo)
    {
        byte[] pixels = PixelArrayBytes(pngFileInfo);
        return CodedBytes(pixels);
    }
    private static string CodedBytes(byte[] pixels)
    {
        int num = 0;
        byte[] array;

        num += DecodeFromBytes(pixels, 0, 1, out array);


        char c = (char)array[0];
        if (c > 'G' || c < 'A')
        {
            return null;
        }
        return ""; //extractedText;
    }
}


I have used some extension methods, but any that you're missing do just what they say they do. Let me know if you want to look at them and I'll post them
Posted
Updated 17-Oct-15 2:38am
v3
Comments
BillWoodruff 17-Oct-15 5:53am    
It appears to me you are trying to hack what is now a demo version of a future commercial game from a company you have to buy an "R&D Pack" from to design whatever. Doubt you'll get help with that here.
Andy Lanng 17-Oct-15 7:37am    
I've spoken to the devs (specifically James) about my project. They are happy to let me continue to create my tools. This one aspect applies to just the screenshots which are, by declaration, public domain

Also, I can see much of their source (ILSpy) but I don't want to change these files, just individual save files and tech images. I support the creative team and only want to add to the hype.

I have the beta game + R&D pack
BillWoodruff 17-Oct-15 7:39am    
Then, why are those Devs not helping you with your task ?
Andy Lanng 17-Oct-15 7:42am    
I don't want to burden them with my pet-project. They have given me permission, but I am trying to reverse engineer what occurs in UnityEngine. That's not the kind of support I can ask for, or feel I can ask for :S
BillWoodruff 17-Oct-15 10:38am    
I hope you get some help here, but I still fail to see why you end up having to hack some format in Unity.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900