Skip to content

Latest commit

 

History

History
115 lines (83 loc) · 8.87 KB

GENERATION.md

File metadata and controls

115 lines (83 loc) · 8.87 KB

Generating Videos with H26Forge

To generate a video with the default configurations, you can run: ./h26forge generate -o vid.264

This will use the default syntax element ranges found in src/vidgen/generate_configurations.rs. You can also get these by adding --save-default-config to the instruction, which will create a default.json file in the current directory: ./h26forge --save-default-config

Recommended video generation command: ./h26forge --mp4 --mp4-frag --mp4-rand-size generate -o vid.264 --small --ignore-ipcm --ignore-edge-intra-pred. This command will quickly generate small MP4 and H.264 bitstream files. See below for what each flag does.

WARNING Because we are generating semantically non-compliant videos, they may not decode correctly, even in H26Forge.

Custom Ranges

You can modify the ranges that each syntax element takes on, but in many cases you are bounded by the type of entropy encoding that is used.

Here is a table of the types of entropy encoding found in H.264 videos, along with the usual ranges.

Function Range Meaning
ae(v): Depends on binarization Context Adaptive Binary Arithmetic Coded (CABAC)
ce(v): Depends on binarization Context Adaptive Variable-Length Coded (CAVLC)
f(n): $[0, 2^n]$ Fixed-pattern bit string using n bits written
i(n): $[-2^{n-1}, 2^{n-1} -1 ]$ Signed integer using n bits
me(v): Depends on binarization Mapped Exp-Golomb-coded syntax element with the left bit first
se(v): Often $[-2^{31}, 2^{31}-1]$ Signed integer Exp-Golomb-coded syntax element with the left bit first
te(v): Depends on binarization Truncated Exp-Golomb-coded syntax element with the left bit first
u(n): Often $[0, 2^{n}-1]$ Unsigned integer using n bits. If "v" is used, then the number of bits varies depending on the value of other syntax elements
ue(v): Often $[0, 2^{32}-1]$ Unsigned integer Exp-Golomb-coded syntax element with the left bit first

For the most effective testing of H.264 decoders, create a custom configuration for your target by putting in the bounds from the target. Note that bounds may also depend on the type used to store the recovered syntax element.

Ranges in a config file are inclusive, so an upper bound on an $n$-bit number should be set to $2^n-1$.

Example Custom Range

The file config/chrome.json has its bounds set based on ranges found in the Chromium H.264 parser source code. This increases the likelihood that videos generated by H26Forge will explore undefined states in the decoder.

Exact values

You can get exact values in the generated videos by setting min and max to the same value. For example, to generate videos with out-of-bounds cpb_cnt_minus1, both can be set to 255:

"cpb_cnt_minus1": {
    "min": 255,
    "max": 255
},

Limitations

H26Forge does not yet have complete support for H.264 spec, so certain syntax element values are not chosen. For example, H26Forge does not generate videos with nal_unit_type equal to 21, a "Coded slice extension for a depth view component or a 3D-AVC texture view" because it does not have support for 3D-AVC slices.

Repeatable Random Videos

To produce the same video, you can set the --seed <SEED> flag to whatever value: ./h26forge generate -o vid.264 --seed 1337

Note that the seed value is also output while a video is being generated:

$ ./h26forge generate -o vid.264 --seed 1337
Generating a new video
         using default random value ranges
1. Generating random video
         seed value: 1337
         random_video - NALU 0 - Generating Sequence Parameter Set
                 SPS seq_parameter_set_id: 1
                 profile_idc: 128
                 level_idc: 41
...

Fuzzing Integration Layer for Mutation (FILM) Interface

The Fuzzing Integration Layer for Mutation (FILM) interface is an attempt to integrate H26Forge with mutation-based fuzzers. It uses the parametric generator idea from Zest [Padhye19]. Basically a FILM file is treated as a source of randomness, where syntax elements are read as binary encoded values that are capped by the maximum set in the configuration. This approach has not been evaluated.

There are two components to the FILM interface: (1) outputting FILM; (2) reading FILM.

Film is output by adding the --output-film flag while generating a video. Each randomly sampled value will be saved as a binary value whose bit-length is based on its maximum possible value. For example, the command ./h26forge generate -o vid.264 --seed 1337 --output-film will generate a file called vid.264.film_file.seed_1337.bin. Note that the random seed is also included in the filename.

FILM is read by passing in the --film <FILMFILE> parameter to H26Forge: ./h26forge generate -o vid2.264 --film vid.264.film_file.seed_1337.bin. Every time that H26Forge samples a random value, it will read from the provided FILM file. If the FILM runs out, then H26Forge will fallback to a passed --seed value or a fresh randomly sampled seed.

A mutation-based fuzzer could perform mutation-based fuzzing to the FILM file, which H26Forge could use to generate a syntactically-correct H.264 file.

Bibliography

Rohan Padhye, Caroline Lemieux, Koushik Sen, Mike Papadakis, and Yves Le Traon. 2019. Semantic Fuzzing with Zest. In Proceedings of the 28th ACM SIGSOFT International Symposium on Software Testing and Analysis (ISSTA’19), July 15–19, 2019, Beijing, China. ACM, New York, NY, USA, 12 pages. https://doi.org/10.1145/3293882.3330576

Options

Here are all the options available for video generation.

Output Options

  • --safestart: Prepend a known safe video to the output.
  • --mp4: Output an MP4 file. If safestart is enabled, it will also output an MP4 of the prepended video.
  • --mp4-frag: Makes the output MP4 into a fragmented MP4 file. This means that instead of the encoded bitstream existing as one big chunk in the MP4, each NALU will be separate, also containing its own AVCC. This is sometimes required for playing videos on the web.
  • --mp4-rand-size: Samples random values to set the output MP4 width and height. The range can be changed in the config file.
  • --mp4-width <width>: Set the output MP4 width to a particular value.
  • --mp4-height <height>: Set the output MP4 height to a particular value.
  • --avcc: Produce a WebCodecs friendly output file. This creates a <output>.avcc.js file that contains the AVCC extradata in this format. The variable avcC can be passed into a VideoDecoderConfig. See CanIUse to identify support.
  • --rtp-replay: Output an rtpdump file. If safestart is enabled, decodable frames will be prepended to the rtpdump file. The config file for the generated dump is rtp_config/replay.config
  • --json: Outputs the entire generated/parsed video as a H264DecodedStream. Note that this file can get really big.
  • -e: Outputs the generated entropy encoded values in a human readable format. This slows down video encoding, and may produce a really large file. This is best used for identifying what particular syntax element values are causing issues.

Randomness Options

  • --seed <seed>: The random seed value used to generate a video.
  • --film <file>: The file to use to sample from.
  • --output-film: The randomly sampled values encoded in binary.

Generated Video Options

  • --small: Keeps the frame size to at most 128x128 pixels. This allows for faster video generation, but if testing a decoder for potential vulnerabilities, some effects from larger frame sizes may be missed.
  • --empty-slice-data: Sets the slice data coded_block_pattern to 0, meaning there will be no residue information in slices. This allows for faster generation, but it may miss issues only found in hardware decoding.
  • --ignore-intra-pred: Generate videos that do not rely on Intra prediction. All I slices have macroblock type INxN. This is to focus on issues that may arise from Inter prediction.
  • --ignore-edge-intra-pred: Limits the Luma/Chroma Thief effect from being generated.
  • --ignore-ipcm: Does not produce losslessly encoded PCM macroblock types.
  • --include-undefined-nalus: Will generate random bytes for NALUs that are not defined in the spec.