Skip to main content
Many exploitation scenarios involve restricted bytes (badbytes) that cannot appear in your payload. Angrop provides sophisticated methods to automatically avoid badbytes in generated ROP chains.

What are Badbytes?

Badbytes are byte values that cannot appear in your exploit payload due to input filtering or processing. Common examples:
  • Null bytes (0x00) - Terminated by string functions like strcpy, scanf
  • Newlines (0x0a, 0x0d) - Terminated by line-oriented input functions
  • Whitespace (0x09, 0x20) - Filtered by input parsing
  • Control characters - Stripped or modified by terminal handlers
  • Application-specific - Custom filters in the target program
Badbytes can appear in:
  1. Gadget addresses - The address of the gadget itself
  2. Data values - Constants, strings, or pointers in the chain
  3. Intermediate values - Values created during chain execution
Angrop handles all three cases automatically.

Configuring Badbytes: set_badbytes()

Use the set_badbytes() method to specify restricted bytes before finding gadgets.

Method Signature

Parameters:
  • badbytes: List of 8-bit integers (0-255) representing restricted bytes

Basic Examples

1

Set common badbytes

2

Set multiple badbytes

3

Use character values

Always call set_badbytes() before find_gadgets(). Setting badbytes after finding gadgets will filter out incompatible gadgets but may result in fewer available gadgets than if you set them first.

Checking Configured Badbytes: get_badbytes()

Retrieve the current badbytes configuration:

How Badbyte Avoidance Works

Angrop uses multiple strategies to avoid badbytes:

1. Gadget Address Filtering

From the source code (rop.py:72-97), when gadgets are found:
Angrop maintains a database of duplicate gadgets (same instructions, different addresses) and substitutes safe addresses when available.

2. Value Construction via Arithmetic

When you need to set a register to a value containing badbytes, angrop constructs it using arithmetic operations:
From the source code (reg_setter.py:699-725), angrop tries:
  1. Concrete value gadgets - Gadgets that set registers to specific values
  2. Arithmetic chains - Using add/sub/xor/or/and to construct values
  3. Register moves - Moving from registers that can be safely set

3. Memory Write Transformations

When writing data containing badbytes to memory, angrop uses sophisticated multi-step transformations:
From the source code (mem_writer.py:213-250), angrop tries operations in order:
1

Try XOR transformation

2

Try OR transformation

3

Try AND transformation

4

Try ADD transformation

The fill_byte parameter in write_to_mem() should never be a badbyte. Angrop will raise an error if you try to use a badbyte as the fill byte.

Real-World Example: Null-Free Exploit

Common Badbyte Scenarios

Scenario 1: strcpy Vulnerability

Scenario 2: Line-Based Input

Scenario 3: URL/HTTP Input

Scenario 4: Alphanumeric Shellcode

Extremely restrictive badbyte lists (like alphanumeric-only) may make it impossible to find working gadgets. If find_gadgets() finds very few or no gadgets, you may need to reconsider your approach.

Troubleshooting Badbyte Issues

Issue 1: “Couldn’t set registers” Error

Cause: Too many badbytes make it impossible to construct required values. Solutions:

Issue 2: “Fail to write data to memory” Error

Cause: Can’t construct memory write chain without badbytes. Solutions:

Issue 3: Very Few Gadgets Found

Cause: Badbytes eliminate too many gadget addresses. Solutions:
1

Check badbyte configuration

2

Use fast_mode=False

3

Check gadget availability

Issue 4: Addresses Contain Badbytes

Cause: The binary loads at addresses containing badbytes. Solutions:

Advanced Badbyte Techniques

Technique 1: Register Arithmetic Chains

When direct register setting fails, use arithmetic:

Technique 2: Memory Staging

Write data to memory in multiple stages:

Technique 3: Gadget Equivalence

Angrop automatically finds equivalent gadgets at safe addresses:

Best Practices

  1. Set badbytes early - Always before find_gadgets()
  2. Be conservative - Only restrict truly necessary bytes
  3. Test payloads - Verify no badbytes in final chain
  4. Cache gadgets - Save and reuse gadgets for same binary+badbytes
  5. Understand constraints - Know why bytes are restricted
  6. Have fallbacks - Plan alternative exploitation if chains fail

Testing for Badbytes

Performance Impact

Badbyte restrictions affect performance:
  • Gadget finding: Slower as more gadgets are filtered
  • Chain building: May require longer chains to avoid badbytes
  • Optimization: More complex constraint solving
Performance tips:
  • Cache gadgets for reuse across exploits
  • Use optimize=True to discover alternative gadget chains
  • Start with minimal badbyte restrictions and add only as needed

Badbyte Limitations

When Badbyte Avoidance Fails

Some situations make badbyte-free chains impossible:
  1. Binary base contains badbytes - Non-PIE binary at bad address
  2. Too many badbytes - Overly restrictive filter (e.g., alphanumeric-only)
  3. Required values contain badbytes - Specific addresses or constants needed
  4. Insufficient gadgets - Not enough safe gadgets available

Alternative Approaches

When angrop can’t generate badbyte-free chains:

Next Steps