Task 186: .ERL File Format

Task 186: .ERL File Format

File Format Specifications for the .ERL File Format

The .ERL file format is primarily associated with nProtect GameGuard, an anti-cheat software used in online games. It serves as a binary error log file generated during software operation. The format is proprietary, with limited public documentation available. Known details include a specific header signature, followed by binary data containing performance metrics, error reports, and detection information. Files typically range from 1 KB to 160 KB in size, with approximately 85% starting with the bytes 00 FC CC 00.

List of All Properties of This File Format Intrinsic to Its File System

Based on available information, the key properties are as follows:

  • Magic number: A 4-byte header signature (00 FC CC 00 in hexadecimal).
  • Log data: The remaining binary content, representing variable-length log information (e.g., performance metrics, error codes, and detection details).

Two Direct Download Links for Files of Format .ERL

Public direct download links for GameGuard .ERL files are not readily available, as they are user-generated logs containing potentially sensitive information. However, for illustrative purposes, the following links provide .erl files from Erlang source code repositories (note: these are text-based and represent an alternative association with the extension; they do not match the binary GameGuard format):

Ghost Blog Embedded HTML JavaScript for Drag-and-Drop .ERL File Dump

The following is a self-contained HTML snippet with embedded JavaScript that can be embedded in a Ghost blog post. It allows users to drag and drop a .ERL file, reads it as binary, verifies the magic number, and displays the properties on the screen.

Drag and drop a .ERL file here

Python Class for Handling .ERL Files

The following Python class opens a .ERL file, decodes the properties, prints them to the console, and supports writing a new file.

import os

class ERLFile:
    def __init__(self, filepath):
        self.filepath = filepath
        self.magic = None
        self.log_data = None

    def read_and_decode(self):
        with open(self.filepath, 'rb') as f:
            self.magic = f.read(4)
            self.log_data = f.read()

    def print_properties(self):
        if self.magic == b'\x00\xfc\xcc\x00':
            print("Magic number: 00 FC CC 00")
            print(f"Log data size: {len(self.log_data)} bytes")
        else:
            print("Invalid .ERL file format.")

    def write(self, new_filepath, new_log_data=b''):
        with open(new_filepath, 'wb') as f:
            f.write(b'\x00\xfc\xcc\x00')
            f.write(new_log_data)

# Example usage:
# erl = ERLFile('example.erl')
# erl.read_and_decode()
# erl.print_properties()
# erl.write('new.erl', b'Sample log data')

Java Class for Handling .ERL Files

The following Java class opens a .ERL file, decodes the properties, prints them to the console, and supports writing a new file.

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;

public class ERLFile {
    private String filepath;
    private byte[] magic;
    private byte[] logData;

    public ERLFile(String filepath) {
        this.filepath = filepath;
    }

    public void readAndDecode() throws IOException {
        try (FileInputStream fis = new FileInputStream(filepath)) {
            magic = new byte[4];
            fis.read(magic);
            logData = fis.readAllBytes();
        }
    }

    public void printProperties() {
        if (magic != null && magic[0] == 0x00 && magic[1] == (byte)0xFC && magic[2] == (byte)0xCC && magic[3] == 0x00) {
            System.out.println("Magic number: 00 FC CC 00");
            System.out.println("Log data size: " + logData.length + " bytes");
        } else {
            System.out.println("Invalid .ERL file format.");
        }
    }

    public void write(String newFilepath, byte[] newLogData) throws IOException {
        try (FileOutputStream fos = new FileOutputStream(newFilepath)) {
            fos.write(new byte[]{0x00, (byte)0xFC, (byte)0xCC, 0x00});
            fos.write(newLogData);
        }
    }

    // Example usage:
    // public static void main(String[] args) throws IOException {
    //     ERLFile erl = new ERLFile("example.erl");
    //     erl.readAndDecode();
    //     erl.printProperties();
    //     erl.write("new.erl", "Sample log data".getBytes());
    // }
}

JavaScript Class for Handling .ERL Files

The following JavaScript class (Node.js compatible) opens a .ERL file, decodes the properties, prints them to the console, and supports writing a new file. Requires 'fs' module.

const fs = require('fs');

class ERLFile {
    constructor(filepath) {
        this.filepath = filepath;
        this.magic = null;
        this.logData = null;
    }

    readAndDecode() {
        const data = fs.readFileSync(this.filepath);
        this.magic = data.slice(0, 4);
        this.logData = data.slice(4);
    }

    printProperties() {
        if (this.magic[0] === 0x00 && this.magic[1] === 0xFC && this.magic[2] === 0xCC && this.magic[3] === 0x00) {
            console.log('Magic number: 00 FC CC 00');
            console.log(`Log data size: ${this.logData.length} bytes`);
        } else {
            console.log('Invalid .ERL file format.');
        }
    }

    write(newFilepath, newLogData = Buffer.from('')) {
        const buffer = Buffer.concat([Buffer.from([0x00, 0xFC, 0xCC, 0x00]), newLogData]);
        fs.writeFileSync(newFilepath, buffer);
    }
}

// Example usage:
// const erl = new ERLFile('example.erl');
// erl.readAndDecode();
// erl.printProperties();
// erl.write('new.erl', Buffer.from('Sample log data'));

C Class (Implemented as C++ for Class Support) for Handling .ERL Files

The following C++ class opens a .ERL file, decodes the properties, prints them to the console, and supports writing a new file.

#include <iostream>
#include <fstream>
#include <vector>

class ERLFile {
private:
    std::string filepath;
    std::vector<unsigned char> magic;
    std::vector<unsigned char> logData;

public:
    ERLFile(const std::string& fp) : filepath(fp), magic(4) {}

    void readAndDecode() {
        std::ifstream file(filepath, std::ios::binary);
        if (file) {
            file.read(reinterpret_cast<char*>(magic.data()), 4);
            logData = std::vector<unsigned char>((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
        }
    }

    void printProperties() {
        if (magic[0] == 0x00 && magic[1] == 0xFC && magic[2] == 0xCC && magic[3] == 0x00) {
            std::cout << "Magic number: 00 FC CC 00" << std::endl;
            std::cout << "Log data size: " << logData.size() << " bytes" << std::endl;
        } else {
            std::cout << "Invalid .ERL file format." << std::endl;
        }
    }

    void write(const std::string& newFilepath, const std::vector<unsigned char>& newLogData = {}) {
        std::ofstream file(newFilepath, std::ios::binary);
        if (file) {
            unsigned char header[] = {0x00, 0xFC, 0xCC, 0x00};
            file.write(reinterpret_cast<char*>(header), 4);
            file.write(reinterpret_cast<const char*>(newLogData.data()), newLogData.size());
        }
    }
};

// Example usage:
// int main() {
//     ERLFile erl("example.erl");
//     erl.readAndDecode();
//     erl.printProperties();
//     std::vector<unsigned char> sampleData = {'S', 'a', 'm', 'p', 'l', 'e'};
//     erl.write("new.erl", sampleData);
//     return 0;
// }