Gaming Your Way

May contain nuts.

goAway, Nephew of SiCo

What do the following things have in comon?

 

test.swf (5,87 KB)

goAway.swf (8,07 KB)

test.png

goAway.jpg


After my funny little episode with the hacked version of Law of the West I started wondering how to prevent that little pricks that can use an URL changer or decompiler to mess around with my stuff. Above you see what might be a solution. It will not stop someone who really, really wants to see your code from seeing it in the end but it will make it reasonably hard.

So how can you prevent that someone just grabs a decompiler, changes things and publish it back?

Maybe if there is no game inside the swf, at least not directly visible.

This is a screenshot of the library of the goAway.swf. Nice, eh?

Right now goAway is a neat little console app (so you can batch it), that takes an swf, optional a textfile full of vars (so you can check them later from the game itself) and spits out a png.

This can be included in another swf (to be released) and is unpacked after loading - and viola you have your swf again, though it'll be like a loaded swf, so you loose your "root".

There is a lot more security related portential behind this:
- load the png from a server instead of including it.
- use a key to decrypt the png
- create the png on the fly on the server each time with a new key
- store multiple swfs/files in a single png to pack a multi file game into a single distributable swf without a lot of trouble
- and and and

The above swf is just a proof of concept and there is still alot to do on the goAway app in oder to make it useable (maybe a frontend, new features (like dynamic png dimensions, splitting into multiple png files for more security, different ways of reading writing the data into the png (byte order)) not to mention an AS3 class to easily handle the goAway png.

After all I'm quite pleased with the idea, as it makes it quite hard for script kids to mess around with a published flash file with the available tools. Making hacking a game just that little bit harder that is needed to seperate the users from the coders.

And of course SiCo will be used to obfuscate the goAway code ...

Ha!

nGFX

Son of SICO

More tinkering with Air, and SICO now has a front-end

soSICO_grab.jpg

The reason for me firing this old project up again was covered in a comment in the last post. Basically the GYWEncrypt app is only as strong as the code decrypting it, so I wanted to mess the source code up for that process as much as possible.

Now this is beta, and it could break. A couple of things to take note of are:
* It doesn't bother messing with local vars. Unless I'm totally mistaken Flash doesn't save local var names anyway, so
var heresMyUltraSecretPassword:String="fistedNun";
won't show up in the source anyway ( Well, not as literally as that ).
* There are some white space issues I want to sort out, although the messed up file does rip out comments so it should result in a smaller file-size. In theory you'll never be looking at the messed up output, it's just that it's bugging me it not quite doing what I wanted ( It's the design tart in me ).
* It doesn't yet ( If ever ) handle lines like
private const var heresMyUltraSecretPassword:String;
The same may apply for private static vars too.
* Because of oop it can't do anything to public functions, as by default your public function are just that ( It only works on 1 file in isolation not a whole project ). If you want that, shell out for this instead.
* I've really not tested it to death. As with most home grown apps it's a case of "It works for me".
* On the Air installer it shows up as unsigned publisher blah, blah, blah. It doesn't do anything naughty at all, it's not going to format your hd or d/load porn in the background. If you don't trust it / me, then fair enough don't d/load it.
* Never ever ever save over your original code. May sound stupid me saying that, but I feel I need to. The filename is saved with an extra ".", so even if you should screw it up it'll be saved as
myLifesWorkRuined..as
But please don't risk it, call the file test..as for peace of mind.


What would be really cool would be if anyone testing it has any problems if they could post the original code snippit and the broken output in the comments. I'm guessing there are going to be issues ( It really depends on how many if this ever gets out of beta or not, if the world and his dog have problems then I'll just open source it and be done with it. If it's only minor stuff then it shouldn't be a problem fixing it up ).

