secureSWF Troubleshooting Guide

NOTE: This guide is for ActionScript 3 based Flash apps.

While secureSWF tries to predict and avoid any issues that may occur after obfuscation, sometimes it may fail. However, secureSWF provides a very rich set of options which enables you to control every aspect of the obfuscation process. This guide will help you configure secureSWF to workaround any issues that may occur.

Before You Begin

In this section, you will be doing two things. First, make sure you can view error messages. Second, optionally enable debug information in your Flash app to more accurately fix issue.

View Error Messages

For web-based Flash apps (.swf files), please make sure you have the Flash Player content debugger plugin installed. You can download it from the following link: http://www.adobe.com/support/flashplayer/downloads.html

If you are using Chrome, then please check how to install the content debugger in Chrome here: http://helpx.adobe.com/flash-player/kb/flash-player-google-chrome.html#How_can_I_run_debugger_or_alternate_versions_of_Flash_Player_in_Google_Chrome

If your SWF file can run locally and inside the stand-alone version of the Flash player, then you can use the debugger version of that too.

For AIR apps, here is nifty little trick:
- In Windows, go to [Installation Folder]\META-INF\AIR and create a new folder and name it "debug".
- In OS X, go to [app name].app and view the package contents. Then browse to [app name].app/Contents/Resources/META-INF/AIR/hash and create a new folder and name it "debug".

This will show debug information when running the AIR app.

Enable Debug Information

To enable debug information in Flash Professional CS6, please follow the following steps:

  1. Go to Publish Settings.
  2. Make sure "Flash (.swf)" is selected.
  3. Expand the "Advanced" section.
  4. Check "Permit debugging".

To enable debug information in Flash Builder, just run the project using the debug launcher and use the generated SWF file for debugging in "bin-debug" folder instead of the release file.

Figuring out what causes the issue

There are three steps to this. First, make sure the issue is not caused by secureSWF itself. Second, check that Code Protection is working and fix any issues caused by it. Third, check that Identifiers Renaming is working and fix any issues caused by it.

Step 1: Turn off everything.

Turn off everything and make sure that the issue is not caused by a bug in secureSWF's ability to read and write SWF files. Follow these steps:

  1. Remove your files from secureSWF and start over.
  2. Add your files again.
  3. Select "Testing" from the Protection Preset drop menu.
  4. Protect the files and test the result.

While it is very unlikely, but if the generated files after these steps do not behave exactly the same as the original ones, then please contact our support team. We give these issues the highest priority and will probably provide a fix in a few days. To help even make things go faster, please provide a sample SWF file. Anything you send to the support team is strictly confidential.

Step 2: Turn on Code Protection settings

There are four main options in Code Protection Settings under the Protection tab in secureSWF. Each one of them makes changes to the compiled ActionScript to prevent decompilation. You can think of the options as protection layers. Each option works independently from the others and provides protection on its own.

Start by enabling Control Flow Obfuscation. It is the most effective option against decompilers. For testing purposes, you need to set the intensity to 100%. When set under 100%, secureSWF will randomly pick locations to manipulate. If there was an issue caused by Control Flow Obfuscation, it will randomly appear. Therefore, use 100% intensity to avoid random results. Please follow the following steps:

  1. Enable Control Flow Obfuscation by checking the checkbox.
  2. Set intensity to 100% by dragging the ticker to the right until the end.
  3. Click "Protect" in the toolbar and test the result.

If you get an error message at this point, please move to the Fixing Code Protection Issue section.

Now that we know the issue was not caused by Control Flow Obfuscation, enable Dynamic Code Wrapping. It is the second most effective method against decompiling. Please follow the following steps:

  1. Enable Dynamic Code Wrapping by checking the checkbox.
  2. Set the level to Medium or to the level you will eventually be using.
  3. Click "Protect" in the toolbar and test the result.

If you get an error message at this point, please move to the Fixing Code Protection Issue section.

Now you should have Control Flow Obfuscation and Dynamic Code Wrapping working for you. You can set Control Flow Obfuscation intensity back to the level you want (20% is the recommended). You can also repeat what we have done above with Statement-level Randomization and Integer Data Obfuscation.

Step 3: Turn on Identifiers Renaming

