Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Code Obfuscation in AIR sdk #494

Open
Shaunmax opened this issue Oct 13, 2020 · 56 comments
Open

[Feature Request] Code Obfuscation in AIR sdk #494

Shaunmax opened this issue Oct 13, 2020 · 56 comments
Labels

Comments

@Shaunmax
Copy link

Problem Description

With the use of decompilers, our SWF's from android apks are exposing precious code and game design/business logics to our competitors and amateur developers. We need a solid code obfuscation feature in AIR sdk, which should make it extremely harder for hackers to read the code and should make the decompilers to crash.

There were 3rd party developers like kindi providing support for code obfuscation, along with optimisation and asset compression but unfortunately their softwares seems to be outdate and they are no longer providing any support.

As it's extremely risky to release builds in Google Play Store with no code obfuscation. I request @ajwfrost & the harman team to look at this issue at the highest priority and provide us a valuable solution as soon as possible.

I sincerely request other developers to vote for this feature and share their valuable feedbacks.

Appreciate your support.

@htmiel
Copy link

htmiel commented Oct 13, 2020

Or as an alternative, maybe compile AS3 to native code for Android and Windows, as it happens already on iOS?

@ajwfrost
Copy link
Collaborator

This is one I had always wondered about (having done my fair share of decompiling of SWFs - though of course mostly this was to solve our customers' bugs!). The SWF and AS3 specifications are open so anyone can create a decompiler..

AOT compiling is a major piece of work and I suspect third-party or shared SWF libraries may still be needed with non-native code, so I would more be thinking of a way that the SWF files could be encrypted and then for AIR to decrypt them as it loads (like right now it compresses them - again, using open standards) - maybe we could compress them with built-in encryption.

The challenge then is authorising the decryption. We can try to add some obfuscated mechanism within AIR (we'd need to make sure it's not clear to anyone who's trying to work out how we're doing the decryption by looking at the assembler code of the AIR library..)... let me talk to some of our folk internally; we'd welcome other comments/suggestions on this though!

thanks

@blackjyn
Copy link

+1 for code obfuscation support.
our codes is part of our intellectual property

@JohnBlackburne
Copy link

I have for a while thought there should an option to strip the text which decompilers use. I can see why it's there. Flash in particular lets you dynamically load content such as other Flash/SWF apps, access their symbols and methods by name. This was used extensively for advertising/publisher preloaders and to embed adverts in webgames.

But no-one is making webgames any more. We are instead making standalone apps. Dynamically loading code is generally poor practice if not explicitly disallowed. Apps are distributed independently not via preloaders on websites. Adverts are supplied by native code in ANEs.

So it makes sense to strip out code from the SWF, or at least replace it with symbols. At least make it an option for developers who know they are making a final, standalone app. Get it out there quickly and developers can try it and see if there are any issues.

@leossmith
Copy link

Maybe there is a way to integrate Proguard or even better on top of Proguard, make Android compile like iOS apps do, so it will be even harder to decompile.

@dmunsie
Copy link

dmunsie commented Oct 14, 2020

This is one I had always wondered about (having done my fair share of decompiling of SWFs - though of course mostly this was to solve our customers' bugs!). The SWF and AS3 specifications are open so anyone can create a decompiler..

I also would like to see this added.. but....what ever ends up being added to the SDK, please do not change the default actions of the build process and make add ons like this optional via command line vars. Thanks.

@Shaunmax
Copy link
Author

Shaunmax commented Sep 5, 2021

Is it possible for Harman to work along with Kindi or acquire them? they have been out of business for a long time. Their obfuscation software is pretty impressive, if that can be included in AIR sdk that would be a great boost for our fraework.

@2jfw
Copy link

2jfw commented Sep 6, 2021

I could actually imagine that when there was proper code obfuscation more developers would out themselves using as3/flash/AIR. I would think that since its easy to decompile swf a bunch of devs would prefet to not tell anyone about it in order to keep their "secrets" and prevent others from "stealing" their sources/assets

@ajwfrost
Copy link
Collaborator

ajwfrost commented Sep 6, 2021

I couldn't see any way of contacting folk from Kindi, wondering if anyone has a contact there?

To gauge the idea of some priorities though: are people looking mostly to encrypt their assets (images, sound files etc), or to prevent decompilers from showing off the ActionScript source code?

The one thing I wonder is that - if you're using a Windows app at least - it's possible to do a memory dump of a process and then inspect that, which someone could use to get at a decrypted copy of the contents. So I'm not sure whether it's possible to do something completely secure. If we just encrypted the SWF contents and then decrypted them at runtime, it should prevent casual folk from getting at stuff, but anyone with access to the process memory could see the decrypted stuff.

@2jfw
Copy link

2jfw commented Sep 6, 2021

@ajwfrost I would think that Mobile iOS and Android are more important and a target to decompilation than Windows/Mac are since these (mostly) mobile games are likely lightweight in their codebase and assets are more likely to get stripped out and used in other games - e.g. see

"Chinese companies also frequently copy U.S. games, creating unauthorized “clones,” or steal U.S. IP assets. ":
https://www.uscc.gov/sites/default/files/Research/China's%20Digital%20Game%20Sector.pdf

It is more common than you might think.
I would think that both, securing codebase and assets, is nearly equally important, whereas assets are more likely to be stolen.
Personally, I would be more afraid that my codebase gets stolen and reused maybe multiple times as engine rather than them using any assets because I feel the code (/engine) is more precious.

@2jfw
Copy link

2jfw commented Sep 6, 2021

The only contact I have from them from back in 2012, when I bought their SecureSWF application is:

Kindi Software, LLC
10 Yajouz Str
POBox 2684
Amman 11941
Jordan

Phone:+962 6 533 5152 (ext 36)
Fax: +962 6 533 5031

support@kindi.com

@ajwfrost
Copy link
Collaborator

ajwfrost commented Sep 6, 2021

Thanks @2jfw I'll drop them a mail in case they're still around..

In terms of protecting things:
https://stackoverflow.com/questions/18151308/how-to-secure-the-assets-stored-in-android-apk
and presumably the same sort of thing from an IPA file..

Essentially it would always need the ability to decrypt - keys etc - to be present in the app and/or runtime. So it would make it harder, but I don't know whether it would dissuade any "professional" thieves...

@dmunsie
Copy link

dmunsie commented Sep 6, 2021

"Or as an alternative, maybe compile AS3 to native code for Android and Windows, as it happens already on iOS?"
I support the idea, but I'd like to see this ^^^ happen first before spending time/resources on obfuscation.

@2jfw
Copy link

2jfw commented Sep 6, 2021

Is it possible for Harman to work along with Kindi or acquire them? they have been out of business for a long time. Their obfuscation software is pretty impressive, if that can be included in AIR sdk that would be a great boost for our fraework.

Oh yeah, it is/was - I had made very good experience with their software and obfuscating capabilities. I did decompile my obfuscated AIR mobile app at that time and found that it was not readable. The app used some ANEs and SWCs too, so the obfuscator was able to handle that all (though it may not have obfuscated them).

@Shaunmax
Copy link
Author

Shaunmax commented Sep 6, 2021

I couldn't see any way of contacting folk from Kindi, wondering if anyone has a contact there?

I just checked in LinkedIn and found this contact : - https://www.linkedin.com/in/hosam-abu-alam-b4b6524/

To gauge the idea of some priorities though: are people looking mostly to encrypt their assets (images, sound files etc), or to prevent decompilers from showing off the ActionScript source code?

As an independent developer, I dont care much about my code getting exposed, but its difficult to convince our clients who are very much worried about both.

@ajwfrost
Copy link
Collaborator

Just as an update, we will be including a utility to encrypt a SWF file into a forthcoming version of the AIR SDK. Limitations will be:

  1. you will need to have the application packaged with the captive runtime in order to work (well, it would also work with a shared runtime, as long as the shared runtime version also is the same version used by the SDK, or later...)
  2. you won't be able to use the LoaderInfo.bytes property to see the decrypted data - which means you can't use an encrypted SWF as both the primordial worker and a background worker..

As mentioned earlier, it's stand-alone encryption so not completely impervious to cracking by someone who's very dedicated, but it should be at least as good as the Kindi approach..

@2jfw
Copy link

2jfw commented Dec 15, 2021

Just as an update, we will be including a utility to encrypt a SWF file into a forthcoming version of the AIR SDK. Limitations will be:

  1. you will need to have the application packaged with the captive runtime in order to work (well, it would also work with a shared runtime, as long as the shared runtime version also is the same version used by the SDK, or later...)
  2. you won't be able to use the LoaderInfo.bytes property to see the decrypted data - which means you can't use an encrypted SWF as both the primordial worker and a background worker..

As mentioned earlier, it's stand-alone encryption so not completely impervious to cracking by someone who's very dedicated, but it should be at least as good as the Kindi approach..

This is amazing news! Thanks a lot for taking care on this, Andrew!
This is another point, which can be taken well for advertising AIR SDK: "Comes with build-in obfuscation! Do not worry about others easily decompiling your app and stealing your assets and code!"

Just curious, was there any contact/communication with Kindi?

@MalacTheLittle
Copy link

Great news!
I would also add to @2jfw question, are Strings obfuscated too and how strong?

@ajwfrost
Copy link
Collaborator

Just curious, was there any contact/communication with Kindi?

I'd sent a mail to the support email address but didn't hear .. but from earlier info it looked like they weren't supporting the product now anyway.

are Strings obfuscated too and how strong

It's just encrypting the SWF as a whole - so basically a bit like when you compress a SWF, there is an 8-byte header but then the rest of the content can be uncompressed, zlib-compressed or LZMA-compressed; we've just added a further option for this to be encrypted. So you wouldn't be able to read strings... the file is then decrypted upon loading (in the same location as the decompression) so everything is protected up to the point you've loaded in the SWF file to memory.

Which does mean that if someone were to load in the application and then do a memory-dump of the whole process, they could search the memory to find the decrypted SWF. Hmm... so, maybe we (also?) need to provide a utility class for the encryption of individual assets...

@2jfw
Copy link

2jfw commented Dec 15, 2021

Which does mean that if someone were to load in the application and then do a memory-dump of the whole process, they could search the memory to find the decrypted SWF. Hmm... so, maybe we (also?) need to provide a utility class for the encryption of individual assets...

I think asset protection is an important part since they are actually getting stolen (see #494 (comment))

@ajwfrost
Copy link
Collaborator

So I've just been looking through the features that Kindi has and I really am not sure how they do some of that without being able to update the runtime, unless they're having everything accessed via some kind of library and are recompiling all of the ActionScript (which is very possible given the amount of obfuscation and optimization they're able to do...)

So we have a slight advantage by being able to update the runtime itself, but are also perhaps not able to offer the levels of code obfuscation etc that they've put in place! But in terms of asset protection:

  • it should be possible for us to create new SWF 'tags' that replace image data with encrypted versions of images, and then when the render is asking for them, it will decrypt on the fly. As ever, if you took a memory snapshot, then the image would be visible in memory after it was expanded to a bitmap (which would be the same as with Kindi..)

  • we can probably do the same with the constant pool within ActionScript byte code, particularly for string data, but this would need to be expanded into memory when it's used i.e. when a function that references a string constant is first accessed. But we'd need to check a little more how this works in the VM...

Let me know of any other priorities...

thanks

@2jfw
Copy link

2jfw commented Dec 16, 2021

ActionScript-wise, as far as I remember, Kindi have renamed all variables and method names by something like "_loc1", "_loc2" etc.. so it will be hard for anyone who decompiles the code to read and understand it.
They did not obfuscate Strings. Regadring assets/images, I am actually not sure but I would think they were not obfuscated.

So I am wondering, when someone now makes a memory dump form the SWF, will they see the variable and method names I used @ajwfrost ?

@MalacTheLittle
Copy link

@2jfw I'm not sure if this is called obfuscation, but Kindi did made Strings unreadable converting them to kind of functions. Here you can see levels of String encription/obfuscation:

image

Key can be chosen from 32-bit to 288-bit.

I made small example: in Animate I just wrote code var privateKey:String = "ABCDEFGHIJKLMNOPQRSTUVXYZ";.
Result of decompiling unprotected .swf (decompiled with online decompiler) is single .as file:

package test_fla {
   import flash.display.MovieClip;
   
   public dynamic class MainTimeline extends MovieClip { 
      public var privateKey:String;
      
      public function MainTimeline() {
         super();
         addFrameScript(0,this.frame1);
      }
      
      function frame1() : * {
         this.privateKey = "ABCDEFGHIJKLMNOPQRSTUVXYZ";
      }
   }
}

And here's result of Kindi procesing it in RC4 mode with 96-bit key (decompiled it with online decompiler):

package test_fla {
   import flash.display.MovieClip;
   
   public dynamic class MainTimeline extends MovieClip {
      public var privateKey:String;
      
      public function MainTimeline() {
         super();
         addFrameScript(0,this.frame1);
      }
      
      function frame1() : * {
         this.privateKey = §_a_-_---§.§_a_--_--§(-1820302793);
      }
   }
}

with bunch of other .as files:
image

Here's both decompiled files for analysis:
test_decompiled.zip
test_secure_decompiled.zip

I find obfuscation of Strings most important so you can store private keys in the app for encryption and decryption of other assets. That way you can make your own encryption algorithm.

@2jfw
Copy link

2jfw commented Dec 16, 2021

Thanks for the insight!

this.privateKey = §_a_-_---§.§_a_--_--§(-1820302793); what magic is this? So there will be another occurence of it somewhere as function? Wouldn't have imagined that this works...

@ajwfrost
Copy link
Collaborator

@MalacTheLittle is it possible to get hold of that 'protected' SWF file itself? I'd be interested by the ABC instructions (rather than by the "decompiled to human-readable" output...)

Normally, a string literal would be stored into the constant pool and then retrieve by the ActionScript via a "pushstring" command and then e.g. "setproperty". So it would need to change the "pushstring" instruction to turn it into a function call, not quite sure what bytecode would make the decompiler look like that though...

Interestingly though, in the avmplus it looks like a string retrieved in this manner is kept in memory i.e. string literals are not then subject to garbage collection. Whereas for things like this, you would want to have a string that's just instantiated and then cleaned up when not in use (and see the new System.poisonStrings property) - so, this may then involve them changing the functionality so that it creates the string dynamically from some other (encrypted) memory block.

If so .. this would be simplest to do via a separate function call ... so you could have this.privateKey = Library.encryptedStrings(MY_PRIVATE_KEY_INDEX);

Interesting stuff :-)

thanks

@ajwfrost
Copy link
Collaborator

Just realised:

this.privateKey = §_a_-_---§.§_a_--_--§(-1820302793); what magic is this?

It's a function called §_a_-_---§.§_a_--_--§() with a parameter -1820302793
So, similar to a function Library.encryptedStrings() with parameter defined via an enumeration...

Rather than risk playing around with existing AS3 bytecode, it would be easier for us to provide a separate tool for you to create a block of encrypted strings, and a library to use them (or we build that decryption into the runtime, more likely.. which then gets a little more secure..)

Let us have a bit of a play with that...

@ajwfrost
Copy link
Collaborator

How about:

  1. you create a set of strings in a 'properties' file format in a utf-8 text file e.g.
MY_PRIVATE_KEY=something_here
ANOTHER_STRING=something_else
  1. we provide a tool to turn this into an encrypted blob

  2. you then embed the blob into the SWF file via the 'embed' instruction in your AS3 code

                [Embed( source = "encrypedStrings.bin", mimeType="application/octet-stream")]
                private const EncStrings:Class;
  1. you access a string via var privateKey : String = System.encryptedString(EncStrings, "MY_PRIVATE_KEY");

It may even be possible for us to do something like:

                [Embed( source = "stringsToEncrypt.txt", mimeType="text/plain", encrypted="true")]
                private const EncStrings:Class;

to skip step 2... (and actually, adding that tag to 'embed' would be useful for other types too e.g. images!....)

@dmunsie
Copy link

dmunsie commented Dec 16, 2021

This is the one I used to use. You may want to contact them and see if it's something you can work with.

https://www.ambiera.com/irrfuscator/index.html

@MalacTheLittle
Copy link

@MalacTheLittle is it possible to get hold of that 'protected' SWF file itself? I'd be interested by the ABC instructions (rather than by the "decompiled to human-readable" output...)

Sure thing, sorry I missed to attach that one too :)
test_swfs.zip

@ajwfrost
Copy link
Collaborator

Thanks ... so yes:

       6    getlocal0     	
       7    getlex        	_e_-----_ //nameIndex = 10
       9    pushint       	-1820302793	// 0x-6c7f9dc9
       11   callproperty  	_e_-_-__- (1) //nameIndex = 14
       14   coerce_s      	
       15   initproperty  	privateKey //nameIndex = 2

and later we have:

class _e_-----_ extends flash.display::Sprite
     static function _e_-_-__-(int):String	/* disp_id=6 method_id=7 nameIndex = 145 */
...

Well, I can see why decompilers wouldn't like it! But after this class has been loaded, the strings would be decrypted (from what I can make out!) so yes it's similar to what we're looking at.

@dmunsie thanks for that link, will take a look..

cheers

@Dextercitox
Copy link

Some time ago when we develop games for some brands ( games with prizes like PlayStation and things like that ) we hide the code attached in images. You take a JPG, get the bytes length of the original image, attach a swf at byte level, and break them apart when you load them, in that moment you load that swf and execute functions hidden there.

It's not very complicated and is an effective way to avoid decompilations. We also use a lot of honeypots, with typical variable names "user_total_points" and those ones are what the users modify with memory readers, then we compare that with the real points that were stored hidden in some element .x property for example and we track de "hackers" banning their accounts ...

Was a funny cat and mouse game :)

@Shaunmax
Copy link
Author

I would like to know if these obfuscation or encrypting would lead to any performance issues or not?

@MalacTheLittle Could you please share your experience with Kindi so far? Have you seen any performance issue on mobile devices? Also is Kindi still supported?

@MalacTheLittle
Copy link

@Shaunmax As you can see on image above, Kindi states that String encription entails an overhead on performance, so you need to use it carefully. When you import complex .swf to Kindi, it reads all the strings and you can choose the ones you want to encrypt. In some apps I used to encrypt up to 70 Strings and didn't feel any performance issues, though performance also depends how often you're accessing particular String according to Kindi statement. Therefore I can’t say for sure that it didn’t affect performance.
But I believe that encrypting most important Strings (10-20) shouldn't make any difference in performance. If it does, you can always think of some other approach, e.g. encrypt only chunks of Strings that run through the most of Strings, connect them in your app and use without calling encrypted variables, or you can encrypt privateKey used for decryption of outter .dat file where you keep all other Strings, etc.

@johnou
Copy link

johnou commented Oct 8, 2022

@ajwfrost super excited this has landed in 50.0.0.1. We would love to adopt this feature for our game swf, and also our asset swfs. Currently the asset swfs are served on CDN and then stored / loaded from disk (cache manager - is there anything built in nowadays? it was much easier when the browser managed it :)), ideally we would persist the encrypted swf to disk and then be able to load that when required.

