npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

brawlhalla-swz

v1.0.1

Published

An SWZ decryption library for the game Brawlhalla

Downloads

8

Readme

brawlhalla-swz

Version Downloads License

brawlhalla-swz is a module for parsing and decrypting SWZ files for the game Brawlhalla.

Installation

You can install brawlhalla-swz through the command line using npm or yarn.

npm install brawlhalla-swz

Usage

import { KeyReader, SWZReader, SWZWriter } from "brawlhalla-swz";

// or

import * as BrawlhallaSWZ from "brawlhalla-swz";

Documentation

KeyReader

The KeyReader class is used for finding the SWZ decryption key from BrawlhallaAir.swf

new KeyReader(buffer: Buffer): KeyReader

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);

findDecryptionKey(): number | false

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

SWZReader

The main object for reading SWZ files.

new SWZReader(buffer: Buffer, decryptionKey: number)

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);

readHeader(): boolean

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

bruteforceHeader(patch: number): number

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

readData(): Buffer | false

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);

SWZWriter

The main object for writing SWZ files.

new SWZWriter(decryptionKey: number)

Constructor for SWZ Writer, taking in the SWZ decryption key.

import { SWZWriter } from "brawlhalla-swz";

const writer = new SWZWriter(492627010);

writeHeader(seed?: number): void

Write the SWZ header to internal buffer.
Seed is a fixed value of 731341442 if not provided.
(Value sampled from previous version of brawlhalla)

import { SWZWriter } from "brawlhalla-swz";

const writer = new SWZWriter(492627010);

writer.writeHeader(123456789);

writeData(data: Buffer, forceChecksum?: number): void

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>"));

getBuffer(): Buffer

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());

The SWZ File Format

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.

How are we able to bruteforce the key?

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.

Contributing

Interested in contributing to brawlhalla-swz?

Contributions are welcome, and are accepted via pull requests. Please review these guidelines before submitting any pull requests.

Help

Installing dependencies:

npm install

Compile:

npm run build

License

All code in this repository is licensed under MIT.