brawlhalla-swz is a module for parsing and decrypting SWZ files for the game Brawlhalla.
You can install brawlhalla-swz through the command line using npm
or yarn
.
npm install brawlhalla-swz
import { KeyReader, SWZReader, SWZWriter } from "brawlhalla-swz";
// or
import * as BrawlhallaSWZ from "brawlhalla-swz";
The KeyReader class is used for finding the SWZ decryption key from BrawlhallaAir.swf
Construct a new KeyReader object from the swf data
buffer
import { readFileSync } from "fs";
import { KeyReader } from "brawlhalla-swz";
const swf = readFileSync(`/Path/To/Brawlhalla/BrawlhallaAir.swf`);
const keyReader = new KeyReader(swf);
This method is for scanning the SWF file for the decryption key.
Returns false if the key cannot be found.
import { KeyReader } from "brawlhalla-swz";
const keyReader = new KeyReader(swfData);
const decryptionKey = keyReader.findDecryptionKey();
> 492627010
The main object for reading SWZ files.
Constructor for SWZ Reader, taking in the SWF data as a buffer and the SWZ decryption key.
Use -1 if you are planning on bruteforcing the key.
import { readFileSync } from "fs";
import { SWZReader } from "brawlhalla-swz";
const swf = readFileSync(`/Path/To/Brawlhalla/BrawlhallaAir.swf`);
const reader = new SWZReader(swf, 492627010);
Attempt to parse the header of the SWZ File.
Returns whether the checksum passed, general indicator as to whether the decryption key is correct.
import { readFileSync } from "fs";
import { SWZReader } from "brawlhalla-swz";
const swf = readFileSync(`/Path/To/Brawlhalla/BrawlhallaAir.swf`);
const reader = new SWZReader(swf, 492627010);
const success = reader.readHeader();
if (!success)
throw new Error("Invalid decryption key");
> true
Attempt to bruteforce the decryption key with the patch number.
The patch number should be a 4 digit number.
e.g. patch 7.01 would be 7010, patch 6.08 would be 6080.
Returns either the decryption key or -1.
The internal decryption key is set when the key is found, so you can read data as normal afterwards.
import { readFileSync } from "fs";
import { SWZReader } from "brawlhalla-swz";
const swf = readFileSync(`/Path/To/Brawlhalla/BrawlhallaAir.swf`);
const reader = new SWZReader(swf, -1);
const key = reader.bruteforceHeader(7010);
if (key == -1)
throw new Error("Failed to bruteforce decryption key");
// read file here
> 492627010
Read a section of data, false if no data left.
Prerequisite is to have parsed the file header.
import { readFileSync } from "fs";
import { SWZReader } from "brawlhalla-swz";
const swf = readFileSync(`/Path/To/Brawlhalla/BrawlhallaAir.swf`);
const reader = new SWZReader(swf, -1);
const key = reader.bruteforceHeader(7010);
if (key == -1) throw new Error("Failed to bruteforce decryption key");
let data;
do {
data = swf.readData();
console.log(data);
} while (!!data);
The main object for writing SWZ files.
Constructor for SWZ Writer, taking in the SWZ decryption key.
import { SWZWriter } from "brawlhalla-swz";
const writer = new SWZWriter(492627010);
Write the SWZ header to internal buffer.
Seed is a fixed value of731341442
if not provided.
(Value sampled from previous version of brawlhalla)
import { SWZWriter } from "brawlhalla-swz";
const writer = new SWZWriter(492627010);
writer.writeHeader(123456789);
Write a data section to the internal buffer, encrypts the data for you.
Forcechecksum allows you to force a specific value for the checksum.
Has the potential to hide data from the game, rarely used.
import { SWZWriter } from "brawlhalla-swz";
const writer = new SWZWriter(492627010);
writer.writeHeader(123456789);
writer.writeData(Buffer.from("<swz file>"));
Retrieve the data buffer from the writer.
Commonly used to export data to a file.
import { SWZWriter } from "brawlhalla-swz";
import { writeFileSync } from "fs";
const writer = new SWZWriter(492627010);
writer.writeHeader(123456789);
writer.writeData(Buffer.from("<swz file>"));
writeFileSync("example.swz", writer.getBuffer());
After this library was created the file format was publicly reversed on the xentax forum.
The SWZ file format is based upon an XOR cipher using a WELL512 pseudorandom number generator. See src/prng.ts
for an implementation.
The header is a checksum to ensure the correct key is being used on the correct file.
See the readHeader
method in SWZReader for more details.
The SWZ file almost acts like an archive, each file is its own data section, read with SWZReader's readData
method.
The first line of each data section is the filename for CSV files.
The filename is the name of the first tag in XML files.
The key for each file isn't truly random. The last 4 digits of every key is the patch which the key is for.
For example the key for the 7.01 tech-test branch is 492627010
We are yet to find what the other digits represent, they are most likely just random.
However, this discovery reduces the search space enough for it to be easily bruteforced. This is implemented in SWZReader's bruteforceHeader
method. If you know the patch you can bruteforce the key.
Interested in contributing to brawlhalla-swz?
Contributions are welcome, and are accepted via pull requests. Please review these guidelines before submitting any pull requests.
Installing dependencies:
npm install
Compile:
npm run build
All code in this repository is licensed under MIT.