Class: Omnizip::Filters::Bcj2

Inherits:
FilterBase
  • Object
show all
Defined in:
lib/omnizip/filters/bcj2.rb

Overview

BCJ2 filter for x86/x64 executables (4-stream variant).

BCJ2 is an advanced version of BCJ that splits x86 executable code into 4 separate streams for maximum compression:

  • Main stream: Non-convertible bytes
  • Call stream: CALL (0xE8) instruction addresses
  • Jump stream: JUMP (0xE9) instruction addresses
  • RC stream: Range coder probability data

This provides better compression than simple BCJ at the cost of increased complexity. BCJ2 requires special handling in archive formats - the 4 streams must be stored and retrieved separately.

NOTE: Currently only decoding (decompression) is implemented. Encoding is extremely complex and will be added in a future version. For compression use cases, the simpler BCJ-x86 filter is recommended.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.metadataHash

Get metadata about this filter.

Returns:

  • (Hash)

    Filter metadata



78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/omnizip/filters/bcj2.rb', line 78

def 
  {
    name: "BCJ2",
    description: "Advanced 4-stream Branch/Call/Jump converter " \
                 "for x86/x64 executables",
    architecture: "x86/x64",
    streams: 4,
    complexity: "high",
    compression_quality: "maximum",
    limitations: "Encoding not yet implemented",
  }
end

Instance Method Details

#decode(data, position = 0) ⇒ String

Decode (postprocess) BCJ2 data after decompression.

This method expects the 4 BCJ2 streams to be provided in a Bcj2StreamData object. In practice, this is called by the archive format reader (e.g., 7z reader) which handles splitting the compressed data into the 4 streams.

Parameters:

  • data (Bcj2StreamData, String)

    The 4 BCJ2 streams or error

  • position (Integer) (defaults to: 0)

    Current stream position

Returns:

  • (String)

    Decoded binary data

Raises:

  • (ArgumentError)

    If data is not a Bcj2StreamData object



62
63
64
65
66
67
68
69
70
71
72
# File 'lib/omnizip/filters/bcj2.rb', line 62

def decode(data, position = 0)
  unless data.is_a?(Bcj2StreamData)
    raise ArgumentError,
          "BCJ2 decode requires a Bcj2StreamData object with " \
          "4 streams. This is typically handled by the archive " \
          "format reader."
  end

  decoder = Bcj2Decoder.new(data, position)
  decoder.decode
end

#encode(_data, _position = 0) ⇒ String

Encode is not currently supported for BCJ2.

Parameters:

  • _data (String)

    Binary data to encode

  • _position (Integer) (defaults to: 0)

    Current stream position

Returns:

  • (String)

    Encoded binary data

Raises:

  • (NotImplementedError)

    BCJ2 encoding not yet implemented



44
45
46
47
48
49
# File 'lib/omnizip/filters/bcj2.rb', line 44

def encode(_data, _position = 0)
  raise NotImplementedError,
        "BCJ2 encoding is not yet implemented. " \
        "Use the simpler BCJ-x86 filter for compression, " \
        "or wait for a future version with BCJ2 encoding support."
end