A Flash Developer Resource Site

Results 1 to 15 of 15

Thread: Encrypting A Swf In A .PNG

  1. #1
    5+5=55 Schfifty Five's Avatar
    Join Date
    Jun 2006
    Posts
    698

    Encrypting A Swf In A .PNG

    This is sort of a response to this thread, but I figured I'd give it its own thread just in case other people were interested. I wanted to try encrypting a swf in a png, and here's what I came up with.

    Here's an example swf (it's a concept for a game I was working on awhile ago, but it's irrelevent to this ):
    (give it a few seconds to load)
    http://img136.imageshack.us/my.php?i....swf&width=800

    And here's the .fla (sorry, it was too big to attach):
    http://www.mediafire.com/?x4eibqtxslf
    In it you'll find a simple preloader, a png in the library, and some code (see below).

    Here's what I did to get from a swf to a png:

    1. Load the swf to be converted with URLLoader, with the dataFormat set to URLLoaderDataFormat.BINARY.
    2. Create a new BitmapData object big enough to store all the data in the swf in its pixels (in this case 3 bytes per pixel, since the png will be 24bit RGB)
    3. Read data from the loaded ByteArray in groups of 3 bytes, setting a pixel of the BitmapData each time, along with some simple encrypting (just applying xor to each pixel).
    4. Encode the BitmapData as a png: http://www.kaourantin.net/2005/10/pn...er-in-as3.html
    5. Since flash doesn't let you save things to your computer directly (except with AIR), I encoded the png as a Base64 string, copied it to the clipboard, and the pasted it into a Base64 decoder to get the png.

    One thing I noticed is that Flash seems to always export the png as 32-bits even if you import it as 24-bits, so there's a wasted alpha channel... if anyone knows how to force it to export as 24-bits, I'd appreciate it if you could tell me... or I'll have to change the code so it uses the alpha channel as well.

    It takes between 4 and 5 seconds on my computer for the png to be converted back to a swf (~500kb). However, I didn't optimise the code much yet, and the conversion could be done over multiple frames so it doesn't freeze up like it does.

    Here's the (manually obfuscated) code that converts the .png in the library to a swf, and adds it to the stage, basicially doing the exact opposite of what the other swf did:

    Code:
    function $($$) {var _={},_0={},___,_0_=__=[1,0,0],_$={},$_;_$._=$$.width;_._=function(__,___=0,____=0,__0=0){(_.__==_.___&&(_.__==0))?_0_.push(1<<_0_.length):0;return __0?0:(_._(0,0,0,1),(__?__.getPixel(_.__,_.___):(_.__=___,_.___=____,_0._O=__)))};
    _.__=_.___=0;_.$=[ByteArray,Loader];_._(0);_0._=((__[(__[0]<<1)+1]>>1)+_._($$)<<__[(__[0]<<1)+1])+(_._(0,__[0],0),(_._($$)>>__[__[(__[0]<<1)+1]>>1])&(--__[__[(__[0]<<1)+1]]));
    _$.$=[(__[0]<<1)+1,__[__[(__[0]<<1)+1]>>1],__[(__[0]<<1)+1],0];_0._0=new _.$[0]();$_=_$.$[0]+1;__[_$.$[0]-1] = _._($$);___=(_0._&__[__[$_-1]]);
    while($_<_0._){if(!($_%_$.$[0])){(++__[0])==_$._?(__[0]=0,__[1]++):0;__[_$.$[0]-1] = (_._(0,__[0],__[1])?_:_._($$));}
    _0._0.writeByte(((__[_$.$[0]-1] >> _$.$[($_%_$.$[0])+1]) & __[__[_$.$[0]]])^___);$_++}_0._0.uncompress();addChild (new _.$[1]).loadBytes(_0._0);}
    
    $(new $$$(0,0));
    If anyone can make sense of it, you're seriously insane, since I can't even completely understand it anymore

    I think it's safe to assume that if someone decompiles your swf and sees that garbage ^ along with a single image filled with "noise", they'll probably give up pretty quickly. It wouldn't be too hard for someone to figure it out if they were dedicated enough, but something like this would probably stop most people right away.

    A couple of notes for anyone who wants to play around with something like this too:

    - Make sure you have the image set to "Lossless" on Export, and not "Photo (JPEG)"
    - When reading data from a ByteArray, be aware of the difference between readByte (-128 to 127) and readUnsignedByte(0 to 255)... it caused me some trouble
    - This will only work with Flash 9 / AS3 swfs.

    Anyone have any thoughts on whether or not it'd be worth it to do this with published games?
    Last edited by Schfifty Five; 06-27-2008 at 03:07 AM.

  2. #2
    The New Guy
    Join Date
    Nov 2007
    Posts
    67
    I've just tried it out. Pure genius!!
    Thats brilliant and I think it could do with turning into some sort of application which can help ease the process of encrypting the SWF through the various stages.

    As for the delay - its the same for me. Around 4 - 5 seconds (and my machine is 2 and a half years old!), It isn't so bad if you display a "decrypting" message/status while it happens, but if the code can be optimised then thats even better for larger SWFs (5Mb+).

    If you get some time, can you please post a working example FLA of the SWF 2 Bmp process (I'm not too good at working with loaders and BMP data!). It would be nice to test it out on a few of my smaller games. Thanks!

    Just one quick question - is there any difference in file size between the original SWF file and the final PNG?

  3. #3
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Love it. You've raised the bar. Next step: embed it in multiple? non-noise assets steganographically, so that if someone decompiles and looks at the library, they see images of you giving them the finger.

  4. #4
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    So I've had "steganographic" and "swf" bouncing around in my head all day, and decided to skim through the swf file format specs. Turns out that there's potentially a LOT of padding zeroes all over the place to get tags byte aligned since individual records in the file are not byte aligned. This doesn't help you put your swf in something else, but it does help if you want to put something unseen in your swf. Like, say, a decryption key. It's also entirely possible to put undefined tags into the swf, which will simply be ignored by players that don't understand them (and potentially screw up decompilers, but that's just a guess). There's great potential to muck around with the swf file itself, which amuses me because a side effect would be that the original swf wouldn't even run correctly after a single decompile-recompile cycle even if you think you changed nothing.

    These aren't true steganographic techniques since examination of the file would reveal data where you expect no data, but it'll confuse the pants off someone trying to steal your stuff.

  5. #5
    Knows where you live
    Join Date
    Oct 2004
    Posts
    944
    I really think that the image technique has a lot of potential to do really confusing things. Combined with some of the more traditional techniques in the main .swf it would be a complete pain to fix.

    One thing that nags me is whether it is actually that hard to recover the original .swf. Like, the initial wtf factor of an image is pretty substantial but if you know that the .swf is encoded in the images, an auto format and quick refactoring should make it pretty clear what is going on.
    The greatest pleasure in life is doing what people say you cannot do.
    - Walter Bagehot
    The height of cleverness is to be able to conceal it.
    - Francois de La Rochefoucauld

  6. #6
    The New Guy
    Join Date
    Nov 2007
    Posts
    67
    I definitely think we're onto something here. I really think we need to code an app which will solve this. My AS3 skills are still in their infancy, otherwise I would have written one by now and posted it here.

    I personally think most coders who are clever enough to decrypt the SWF are just curious George's wanting see how your game works, thats all. They're smart enough to write pretty much anything they want and most of 'em have ethics.
    Its the lazy ones who leech off other people's work for a quick profit, that we need to worry about. But I think even the most basic protection will pack enough rat poison to keep them from trying anything more complex than a decompiler. Still, its a funny old world and its best to take no chances.

    I love the PNG idea as it prevents the theft of both code and graphics! The decryption takes some time to complete, but if it was tagged with a simple progress bar then I'm sure people wouldn't mind.

  7. #7
    5+5=55 Schfifty Five's Avatar
    Join Date
    Jun 2006
    Posts
    698
    Quote Originally Posted by 5TonsOfFlax
    Love it. You've raised the bar. Next step: embed it in multiple? non-noise assets steganographically, so that if someone decompiles and looks at the library, they see images of you giving them the finger.
    Haha I like that idea
    I was thinking of seperating all the assets from a swf (graphics, sounds, etc...) from the actual code (which should be pretty small by itself). Then the code part could be encrypted in a real image (someone giving them the finger ) by using the lower bit of each color channel (no-one will notice the difference between 0x000000 and 0x010101). The code would then just have to load all its assets from its parent.

    If someone was really hardcore about protecting their swf, imagine something like:

    1. Split all the code from the assets, leaving a swf with just code.
    2. Manual obfuscation first - just a few simple things to make code harder to follow, i.e. shifts instead of multiplying by powers of two, ?: instead of if, etc...
    3. Automatic obfuscation - i.e. http://www.ambiera.com/irrfuscator/downloads.html - renaming variables, etc...
    4. Use SWF Encrypt 5 on it (it didn't work too well when I tried the trial, but hopefully the full version is better / they'll make improvements).
    5. Embed the encrypted swf in a png using the lower bit of each color channel (it'd still look like a normal picture 7-bit per channel color depth is hard to tell from 8-bit)
    6. Another possible step: encrypt the data going into the png with RSA or something, and require authentication from a server before the key to decrypt it is sent.
    7. Create the wrapper swf to reconstruct it from the png, along with all the assets it needs.
    8. Obfuscate / Encrypt the wrapper swf.
    9. Finally... put the wrapper swf in the MochiAds version control system.

    Another possibility: swfs in wavs/mp3s?

    I know this is all overboard, but it might be cool to try.

    After I clean up the code a bit I'll post the SWF to PNG converter .fla for anyone interested.


    Quote Originally Posted by f-zero
    I personally think most coders who are clever enough to decrypt the SWF are just curious George's wanting see how your game works, thats all. They're smart enough to write pretty much anything they want and most of 'em have ethics.
    I think you're right about that (in fact I've done that a few times ... I would never steal code, but sometimes I like to see how something is done and whether or not it's the same method I would've used).
    People who steal code for profit on the other hand would probably target something with minimal/no protection just because it's easier/quicker for them.


    Quote Originally Posted by 691175002
    One thing that nags me is whether it is actually that hard to recover the original .swf. Like, the initial wtf factor of an image is pretty substantial but if you know that the .swf is encoded in the images, an auto format and quick refactoring should make it pretty clear what is going on.
    True, if someone wanted to and they had the skills to do so, they could definitely get back the original swf. However, something like this would stop a lot of idiots with decompilers (who really don't know what they're doing) from stealing the code, since they'd probably give up and look for something else to steal

    Quote Originally Posted by 5TonsOfFlax
    So I've had "steganographic" and "swf" bouncing around in my head all day, and decided to skim through the swf file format specs. Turns out that there's potentially a LOT of padding zeroes all over the place to get tags byte aligned since individual records in the file are not byte aligned. This doesn't help you put your swf in something else, but it does help if you want to put something unseen in your swf. Like, say, a decryption key. It's also entirely possible to put undefined tags into the swf, which will simply be ignored by players that don't understand them (and potentially screw up decompilers, but that's just a guess). There's great potential to muck around with the swf file itself, which amuses me because a side effect would be that the original swf wouldn't even run correctly after a single decompile-recompile cycle even if you think you changed nothing.

    These aren't true steganographic techniques since examination of the file would reveal data where you expect no data, but it'll confuse the pants off someone trying to steal your stuff.
    That sounds interesting, I'll have to look into it

  8. #8
    The New Guy
    Join Date
    Nov 2007
    Posts
    67
    Quote Originally Posted by Schfifty Five
    Then the code part could be encrypted in a real image (someone giving them the finger ) by using the lower bit of each color channel
    Yeah that would be funny.... or perhaps you could use that infamous "Goatse" image!! LOL Now that would be enough to freak any wanna-be hacker out!


    Quote Originally Posted by Schfifty Five
    After I clean up the code a bit I'll post the SWF to PNG converter .fla for anyone interested.
    Awesome! Can't wait for it.

  9. #9
    Knows where you live
    Join Date
    Oct 2004
    Posts
    944
    Storing the code in a different way than the assets seems like more work than its worth.

    On the other hand, if you if your swf already loads most assets externally and is only around .7MB you could do some fun stuff without worrying about ballooning the file size too much.
    The greatest pleasure in life is doing what people say you cannot do.
    - Walter Bagehot
    The height of cleverness is to be able to conceal it.
    - Francois de La Rochefoucauld

  10. #10
    5+5=55 Schfifty Five's Avatar
    Join Date
    Jun 2006
    Posts
    698
    Sorry about the delay guys, the source is attached (includes the swf to png converter, and the non-obfuscated png to swf converter).

    When creating a png, it'll store it as a Base64 encoded string in your clipboard (since Flash can't save things to the hard-drive on its own).
    To get the png, just Google for a Base64 decoder, like this one. Paste what's in your clipboard, choose decode, and select "export to a binary file, filename: " and put in something like example.png and it'll make the png for you.

    If anyone has any problems with it not working, let me know... it might not always work (although everything I tried worked, except a Box2D Flash demo).

    I'll post an example of encrypting a swf in a real image in a little while.
    Attached Files Attached Files
    Last edited by Schfifty Five; 06-30-2008 at 12:56 AM.

  11. #11
    Ө_ө sleepy mod
    Join Date
    Mar 2003
    Location
    Oregon, USA
    Posts
    2,441
    Cool, sweet work and thanks for posting!

  12. #12
    The New Guy
    Join Date
    Nov 2007
    Posts
    67
    Awesome! I just tried it on one of my smaller work-in-progress game and it seems to work nicely. It screwed up at first but thats cos I forgot to set the image encoding to lossless/gif.

    The extra data wasn't too much either. A 11,300 byte SWF ended up being an 11,484 byte PNG which is pretty good. The final SWF with the embedded PNG and decryption routines was 14k so it works quite well.

    As for speed, it was pretty much instantaneous, but I'll try it on one of my larger games and let you know how it goes.

    Thank you so very much for posting this!!!

  13. #13
    Junior Member
    Join Date
    Dec 2009
    Posts
    2
    It's a great way to protect our projects. But is there a way the reverse it or is it one way encryption. I've checked the internet and couldn't find any other articles about that.

    Is it reversible?

    BTW thanks a bunch.

  14. #14
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Of course it's reversible, or else it wouldn't be able to play the swf. But if you're asking whether you can take the obfuscated swf and get back the original, then the answer is "it's really really hard, that's the point."

    This sort of encryption/obfuscation should be done to the final product. Keep the non-obfuscated stuff around in case you need to make changes and republish.

  15. #15
    Junior Member
    Join Date
    Dec 2009
    Posts
    2
    thanks for the quick reply. I was thinking about using flash with png encryption in a serious project. I'm still not sure though

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center