@ajwfrost
Copy link
Collaborator

@johnou hope it's useful.. I think it should work fine if you have a SWF you've encryped with the SDK utility, you can load that in via Loader and it will automatically get decrypted as it's loaded. So the caveat applies: in memory, there would be an unencrypted version of everything. Plus of course this is self-contained i.e. we're not asking the user/system for a decryption key, which means this isn't as strong as your normal end-to-end encryption channels... we were wondering if it would help to have an optional key given as input to the encryption process, which means you'd also need to give the key when decrypting (but the key could then be provided by a server-side, post-authentication HTTPS service or similar...)

So this is a first step, and we can see where people want to take it, how we can make it more useful/secure/etc... As always, suggestions are welcome!

thanks

@johnou
Copy link

johnou commented Oct 11, 2022

@ajwfrost looks like https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/URLRequest.html#cacheResponse should already cache swf files using the "operating system's HTTP cache"..? (something like %temp% for Windows?) I assume encrypted swfs are also cached as encrypted swfs and decryption only happens in memory?

@ajwfrost
Copy link
Collaborator

Correct, if there is any caching going on with the SWF or the system, then this would be the encrypted file. The decryption of an entire SWF happens as it's loaded into memory within the AIR runtime.

@Ender22
Copy link

Ender22 commented Oct 31, 2022

