  Memory corruption is a serious class of software vulnerabilities, which
requires careful attention to be detected and removed from applications before
getting exploited and harming the system users. Symbolic execution is a
well-known method for analyzing programs and detecting various vulnerabilities,
e.g., memory corruption. Although this method is sound and complete in theory,
it faces some challenges, such as path explosion, when applied to real-world
complex programs. In this paper, we present a method for improving the
efficiency of symbolic execution and detecting four classes of memory
corruption vulnerabilities in executable codes, i.e., heap-based buffer
overflow, stack-based buffer overflow, use-after-free, and double-free. We
perform symbolic execution only on test units rather than the whole program to
avoid path explosion. In our method, test units are considered parts of the
program's code, which might contain vulnerable statements and are statically
identified based on the specifications of memory corruption vulnerabilities.
Then, each test unit is symbolically executed to calculate path and
vulnerability constraints of each statement of the unit, which determine the
conditions on unit input data for executing that statement or activating
vulnerabilities in it, respectively. Solving these constraints gives us input
values for the test unit, which execute the desired statements and reveal
vulnerabilities in them. Finally, we use machine learning to approximate the
correlation between system and unit input data. Thereby, we generate system
inputs that enter the program, reach vulnerable instructions in the desired
test unit, and reveal vulnerabilities in them. This method is implemented as a
plugin for angr framework and evaluated using a group of benchmark programs.
The experiments show its superiority over similar tools in accuracy and
performance.
