---
id: 10077
canonical_url: "https://phying.com/item/10077"
title: "SWF File Unpacking with esReven"
type: "research"
cve: null
cvss: null
severity: "unknown"
vendor: "Adobe"
product: "Flash Player"
affected_versions: null
source_domain: "eshard.com"
source_url: "https://www.eshard.com/blog/swf-unpacking"
published_at: "2015-04-22T00:00:00Z"
snapshot_at: "2026-10-26T05:55:00Z"
archived_by: "Phying News (https://phying.com/item/10077)"
lang: "en"
---

# SWF File Unpacking with esReven

*Author: Hugues Thiebeauld · Published: April 22, 2015 · Source: [eshard.com](https://www.eshard.com/blog/swf-unpacking)*

![PIC_1v2.png](https://cdn.prod.website-files.com/69b01787a35e34bba5ee9674/69ef09be71a8a48195fc2b40_PIC_1v2_e7c8198305.png)

*(source: wikimedia commons)*

Recently we took a look at a new flash player exploit used by the Angler exploit kit. The sample was obfuscated using the well known 'packing' technique: the dropped SWF file embeds a second stage SWF in the form of an encrypted blob that will be decrypted at runtime and then executed using the `loader.loadbytes` ActionScript API.

In order to extract the exploit code, we need to remove those multiple obfuscation layers. We could reverse engineer the ActionScript code to try and decrypt the second stage, or we could simply load the SWF file in a Flash Player instance and let it unpack the sample for us.

Let's see how we can do the latter in [esReverse / esReven](https://eshard.com/esreverse):

## Dynamic Unpacking

The idea behind dynamic unpacking is that in order to be executed, sooner or later the final stage code has to be decrypted and stored in memory. This is where esReven shines: it provides a simple way to retrieve memory chunks directly from a recorded whole-system execution trace.

Once a trace of the SWF file execution is generated, we extract a memory snapshot at the end of the trace and browse it, looking for SWF headers. According to the [SWF File Format Specification](http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/swf/pdf/swf-file-format-spec.pdf), the uncompressed SWF file header contains an `'FWS'` signature string followed by a version byte and the total file size stored in a 32-bit double-word integer:

```text
 0           4       8
 +-----------+-------+------+
 | Signature |Version| Size |
 | ('FWS')   |(1B)   | (4B) |
 +-----------+-------+------+
```

This is sufficient to find and dump all decrypted SWF files residing in the memory dump.

## Scripting esReven in Python

The first step is to choose an execution point at which the memory will contain the final decrypted stage code. While we could trace the memory allocations made by the Flash Player binary, we can keep it simple and select the last instruction of the execution trace:

```python
import reven

# Connect to the Reven server
rvn = reven.reven_connection("localhost", 13371)

# Get the last execution point of the trace
run = "Execution run"
sequence = rvn.run_get_sequence_count(run) - 1
point = reven.execution_point(run, sequence, 0)

# Get the base address of the (Windows) data segment
ds = 0x23
address = reven.logical_address(ds, 0)
```

Then, we search for the `'FWS'` signature string across the address space. For each match, we read the SWF size from the header offset (`match + 4`) and dump the decrypted buffer to disk:

```python
matches = rvn.memory_search_buffer(point, address, address + 0xffffffff, "FWS")
for match in matches:
    try:
        # Size is stored as a DWORD at offset +4
        size = rvn.memory_get_dword(point, match + 4)
        swf = rvn.memory_get_buffer(point, match, size)
    except:
        # Memory accesses may throw an exception if requested chunk is not mapped
        continue

    filename = str(match.offset) + '.swf'
    with open(filename, 'wb') as f:
        f.write(swf)
    print(f"Dumped {size} bytes to {filename}")
```

With this concise Python script, we can effortlessly extract all unpacked SWF payloads from memory, completely bypassing manual ActionScript obfuscation layers.

*(Note: Malware authors have devised countermeasures, such as allocating hundreds of decoy 'FWS' headers in memory, but in typical cases this heuristic is fast and effective.)*

## Conclusion

This walkthrough illustrates how timeless debugging and execution tracing in esReven simplifies binary extraction tasks compared to traditional dynamic debuggers.

Beyond memory searching, another precise approach is intercepting calls to the ActionScript runtime API directly (e.g. using Timo Hirvonen's [Sulo PIN tool](https://github.com/F-Secure/Sulo)).

![esReven Banner](https://cdn.prod.website-files.com/69b01787a35e34bba5ee9674/69e88acec9a177039007c122_es_Reven_Banner_f7f9c0ae88.png)

---
> 📦 **Full-Text Markdown Snapshot** archived by [Phying News](https://phying.com/item/10077) · Original source: [eshard.com](https://www.eshard.com/blog/swf-unpacking)