Sorry, I'm a bit confused, saw johnou's comment about it being included in 50.0.0.1 but I don't see anything in the release notes about code obfuscation. Can anyone please briefly write what was added and how it works for anyone stumbling on this question and this thread? I'm just wondering about the basic case of how to better prevent swf decompiling

@johnou
Copy link

johnou commented Nov 1, 2022

github-494: Incorporating support for encrypted SWF formats
This is a mechanism to support SWF files where the contents of the file have been encrypted (using a
new tool that will be provided as part of the AIR SDK, ultimately this is planned to be an option for the
new ActionScript compiler as well). Note that the SWF is decrypted in memory and so it may still be
possible for users to access the decrypted SWF data if they can do a memory dump of a process.

@johnou
Copy link

johnou commented Nov 2, 2022

@ajwfrost I tried running it through swfencrypt.xml but it seems the captive runtime doesn't support encrypted SWF format? When opening the application I receive the error "Initial content could not be loaded for this application. Try re-installing or contacting the publisher for assistance."

    <target name="encrypt-swf" depends="init">
        <copy file="${target.dir}/app.swf" tofile="${target.dir}/app_unencrypted.swf"/>

        <condition property="adl.path" value="${FLEX_HOME}/bin/adl.exe">
            <os family="windows" />
        </condition>

        <!-- default -->
        <property name="adl.path" value="${FLEX_HOME}/bin/adl"/>

        <exec executable="${adl.path}" failonerror="true">
            <arg line="-nodebug" />
            <arg line="-cmd"/>
            <arg line="${FLEX_HOME}/bin/apps/swfencrypt.xml --"/>
            <arg line="-in ${target.dir}/app_unencrypted.swf"/>
            <arg line="-out ${target.dir}/app.swf"/>
        </exec>
    </target>

