Every program bug has at least one concrete input that triggers it. The tricky part is finding that input without knowing it in advance.
Symbolic execution flips the question. Instead of picking a specific number and running the program, it leaves the input as an unknown — call it — and asks: what does the program's behavior look like for all possible values of at once?
As the program executes, each branch it takes adds a constraint on . After a if (x > 10) branch, you know . After another if (x == 42) branch, you know . When a crash path is reached, the accumulated constraints form a system of equations. Hand that system to a constraint solver (typically a SAT or SMT solver), and it hands back a concrete input that walks straight into the crash.
Invented in 1976 by James C. King, symbolic execution stayed largely theoretical for decades — constraint solvers were too slow. Once modern SMT solvers appeared in the mid-2000s, tools like DART, SAGE, and KLEE turned it into a practical weapon for finding security vulnerabilities in real software.
Comments
Loading comments...