At this point, you should be sure of two things:

  1. secureSWF can read and write your SWF files without issues.
  2. Code Protection methods in the Protection tab work.

Please follow the following steps:

  1. Remove your files from secureSWF and start over.
  2. Add your files again.
  3. Select "Testing" from the Protection Preset drop menu.
  4. Go to the Renaming tab and check "Enable Identifiers Renaming" at the top.
  5. Click the Protect button in the toolbar and test the result.

Note: Remember to alway test the protected SWF files in the Flash player content debugger plugin or stand-alone. Before you begin section of this guide has the details. It will also help a lot if you have debug information included in the Flash app.

If you get an error message after protecting with these settings, then please move to the following section, Fixing Identifiers Renaming Issues

If your Flash app worked perfectly after protecting it with the above settings, then you can enable code protection features. With Identifiers Renaming and Code Protection enabled, you Flash app is fully protected against decompilers. You can now enable other settings if you need to. Start with the options that are important to you. Protect and test your app after each change.

Fixing Identifiers Renaming Issues

While secureSWF should be able to safely rename identifiers and automatically avoid renaming problematic ones, when it fails, there is an easy way to workaround that.

First step of fixing identifiers renaming issue is translating the error message using the Stack Trace Translator

In secureSWF GUI, go to Tools > Stack Trace Translator in the main menu. Select the mapping table file. This is the json file secureSWF generates every time you process a file with identifiers renaming turned on. If you have not set one yourself, then you can find it next to the protected file with a "_map" postfix and a .json extension. This file contains a map between obfuscated names and the original names of all the renamed identifiers.

After selecting the mapping table, just copy and paste the error message from the Flash player into the Original Call Stack Trace text area. The translated error message will automatically appear in the text area below it.

Common Error Messages:

1053: Illegal override of %n in %t

Example:

VerifyError: Error #1053: Illegal override of methodName in com.kindi.TestClass

This error occurs when secureSWF renames a method in a child class which overrides a method in the base class without renaming the method in the base class.

To fix this issue, you need to exclude the method from renaming. The easiest way of doing that is by adding a configuration rule as follows:

  1. Go to the Configuration Tab in secureSWF
  2. In the pattern field enter: ::/methodName
  3. Right click anywhere in the Rule Editor section and select "Disable all renaming options" from the context menu.
  4. Click Add and a new rule should appear in the Configuration Rules section.

What we did above is configure secureSWF to exclude all class members which name matches methodName. While this will solve the issue, you don't have to exclude all class members with that name. You can pinpoint the exact method that is causing the problem by changing the pattern of the rule to packageName::ClassName/methodName. In the above example, it should become com.kindi::TestClass/methodName.

1014: Class %n could not be found.

Example:

VerifyError: Error #1014: com.kindi::TestClass can not be found

This error occurs when secureSWF tries to rename a class but either misses renaming the class definition or one of the references.

To fix this issue, you need to exclude the class TestClass from renaming. The easiest way of doing that is by adding a configuration rule as follows:

  1. Go to the Configuration Tab in secureSWF
  2. In the pattern field enter: com.kindi::TestClass
  3. Right click anywhere in the Rule Editor section and select "Disable all renaming options" from the context menu.
  4. Click Add and a new rule should appear in the Configuration Rules section.

What we did above is configure secureSWF to exclude the class TextClass in the package com.kindi. This should solve the issue.

1065: Variable %n is not defined

Example:

ReferenceError: Error #1065: Variable xyz is not defined

This error occurs when secureSWF tries to rename a variable but fails to rename all its references.

To fix this issue, you need to exclude the variable xyz from renaming. The easiest way of doing that is by adding a configuration rule as follows:

  1. Go to the Configuration Tab in secureSWF
  2. In the pattern field enter: ::/xyz
  3. Right click anywhere in the Rule Editor section and select "Disable all renaming options" from the context menu.
  4. Click Add and a new rule should appear in the Configuration Rules section.

What we did above is configure secureSWF to exclude all class members which match the name xyz in all packages and classes. This should solve the issue. However, if you know where xyz is, then change the pattern to package::Class/xyz to avoid excluding additional identifiers from renaming.

1056: Cannot create property %n on %t

Example:

ReferenceError: Error #1056: Cannot create property [property] on [Type]

ReferenceError: Error #1056: Cannot create property txtInput on package.name.DocumentClass

This error occurs when secureSWF tries to rename a class member but fails to rename all its references.

To fix this issue, you need to exclude the property txtInput from renaming. The easiest way of doing that is by adding a configuration rule as follows:

  1. Go to the Configuration Tab in secureSWF
  2. In the pattern field enter: package.name::DocumentClass/txtInput
  3. Right click anywhere in the Rule Editor section and select "Disable all renaming options" from the context menu.
  4. Click Add and a new rule should appear in the Configuration Rules section.

What we did above is configure secureSWF to the class member txtInput in package.name.DocumentClass. This should solve the issue. 

1009: null has no properties

1010: A term is undefined and has no properties.

Errors 1009 and 1010 can be treated in the same way.

Examples:

TypeError: Error #1009: Cannot access a property or method of a null object reference.

TypeError: Error #1010: A term is undefined and has no properties.

Unfortunately, these error message from the Flash player do not provide details to pinpoint the identifier causing the issue. However, from the call stack trace that appears after the error message, we can at least know at which part of the code it is occurring. Consider the following example:

TypeError: Error #1009: Cannot access a property or method of a null object reference.

    at com.kindi::TestClass/foo()[TestClass::frame1:5]

    at com.kindi::TestClass/bar()[TestClass::frame1:8]

    at com.kindi::TestClass/frame1()[TestClass::frame1:10]

The above shows that the type error is occurring at the method foo in the class TestClass in the package com.kindi. We can also tell that the error occurred at line 5 in ActionScript at frame 1. If you are using Flash Builder, you will get the ActionScript file path instead of "TestClass::frame1". If you cannot see which line number is occurring at, then it's because you have not enabled debugging in your SWF file. Please check Before You Begin section of this guide.

All what you can do now is start a trail-and-error process to figure out which identifier causes an issue when renamed. We recommend using the Identifier Browser in secureSWF Renaming tab for that. Exclude identifiers by making sure the checkbox next to their name is unchecked. After each change, process the file and test it. If the error no longer occurs, then you have found the identifier causing it.

Once you have figured out which identifier is causing the issue, we recommend to exclude it from renaming by adding a configuration rule. It is easier to maintain configuration rules than directing manipulating settings. To add a configuration rule which excludes the variable foobar in the class TestClass in the package com.kindi, please follow the following steps:

  1. Go to the Configuration Tab in secureSWF
  2. In the pattern field enter: com.kindi::TestClass/foobar
  3. Right click anywhere in the Rule Editor section and select "Disable all renaming options" from the context menu.
  4. Click Add and a new rule should appear in the Configuration Rules section.

Fixing Code Protection Issues

The common errors caused by Code Protection are:

  • 1017: Scope stack overflow occurred.
  • 1018: Scope stack underflow occurred.
  • 1020: Code cannot fall off the end of a method.
  • 1030: Stack depth is unbalanced. _ != _.
  • 1068: _ and _ cannot be reconciled.

If the error message you are receiving is not among the above list, give the following steps a try anyway and feel free to contact us if you need further help.

If you followed the steps in this guide, you should have only Code Protection enabled. Therefore, the error message you have received from the Flash player should not require translation.

Regardless of the error message and type, the second line contains the name of the method which at the error is occurring. For example:

VerifyError: Error #1030: Stack depth is unbalanced. 2 != 0.

    at com.kindi::TestClass/foo()[TestClass::frame1:9]

    at com.kindi::TestClass/bar()[TestClass::frame1:23]

    at com.kindi::TestClass/frame1()[TestClass::frame1:62]

This is all you need to fix the issue. In the above example, we just need to remove code protection from the method foo in the class TestClass in the package com.kindi. To do that, add a rule in the Configuration tab in secureSWF. Here is how to do that:

  1. Go to the Configuration tab in secureSWF
  2. In the pattern field enter: com.kindi::TestClass/foo
  3. Right click anywhere in the Rule Editor section and select "Disable all protection options" from the context menu.
  4. Click Add and a new rule should appear in the Configuration Rules section.

This should fix the issue. If it does not, please let us know.