### Complete Fuzzing Target Example in Python Source: https://context7.com/jwilk/python-afl/llms.txt This Python script demonstrates a complete fuzzing target for a JSON parser, including proper initialization with `afl.init()`, error handling for `JSONDecodeError`, and optional fast exit using `os._exit()` to improve fuzzing performance. ```python #!/usr/bin/env python """ Fuzz target for a JSON parser. Usage: py-afl-fuzz -i corpus -o findings -- python json_target.py """ import os import sys import json import afl def fuzz_json_parser(data): """ Target function that parses JSON data. Returns parsed object or raises exception on invalid input. """ try: parsed = json.loads(data) # Deep validation that might trigger bugs if isinstance(parsed, dict): for key, value in parsed.items(): if not isinstance(key, str): raise TypeError(f"Invalid key type: {type(key)}") return parsed except json.JSONDecodeError as e: # Expected for invalid JSON - don't treat as crash return None except (RecursionError, MemoryError) as e: # These indicate potential DoS vulnerabilities raise def main(): data = sys.stdin.read() if not data: print("Empty input", file=sys.stderr) return 1 result = fuzz_json_parser(data) if result is not None: print(f"Valid JSON with {len(str(result))}" chars) else: print("Invalid JSON") return 0 if __name__ == '__main__': # Initialize AFL after all imports afl.init() exit_code = main() # Fast exit skips cleanup, improving fuzzing speed # Remove this if you need to test cleanup/destructor bugs os._exit(exit_code) ``` -------------------------------- ### Persistent Mode Fuzz Target Example in Python Source: https://context7.com/jwilk/python-afl/llms.txt This Python script demonstrates a persistent mode fuzz target for XML parsing, designed for maximum throughput. It uses `afl.loop(1000)` to process up to 1000 inputs per forked process and ensures `stdin` is rewound for each iteration. ```python #!/usr/bin/env python """ Persistent mode fuzz target for XML parsing. Processes up to 1000 inputs per fork for maximum speed. Usage: py-afl-fuzz -i corpus -o findings -- python xml_target.py """ import os import sys import afl # Import parser outside loop for efficiency try: from xml.etree import ElementTree as ET except ImportError: import xml.etree.ElementTree as ET def fuzz_xml(data): """Parse XML and perform basic validation.""" try: root = ET.fromstring(data) # Walk the tree to trigger potential bugs for elem in root.iter(): _ = elem.tag _ = elem.text _ = elem.attrib return True except ET.ParseError: return False if __name__ == '__main__': # Warm up: ensure all codecs/modules are loaded before loop ''.encode('UTF-8') ''.encode('UTF-8') # Persistent loop: process 1000 inputs per process while afl.loop(1000): # CRITICAL: Must rewind stdin each iteration sys.stdin.seek(0) data = sys.stdin.read() if data: fuzz_xml(data) # Clean exit after loop exhaustion os._exit(0) ``` -------------------------------- ### Initialize AFL Instrumentation in Python Source: https://github.com/jwilk/python-afl/blob/master/README.rst This snippet shows how to initialize the AFL instrumentation within a Python program. It should ideally be placed after all other module imports. This is a prerequisite for enabling fuzzing. ```python import afl afl.init() ``` -------------------------------- ### Display Coverage Map with py-afl-showmap (Bash) Source: https://context7.com/jwilk/python-afl/llms.txt Wrapper for `afl-showmap` to display the coverage map generated by running a target with a specific input. Useful for debugging and understanding code path execution. Can output to stdout or a file. ```bash # Show coverage map for a single input echo "test input" | py-afl-showmap -o /dev/stdout -- python target.py # Save coverage map to file py-afl-showmap -o coverage.txt -- python target.py < test_input.txt # Compare coverage between inputs py-afl-showmap -o map1.txt -- python target.py < input1.txt py-afl-showmap -o map2.txt -- python target.py < input2.txt diff map1.txt map2.txt ``` -------------------------------- ### Run Fuzzing with py-afl-fuzz (Bash) Source: https://context7.com/jwilk/python-afl/llms.txt Command-line wrapper for `afl-fuzz` to fuzz Python scripts. It automatically configures the fork server, signal handling, and persistent mode. Supports various options like timeout, memory limits, dumb mode, and parallel fuzzing. ```bash # Create input corpus directory with seed files mkdir -p input_corpus echo "valid input" > input_corpus/seed1.txt echo "another test" > input_corpus/seed2.txt # Create output directory for findings mkdir -p output # Basic fuzzing command py-afl-fuzz -i input_corpus -o output -- python target.py # With timeout (1000ms) and memory limit (500MB) py-afl-fuzz -i input_corpus -o output -t 1000 -m 500 -- python target.py # Dumb mode (no instrumentation feedback, faster but less effective) py-afl-fuzz -n -i input_corpus -o output -- python target.py # Parallel fuzzing with multiple instances py-afl-fuzz -M fuzzer01 -i input_corpus -o output -- python target.py & py-afl-fuzz -S fuzzer02 -i input_corpus -o output -- python target.py & py-afl-fuzz -S fuzzer03 -i input_corpus -o output -- python target.py & ``` -------------------------------- ### Initialize AFL Fork Server and Instrumentation (Python) Source: https://context7.com/jwilk/python-afl/llms.txt Initializes the AFL fork server and enables code instrumentation. This function should be called as late as possible in program initialization, before any input is read. It sets up shared memory for coverage tracking and communication with the AFL fuzzer. ```python #!/usr/bin/env python import sys import afl def process_input(): """Parse and process input from stdin.""" data = sys.stdin.read() if not data: raise ValueError("Empty input") # Your parsing/processing logic here if data.startswith("CRASH"): raise RuntimeError("Triggered crash condition") return data.upper() if __name__ == '__main__': # Initialize AFL fork server after imports, before reading input afl.init() # Process the fuzzed input result = process_input() print(result) ``` -------------------------------- ### Minimize Test Cases with py-afl-tmin Source: https://context7.com/jwilk/python-afl/llms.txt The py-afl-tmin wrapper minimizes a single test case to its smallest form that still triggers the same behavior, essential for creating minimal bug reproducer files. It supports options for exact crash mode and timeouts. ```bash # Minimize a crashing input py-afl-tmin -i crash_input.txt -o minimized.txt -- python target.py # With exact crash mode (preserves exact crash signature) py-afl-tmin -e -i crash_input.txt -o minimized.txt -- python target.py # With timeout py-afl-tmin -t 1000 -i crash_input.txt -o minimized.txt -- python target.py ``` -------------------------------- ### Configure Python AFL Behavior with Environment Variables Source: https://context7.com/jwilk/python-afl/llms.txt Python AFL's behavior, including crash handling and persistent mode, can be controlled using environment variables. Key variables include PYTHON_AFL_SIGNAL for exception-to-crash conversion and PYTHON_AFL_PERSISTENT for enabling persistent mode. ```bash # PYTHON_AFL_SIGNAL: Signal sent on unhandled exceptions (default: SIGUSR1) # Set to 0 to disable exception-to-crash conversion export PYTHON_AFL_SIGNAL=SIGUSR1 python target.py # Disable crash reporting for exceptions export PYTHON_AFL_SIGNAL=0 python target.py # PYTHON_AFL_PERSISTENT: Enable persistent mode (set automatically by py-afl-fuzz) export PYTHON_AFL_PERSISTENT=1 python target_persistent.py # PYTHON_AFL_TSTL: Ignore TSTL test harness code in coverage export PYTHON_AFL_TSTL=1 python tstl_target.py ``` -------------------------------- ### Force Exit for Faster Fuzzing in Python Source: https://github.com/jwilk/python-afl/blob/master/README.rst This code snippet demonstrates how to force an immediate exit of the Python process. It can speed up fuzzing by avoiding normal exit procedures, but may risk missing bugs that occur during a regular shutdown. Requires the 'os' module. ```python import os os._exit(0) ``` -------------------------------- ### Enable Persistent Mode for Fuzzing in Python Source: https://github.com/jwilk/python-afl/blob/master/README.rst This snippet illustrates how to enable persistent mode for fuzzing in Python using `afl.loop(N)`. This mode processes a specified number of inputs (`N`) before restarting. `afl.init()` should not be called when using persistent mode. Requires AFL version 1.82b or later. ```python while afl.loop(N): ... ``` -------------------------------- ### Rewind Stdin in Persistent Mode (Python) Source: https://github.com/jwilk/python-afl/blob/master/README.rst When reading input from `sys.stdin` in persistent mode, this code snippet shows how to rewind the stream to the beginning in each loop iteration. This ensures that the input is re-read correctly for each fuzzing cycle. Requires the 'sys' module. ```python import sys sys.stdin.seek(0) ``` -------------------------------- ### Enable Persistent Mode Fuzzing (Python) Source: https://context7.com/jwilk/python-afl/llms.txt Enables persistent mode fuzzing, processing multiple inputs within a single forked process for improved performance. The optional `max` parameter limits iterations per process. Requires AFL >= 1.82b. Remember to rewind stdin on each iteration. ```python #!/usr/bin/env python import sys import afl def parse_data(data): """Parser function to fuzz.""" if len(data) < 2: return None # Simulate parsing logic that might crash if data[0] == 'X' and data[1] == 'Y': raise ValueError("Invalid XY sequence") return data.decode('utf-8') if isinstance(data, bytes) else data if __name__ == '__main__': # Preload any modules before entering the loop ''.encode('ASCII') # Persistent mode: process up to 1000 inputs per fork while afl.loop(1000): # IMPORTANT: Rewind stdin on each iteration sys.stdin.seek(0) data = sys.stdin.read() try: result = parse_data(data) if result: print(f"Parsed: {result[:20]}...") except Exception as e: print(f"Error: {e}") ``` -------------------------------- ### Minimize Corpus with py-afl-cmin (Bash) Source: https://context7.com/jwilk/python-afl/llms.txt Wrapper for `afl-cmin` to minimize a corpus of test inputs by removing redundant files that do not contribute unique coverage. Essential for maintaining an efficient fuzzing corpus. Supports timeout and preserving filenames. ```bash # Minimize corpus directory py-afl-cmin -i large_corpus -o minimized_corpus -- python target.py # With timeout for slow targets py-afl-cmin -t 5000 -i large_corpus -o minimized_corpus -- python target.py # Preserve file names (useful for debugging) py-afl-cmin -C -i large_corpus -o minimized_corpus -- python target.py ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.