@ajwfrost
Copy link
Collaborator

ajwfrost commented Nov 2, 2022

Yes I'm just finding the same currently, but not sure quite what's happening (initial debugging actually looks like there's some data mismatch/corruption, as the decryption is failing).... will try to get this sorted out!

@ajwfrost
Copy link
Collaborator

ajwfrost commented Nov 4, 2022

FYI @johnou - the issue was with some handling code when dealing with chunked and compressed data, the decryption process didn't handle this properly hence failed to decipher the SWF file. Got a fix for this coming up..

@Mintonist
Copy link

What about this idea:

[Embed( source = "stringsToEncrypt.txt", mimeType="text/plain", encrypted="true")]
                private const EncStrings:Class;

adding that encrypted="true" to 'embed' would be useful for other types too e.g. images

@johnou
Copy link

johnou commented Nov 7, 2022

What about this idea:

[Embed( source = "stringsToEncrypt.txt", mimeType="text/plain", encrypted="true")]
                private const EncStrings:Class;

adding that encrypted="true" to 'embed' would be useful for other types too e.g. images

I think that's redundant, the entire SWF will be encrypted.

@ajwfrost
Copy link
Collaborator

ajwfrost commented Nov 7, 2022

Actually @Mintonist @johnou that is one of the options we're looking at ... the disadvantage of encrypting the whole swf is that you can do a memory dump (at least on Windows) and find the decrypted copy; but keeping individual elements as encrypted means that we could decrypt and return a single string from this, keeping everything else protected and the memory used for the string would be wiped as soon as you're done with it.

I think it's already supported for embedded data as byte arrays actually.. will have to check whether that's actually made it into a release!

@johnou
Copy link

johnou commented Nov 8, 2022

@ajwfrost sounds great, could this also be used on class field members which have sensitive memory to deter memory hacking?

@ajwfrost
Copy link
Collaborator

ajwfrost commented Nov 8, 2022

@johnou sorry, not sure what you mean about class field members? Normal AS3 classes/objects would always have a representation in normal memory (not the easiest representation to decipher perhaps, but I don't think we can encrypt object property values etc if that's what you mean?)

@johnou
Copy link

johnou commented Nov 14, 2022

my bad, love how the terminology changes between languages! yeah giving it further thought I don't think the encryption would be relevant for what I had in mind so ignore my previous question 👍

@StefanDubskySmeet
Copy link

Hi there, we are very interested to use the swfencrypt to protect our own game, but there seem to be no documentation so far on how to. Am I just missing the correct tag in my search or can someone provide a link or an example?
By the way: great progress so far, that this feature finally exists.

@ajwfrost
Copy link
Collaborator

Currently this is just a command-line utility (well, AIR app) that encrypts the whole of the SWF file using internal information to generate the key/IV. The file can then just be read back into AIR which will decrypt it again as it does so.

So e.g.

swfencrypt -in input.swf -out output.swf

You need to have swfencrypt on your path i.e. the AIR SDK "bin" folder, unless you're running it from there I guess.

Please note the potential down-side to this which is that the entire SWF is decrypted and stored in memory so if someone dumps the process memory, they'll likely be able to pull out your SWF.

@raresn
Copy link

raresn commented Jun 15, 2023

@ajwfrost
Will be we able to use this encrypted swf and package for iOS/Android?
Any limintations?

@ajwfrost
Copy link
Collaborator

Android should work fine. But for iOS with the ahead-of-time compilation, the AOT tool wouldn't be able to pull the ActionScript code out of the SWF if it's encrypted. If you're looking to encrypt the rest of the SWF after it's been stripped by the ADT process, I guess we would be able to add that as an option? Or any stuff that needs to be secure could be put into a bytearray perhaps, via the 'embed' command?

		[Embed(source="mydata.bin", mimeType="application/octet-stream", encrypted="true")]
		static public var MyData:Class;

then as/when you need it:

	var myData : ByteArray = System.decryptBlob(MyData);
	trace("My Data is " + myData.length + " bytes");

@raresn
Copy link

raresn commented Jun 15, 2023

Well, in order for people to use this i think A PROCESS to streamine the work needed to be done on each export/compile would be extremely helpful.
FYI, we trully apreciate the hard work you and you are team are doing! (and this is an understatement)

@evaleries
Copy link

Nice try, but this is how to decrypt the encryption.
If we could customize the key, maybe it will be more secure. Another option would be encrypt the as3 code itself just like kindi does.

@ajwfrost
Copy link
Collaborator

@evaleries thanks for pointing that out, that's a shame ..

Customising the key is fairly straightforward but it still then needs to be derived or obtained from somewhere. Securing the SWF itself, implies we need to take some data from the SWF (or the code that does this process needs to be specially obfuscated so that it's harder to reverse engineer, which is what I assume they've done to work out how to decrypt).

The alternative is to keep the key separate and then to provide this via some mechanism, for example:

  • the runtime could reach out to a server to get the key, via https.. not sure whether that would be suitably secure?!
  • the end user would have to enter a password -> bad idea I think
  • anything else...?

Potentially we could have a way for a key to be retrieved from a server when the app is first run and then stored locally, if we could do this securely (and we can't e.g. on Windows where the current user would normally be able to check all their stored credentials etc).

Another option would be encrypt the as3 code itself just like kindi does.

I think they have a few options, one of them is full swf encryption and then using a loader to decrypt it. The loader therefore must have all the logic in it to decrypt, but it's "heavily obfuscated" so maybe that's just where we went wrong with this..

The AS3 obfuscation option that Kindi has doesn't look too tricky i.e. it's just about renaming things, rather than any changes to the logic. I think it would still be better for the "loader" part (i.e. decryption) to be done in C++. We can adjust it perhaps - will check how we can obfuscate it - and we can provide ways to pass in a custom key for when encrypting embedded bits of data in AS3 files. Open to other suggestions then for how we could actually get the keys to be provided dynamically for whole-swf encryption!

thanks

@bobaoapae
Copy link

Hello, any news on that?

Maybe if the entry SWF it's fully encrypted with a random key each time and this key will need to be placed in a random and also encrypted part of the runtime AIR assembly to avoid finding this in easy way.

Then with the entry SWF being "secure" each developer can build they own logic to handle protection of the others files using something in they loaders.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests