Understanding: "Amayeta SWF Encrypt"
A brief guide to how amayeta obfuscation works
Understanding: Posted on: 04/26/2012 7:16am
Quote Post
Never let a computer tell me shit.
I found some info lying around and thought it was worth sharing, as the question has been raised more than once.


"Amayeta SWF Encrypt", uses a protection method which involves nothing more than hiding.

The Primary Method
First, the original bytecode is moved into a new record (type=253), and a new record is created with the type and header of the original bytecode (12 or 59, which are DoAction and DoInitAction respectively). Because the type 253 doesn't correspond to an existing type, decompilers ignore it.

Next, the original bytecode has nine bytes appended, which consist of two jumps:
  • The first leads to another jump inside the obfuscator's body
  • The second jumps to the OEP.
The target of the first jump is an END/HLT instruction, which is overwritten by the first of the jumps at the terminus of the original code. Following the type 253 record is the obfuscator body proper, consisting of a finite-state-machine of length approximately 100 states; the accepting state of this FSM involves jumping to the second of the jumps described above (which then further jumps to the OEP, allowing the execution of the original bytecode.)

In addition, amayeta adds a record of type 255 before the first 253 record; this "signature" record has consisted of a single byte of data, 0x20, in all of the protected SWFs the author has examined. ?


Ancillary Methods
A second obfuscation trick just places the code to be hidden in an instruction with an invalid opcode (0xFC). This instruction is then placed inside of the junk code.

A bit of junk code followed by the old jump-into-middle-of-instruction trick to confuse decompilers. Simply removing this code (first 0x2A bytes) fixes it.


Unprotect Method -=Click To Show=-
The method of the unprotector is to convert a 253 record followed by a type 12 or 59 record into the corresponding 12 or 59 record, renumbering the original obfuscator's record to type 254. The type 59, DoInitAction record, contains an additional 16-bit word following its header to identify the sprite to which it refers; this word is copied to the type 253 record after the data is moved two bytes forward to accomodate. The ten bytes (or eight, in the case of fixed 59 records) where the jumps were located are filled with zeros to both terminate the ActionScript bytecode and clear the end of the record to avoid confusing a disassembler, without having to hassle with the resizing of records (which is the same reason for merely renaming instead of removing the inserted blocks of the obfuscator.)

General working procedure:
  • iterate over tags
    • when we encounter a tag containing code:
      • if it contains special meta information (e.g. DefineButton2), copy it over
      • make sure the code starts with 9B 07 00 01 02 00 00 00
      • scan the tag for a constants definition where the constant names only have readable names. if found, copy it over
      • follow the backward branch at the end of the 253 tag preceding the tag to get to the actual code
  • if the tag code on the other hand starts with:

? ? ? ? ? 96 03 00 00 09 00 96 05 00 07 02 00 00 00 3C 96
? ? ? ? ? 03 00 00 09 00 88 09 00 03 00 20 00 01 01 00 02
? ? ? ? ? 00 1C 9D 02 00 03 00


? ? ? it's the splice jump trick. just drop the first 0x2A bytes from the code.
? ? ? this code contains a constants declaration with some junk entries. one might think
? ? ? that the "real" constants declaration will be appended to this, and that therefore
? ? ? the constants references in the code need to be adjusted when the junk constants
? ? ? are dropped. luckily, a constants declaration *replaces* any previous ones, so there's
? ? ? no problem.



? ? ? tags that contain code are:
  • 12: DoAction? ? ? ? ? ? ? ? ? ? ? ? -> contains just raw code
  • 26: PlaceObject2? ? ? ? -> skip a whole lot of structures that may or may not be there depending on flags
  • 34: DefineButton2? ? ? -> cond blocks start at tag_data + 3 + word ptr [tag_data+3].
  • 39: DefineSprite? ? ? ? ? ? -> skip four bytes and read tags until End tag is encountered
  • 59: DoInitAction? ? ? ? ? ? -> skip first two bytes (sprite ID)
  • 253: move the code over to the code tag that follows and drop this one


? ? ? may contain code but are apparently not used:
  • too old:
    • 7:? DefineButton
  • too new:
    • 70: PlaceObject3
    • 72: DoABC
    • 82: DoABCDefine


? ? ? When there are multiple code blocks in one tag (for example multiple conditions on DefineButton2),
? ? ? the code is arranged as follows in the 253 tag:

? enter2_cond1:
? ? ? <code cond1>
? ? ? jmp ret1_cond1
? enter1_cond1:
? ? ? jmp enter2_cond1

? enter_cond2:
? ? ? <code cond2>
? ? ? jmp ret_cond2? ? ? ? ? ? ? ? ? -> return to junk code
? ? ? jmp enter_cond2? ? ? ? ? <- junk code jumps here
? ret1_cond1:
? ? ? jmp ret2_cond1? ? ? ? ? ? ? ? -> return to junk code ? ? ?
? ? ? jmp enter1_cond1? ? ? ? <- junk code jumps here



I use this AoB tool to make all the AoBs I post. Try the online version if you dont feel like downloading it.
"Obviously, windows are central to Windows. They are so important that they named the operating system after them. But what is a window?"