Join also our Discord channel! Click here.

Boukyaku Princess

Read or post about compression. And decompression. Or ask questions how to decompress your files.
Post Reply
finale00
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 2382
Joined: Sat Apr 09, 2011 1:22 am
Has thanked: 170 times
Been thanked: 297 times

Boukyaku Princess

Post by finale00 » Mon Feb 03, 2014 3:25 am

Here's a flash-based online game.
It sends 60 MB worth of data to your machine, half of which are the game's resources.

The resources are stored in a proprietary archive, with the file table at the top, followed by the file data.
The table is compressed using deflate algo, and is straightforward once you decompress it.

The files are encrypted using a custom algorithm.
I found the algorithm in one of the SWF files, but I'm unable to get it working properly myself.

This is the basic algorithm

Code: Select all

1. Given a filename (or path)
2. Generate the key
3. Use the key to decrypt the data (using simple XOR)
The names you find in the file table are MD5-hashed versions of the original name, and mean nothing for the most part when it comes to decryption. It is only used by the program to grab the appropriate entry and return the data. What you need is the original name to feed to the key generator function.

The name of file is what you need to use as the key material. You can verify that MD5 hashing the name will give you the entry in the archive.

These are the functions that you will be using (I just took them from the source).

Code: Select all

private static function HashKey(param1:String) : uint
{
    var _loc_3:int = 0;
    var _loc_2:uint = 1234567;
    _loc_3 = 0;
    while (_loc_3 < param1.length)
    {
        
        _loc_2 = (param1.charCodeAt(_loc_3) + _loc_2) * 251;
        _loc_3 = _loc_3 + 1;
    }
    return _loc_2;
}// end function

private static function Decrypt(param1:ByteArray, param2:uint) : void
{
    var _loc_3:int = 0;
    _loc_3 = 0;
    while (_loc_3 < param1.length)
    {
        
        param1[_loc_3] = param1[_loc_3] ^ param2 & 255;
        param2 = param2 * 977 + 1;
        _loc_3 = _loc_3 + 1;
    }
    return;
}// end function

I've included my own implementation of an exporter with the package, but I don't think it works (or at least, the output I'm getting is junk). It's written in Ruby.

Here are some files: http://www.mediafire.com/download/xwnr3 ... incess.zip

When you are testing your code, use "1.swf" as the input filename.

Ekey
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 1650
Joined: Wed Mar 31, 2010 6:54 am
Has thanked: 68 times
Been thanked: 832 times

Re: Boukyaku Princess

Post by Ekey » Tue Feb 04, 2014 12:02 pm

Done. Here my crappy code. Copy files in tool folder.

Code: Select all

[Usage]
        BPTest <pFileIn> <pFileOut>

[Example]
        BPTest 1.swf 1_dec.swf
Source code included. Enjoy :)
You do not have the required permissions to view the files attached to this post.

finale00
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 2382
Joined: Sat Apr 09, 2011 1:22 am
Has thanked: 170 times
Been thanked: 297 times

Re: Boukyaku Princess

Post by finale00 » Wed Feb 05, 2014 5:27 am

Hmm I wonder where I went wrong with the algorithm :(
It's really straightforward too.

Ekey
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 1650
Joined: Wed Mar 31, 2010 6:54 am
Has thanked: 68 times
Been thanked: 832 times

Re: Boukyaku Princess

Post by Ekey » Wed Feb 05, 2014 10:47 am

finale00 wrote:Hmm I wonder where I went wrong with the algorithm :(
It's really straightforward too.
Well encrypted SWF's have header

Code: Select all

struct ENCSWFHeader
{
 	DWORD pCRC; // ???
 	DWORD pFlag; // ???
 	DWORD pDataOffset; // Offset with encrypted SWF data ( + 0xC < header size )
}

Post Reply