If this all goes well ( It's sweet for me ) then the next couple of days should see GYWEncrypt finished too, although we're not sure what we're going to do with that yet.

Here's the link for the air file, thanks in advance for giving it a bash
SonOfSICO.zip 21k

Squize.

Air today, gone...

Air. The future of RIA. Unless you try and actually use it.

I've been wanting to write a swf encryptor for ages and last night I finally cracked ( As I'm working on something that I really don't want decompiling for various reasons ).
It was a toss up between Zinc and Air, but I opted for AIR 'cause in theory it is the future and therefore should have better support than Zinc.

So after all the hype surrounding Air I should just be able to google around, find out how to drag and drop, save a file and some other basics. I develop in Flex rather than cs3 'cause it's a million times better, but any search for Flex and Air just brings up examples using MXML. That's not great.

Eventually I found a hacky way to create an Air project in actionscript in Flex ( It's so convoluted it's untrue. You create a Flex project as opposed to an AS one as usual, tick the Air box, but on the part where you set the document class you alter the mxml extension to .as and it works ).
Getting there. Published the main class and up popped... nothing. More searching and I found out how to set it up ( A big thanks to Toby for blogging about it, without his words I'd have given up all together ).

Cool, got a window in place now. Close it, try publishing it again, and... nothing. Lot's more searching ( And swearing ) and I found out what the problem was, and the cure. If you don't exit your app correctly ( ie call an exit() after adding a listener to the close button ) then it doesn't actually exit correctly ( I found this out myself after a lot of messing about ).
When you publish an air app it runs something called adl.exe ( Adobe Debugging something. I've had enough air googling for a life time so can't face looking it up ) which runs the swf wrapped in the air api.
If you don't call exit() then when you close the app adl.exe keeps running. Ok, that's not the end of the world. What actually is though, is that you can only run one instance of adl.exe. If it's running after you've closed your app incorrectly, then you can't run any more air apps.
The beautiful thing is, it doesn't tell you. Flex doesn't tell you either. It's like they've ganged up to keep us in the dark.

Until I figured out the whole exit() thing, I was working with task manager open closing it down every time. The only solutions I found online were, yep, work with task manager open and...

Ok it kinda makes sense, and if you've got to call exit() then you've got to call it, but c'mon, this is the future of RIA and I've got task manger open to kill it ?
It all feels very beta-ish, from the hacky way to even create an Air project in Flex to that.

Once I got past these hurdles, I must admit it wasn't that bad. The lack of docs ( I only found this after I'd gone through a lot of pain ) has made it a less pleasant exercise than it should have been ( Oh joy, another mxml example for something I want to do with code ).

One weird thing which I'm putting down to me is that when I drag and drop a swf into my sexy little app it runs the app twice. I don't mean it opens another window, it just runs through all the code twice ( In alcon I was getting,
"wtf ?"
"wtf ?"
which was a bit of a give away ). A little kludgy check cleared that up.

At present we've got a simple little app which you can drag a swf onto, it then encrypts that with blowfish via the very nice Crypto library and you can then save that back out.

Next up ( And what I've been swearing at for the past hour or so ) is the decryption routines. Well, the code is being embedded and decrypted, it's just figuring out how to then make that byteArray run as a swf rather than just sitting there annoying me.

Squize.

SICO

As regular readers will know, we've been done over with a hacked version of "Law of the West". Instead of just bitching about it, we've decided to be pro-active.

This is going to take a number of forms, one of which is SICO, or "Source In, Crap Out".
We looked at what encryption and obfuscator software there is out at there, and came across irrFuscator. It looks pretty cool, and at 69 euros isn't going to to break the bank, but it also looked like it was something we could do ourselves without too much effort.
Where SICO fails compared to irrFuscator is that from what I can tell it takes the whole project and messes it up, so public functions ( And therefore getters / setters ) get screwed with too, whereas our project just takes one file and so has to leave anything which could be called from a different class alone.
Also it converts strings, but it looks costly. Looking at the example on their page, "end" gets converted to irrcrpt(23, "uzd."). That kinda looks like a static class is added to the project with a method called irrcrpt, which takes the first value as the "key", and I guess it's just a simple XOR with the string value.
Fine for scrambling a filename, but I think it would be too harsh [ In performance terms ] to do that to every string in the game, so it's easy enough to just add a method in like that by hand for your filenames / passwords / cheat codes etc.

( In case this reads like I'm just bashing irrFuscator, I'm really not. It's better than SICO, I'm just pointing out the differences ).

So what can our baby do ? Here's the loader class we use for it:

package Classes {  
    import flash.events.Event;
    import flash.net.URLLoader;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLRequest;
    
    public class IO {

//---------------------------------------------------------------------------------------
// Properties
//---------------------------------------------------------------------------------------
        private var loader:URLLoader;
        private var callBack:Function;
        
//---------------------------------------------------------------------------------------
//Constructor
//---------------------------------------------------------------------------------------
        public function IO(){
/*
Null constructor, we don't need to do anything here
*/

        }

//---------------------------------------------------------------------------------------
// Public
//---------------------------------------------------------------------------------------
        public function toString():String {
            return "IO";
        }        

//---------------------------------------------------------------------------------------
        public function loadScript(filename:String,callBackArg:Function):void{
            callBack=callBackArg;
            
            loader = new URLLoader();
            loader.dataFormat=URLLoaderDataFormat.TEXT;
            loader.addEventListener(Event.COMPLETE, xmlLoaded);

            var request:URLRequest = new URLRequest(filename);
            loader.load(request);
        }

//---------------------------------------------------------------------------------------
// Private
//---------------------------------------------------------------------------------------
        private function xmlLoaded(eventArg:Event):void{
            var source:String=eventArg.target.data;
            callBack(source);
        }

//---------------------------------------------------------------------------------------
    }
}

And here's what it looks like after being run through SICO:

package Classes {  
    import flash.events.Event;
    import flash.net.URLLoader;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLRequest;
    
    public class IO {

        private var _V64K0q:URLLoader;
        private var _87qjufb1lsM:Function;
        
        public function IO(){
        }

        public function toString():String {
            return "IO";
        }        

        public function loadScript(M85u8En4i:String,_87qjufb1lsMArg:Function):void{
            _87qjufb1lsM=_87qjufb1lsMArg;
            
            _V64K0q = new URLLoader();
            _V64K0q.dataFormat=URLLoaderDataFormat.TEXT;
            _V64K0q.addEventListener(Event.COMPLETE, _v1zr6rD62q);

            var kDu541CN2C5:URLRequest = new URLRequest(M85u8En4i);
            _V64K0q.load(kDu541CN2C5);
        }

        private function _v1zr6rD62q(_wVl6q:Event):void{
            var n1XScOB03y:String=_wVl6q.target.data;
            _87qjufb1lsM(n1XScOB03y);
        }
    }
}

Pretty mashed up. There are still some quirks to it which need ironing out, and it's not got a list of reserved words or anything that cool, but that code is nasty once run through it.

Next we need to actually make some sort of front-end for it, ideally using Air to get to play with that, more possibly with Zinc to make it easier, and then decide what to do with it. It won't ever be for sale, it may be a case of we just give it to friends and let it spread gradually like that, we're not sure yet, but it will be given away. There's no point bitching about hacking, and then coming up with something that makes our stuff safe and screw everyone else.

And that's part 1 ( Or 0.5 ) of our push to try and get the community as a whole being a bit more protected, there is more to come. Olli and I have had some long chats the past couple of days. We both came to the conclusion that yeah, having hacked games floating around sucks, but there are some things which are more acceptable than others.
If LoW had been hacked to use the hi-score component of the system it's been hacked for ( Some "shovelware portal in a box" system ) and everything else had been left intact, then we can swallow that. Just. The game gets spread so the sponsors happy, we get our credit out so it's not too bad for us, the ad gets seen etc. It's not that bad. It's only when the game is just ripped of everything like that we get pissy.

Part of this process of stopping it is to actually get involved with the boards that link these games, for fear of sounding like a politician, it's about education. A lot of sites with hacked games on are run by decent people, just trying to make a couple of quid, and not really knowing about any harm they could be causing 'cause they never ever have any contact with a developer.
Flash games are percieved as such a throw away commidity that the line between IP theft and hosting becomes very blurred. A lot of people who run boards wouldn't dream of hosting mp3's, but see Flash in a totally different light.

We really fucking resent having to spend time on things like this, but if we're in the position of toying with ads and sponsorship as well as the client based work, then we need to protect our IP. Like we all do.

There's more coming,

Squize.