Skip to content
Back to skills

2538 Symbolic Execution 64987aba

ASecurity

Symbolic execution explores program paths using symbolic values instead of concrete inputs, enabling systematic discovery of behavioral differences between code artifacts.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
code-qualitypythongojavaexpresstestingsecurityperformance

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 2538-symbolic_execution_64987aba --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 2538 Symbolic Execution 64987aba?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 2538 Symbolic Execution 64987aba
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-2538-symbolic-execution-64987aba/badge)](https://www.skillsdirectory.com/skills/tools-only-2538-symbolic-execution-64987aba)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# Symbolic Execution for Equivalence Checking

## Overview

Symbolic execution explores program paths using symbolic values instead of concrete inputs, enabling systematic discovery of behavioral differences between code artifacts.

## Core Concepts

### Symbolic Values

Replace concrete inputs with symbolic variables:
- Concrete: `x = 5` → compute with 5
- Symbolic: `x = α` → track constraints on α

### Path Conditions

Accumulate constraints along execution paths:
```
if (x > 0):
    y = x + 1      # Path condition: x > 0
else:
    y = x - 1      # Path condition: x <= 0
```

### Constraint Solving

Use SMT solvers to:
- Check path feasibility
- Generate concrete test inputs
- Find counterexamples to equivalence

## Equivalence Checking Workflow

### Step 1: Symbolic Execution of Both Artifacts

Execute both artifacts symbolically with same symbolic inputs:

```python
# Artifact A
def artifact_a(x):
    if x > 0:
        return x * 2
    else:
        return 0

# Artifact B
def artifact_b(x):
    if x > 0:
        return x + x
    else:
        return -x
```

**Symbolic execution:**
- Path 1 (x > 0): A returns 2x, B returns 2x → Equivalent
- Path 2 (x ≤ 0): A returns 0, B returns -x → Not equivalent when x < 0

### Step 2: Path Exploration Strategies

**Depth-First Search (DFS):**
- Explore one path completely before backtracking
- Memory efficient
- May miss shallow bugs

**Breadth-First Search (BFS):**
- Explore all paths at depth k before depth k+1
- Finds shallow bugs quickly
- Higher memory usage

**Heuristic-Guided:**
- Prioritize paths likely to reveal differences
- Use coverage metrics or complexity heuristics
- Balance exploration efficiency

### Step 3: Constraint Collection

For each path pair (path_A, path_B):
```
PC_A: path condition for Artifact A
PC_B: path condition for Artifact B
Output_A: symbolic output expression for A
Output_B: symbolic output expression for B

Check: PC_A ∧ PC_B ∧ (Output_A ≠ Output_B)
If satisfiable → Found counterexample
If unsatisfiable → Paths are equivalent
```

### Step 4: Counterexample Generation

When difference found:
1. Extract satisfying assignment from solver
2. Convert symbolic values to concrete test case
3. Verify difference with concrete execution
4. Report input demonstrating non-equivalence

## Tools and Frameworks

### KLEE

Symbolic execution engine for C/LLVM:

```c
#include <klee/klee.h>

int artifact_a(int x) {
    if (x > 0) return x * 2;
    return 0;
}

int artifact_b(int x) {
    if (x > 0) return x + x;
    return -x;
}

int main() {
    int x;
    klee_make_symbolic(&x, sizeof(x), "x");

    int result_a = artifact_a(x);
    int result_b = artifact_b(x);

    klee_assert(result_a == result_b);
    return 0;
}
```

Run: `klee --emit-all-errors program.bc`

### SymDiff

Differential symbolic execution tool:
- Compares two program versions
- Identifies semantic differences
- Generates difference summary

### Angr

Python framework for binary analysis:

```python
import angr

# Load both binaries
proj_a = angr.Project('artifact_a.bin')
proj_b = angr.Project('artifact_b.bin')

# Create symbolic state
state_a = proj_a.factory.entry_state()
state_b = proj_b.factory.entry_state()

# Add symbolic input
x = state_a.solver.BVS('x', 32)
state_a.memory.store(0x1000, x)
state_b.memory.store(0x1000, x)

# Explore paths
simgr_a = proj_a.factory.simulation_manager(state_a)
simgr_b = proj_b.factory.simulation_manager(state_b)

simgr_a.explore()
simgr_b.explore()

# Compare outputs
for state_a in simgr_a.deadended:
    for state_b in simgr_b.deadended:
        if state_a.solver.satisfiable(extra_constraints=[
            state_a.regs.rax != state_b.regs.rax
        ]):
            print("Found difference:", state_a.solver.eval(x))
```

### Java PathFinder (JPF)

Symbolic execution for Java:

```java
import gov.nasa.jpf.symbc.Debug;

public class Equivalence {
    public static int artifactA(int x) {
        if (x > 0) return x * 2;
        return 0;
    }

    public static int artifactB(int x) {
        if (x > 0) return x + x;
        return -x;
    }

    public static void main(String[] args) {
        int x = Debug.makeSymbolicInteger("x");
        int resultA = artifactA(x);
        int resultB = artifactB(x);
        assert resultA == resultB : "Not equivalent";
    }
}
```

## Handling Complexity

### Path Explosion

**Problem:** Exponential growth in number of paths

**Solutions:**
1. **Path merging**: Combine similar paths using disjunctions
2. **Loop bounds**: Limit loop iterations (k-bounded exploration)
3. **Function summaries**: Precompute summaries for called functions
4. **Compositional analysis**: Verify components separately

### Constraint Complexity

**Problem:** Complex constraints slow down solver

**Solutions:**
1. **Incremental solving**: Reuse solver state across paths
2. **Constraint simplification**: Apply algebraic simplifications
3. **Theory-specific optimizations**: Use specialized solvers
4. **Concretization**: Replace symbolic values with concrete ones when beneficial

### Memory Modeling

**Problem:** Symbolic pointers and heap operations

**Solutions:**
1. **Lazy initialization**: Create objects on-demand
2. **Address concretization**: Use concrete addresses when possible
3. **Shape analysis**: Abstract heap structure
4. **Bounded heap**: Limit heap size for analysis

## Differential Symbolic Execution

Optimize for equivalence checking:

**Key insight:** Only explore paths where artifacts diverge

**Algorithm:**
1. Execute both artifacts in lockstep
2. When control flow diverges, fork exploration
3. When control flow reconverges, check output equivalence
4. Prune equivalent paths early

**Benefits:**
- Fewer paths to explore
- Faster counterexample discovery
- Scales better than independent analysis

## Practical Guidelines

**When to use symbolic execution:**
- Moderate-sized functions (< 1000 LOC)
- Programs with complex branching logic
- When concrete test generation is difficult
- Security-critical code paths

**Limitations:**
- Path explosion for large programs
- Constraint solver timeouts
- External dependencies (I/O, network)
- Native code and system calls

**Best practices:**
- Set reasonable time/path bounds
- Focus on critical code sections
- Combine with concrete testing
- Use function summaries for libraries
- Monitor solver performance

## Example: Complete Workflow

```python
# Using Z3 for simple symbolic execution

from z3 import *

def symbolic_execute_equivalence(artifact_a, artifact_b, input_vars):
    """
    Check equivalence using symbolic execution

    Returns: (is_equivalent, counterexample)
    """
    solver = Solver()

    # Execute both artifacts symbolically
    result_a = artifact_a(*input_vars)
    result_b = artifact_b(*input_vars)

    # Check if outputs can differ
    solver.add(result_a != result_b)

    if solver.check() == sat:
        # Found counterexample
        model = solver.model()
        counterexample = {str(v): model[v] for v in input_vars}
        return False, counterexample
    else:
        # Proven equivalent
        return True, None

# Example usage
x = Int('x')
y = Int('y')

def artifact_a(x, y):
    return If(x > y, x - y, y - x)

def artifact_b(x, y):
    return If(x > y, x - y, x - y)  # Bug: should be y - x

is_equiv, counter = symbolic_execute_equivalence(artifact_a, artifact_b, [x, y])

if is_equiv:
    print("Artifacts are equivalent")
else:
    print(f"Not equivalent. Counterexample: {counter}")
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.