{% extends "base.html" %} {% block body %}

Network format

eAmuse packets are sent and received over HTTP (no S), with requests being in the body of POST requests, and replies being in the, well, reply.

The packets are typically both encrypted and compressed. The compression format used is indicated by the X-Compress header, and valid values are

Source code details
libavs-win32-ea3.dll:0x1000fa29

Encryption is performed after compression, and uses RC4. RC4 is symmetric, so decryption is performed the same as encryption. That is, packet = encrypt(compress(data)) and data = decompress(decrypt(data)).

Encryption keys

Encryption is not performed using a single static key. Instead, each request and response has its own key that is generated.

These keys are generated baesd on the X-Eamuse-Info header.

This header loosely follows the format 1-[0-9a-f]{8}-[0-9a-f]{4}. This corresponds to [version]-[serial]-[salt]. TODO: Confirm this

Our per-packet key is then generated using md5(serial | salt | KEY). Identifying KEY is left as an exercise for the reader, however should not be especially challenging. Check the page source if you're stuck.

LZ77

Packets are compressed using lzss. The compressed data structure is a repeating cycle of an 8 bit flags byte, followed by 8 values. Each value is either a single literal byte, if the corresponding bit in the preceeding flag is high, or is a two byte lookup into the window.

The lookup bytes are structured as pppppppp ppppllll where p is a 12 bit index in the window, and l is a 4 bit integer that determines how many times to repeat the value located at that index in the window.

The exact algorithm used for compression is not especially important, as long as it follows this format. One can feasibly perform no compression at all, and instead insert 0xFF every 8 bytes (starting at index 0), to indicate that all values are literals. While obviously poor for compression, this is an easy way to test without first implementing a compressor.

Prev page | Next page {% endblock %}