  Despite the fact that the state-of-the-art fuzzers can generate inputs
efficiently, existing fuzz drivers still cannot adequately cover entries in
libraries. Most of these fuzz drivers are crafted manually by developers, and
their quality depends on the developers' understanding of the code. Existing
works have attempted to automate the generation of fuzz drivers by learning API
usage from code and execution traces. However, the generated fuzz drivers are
limited to a few specific call sequences by the code being learned. To address
these challenges, we present HOPPER, which can fuzz libraries without requiring
any domain knowledge to craft fuzz drivers. It transforms the problem of
library fuzzing into the problem of interpreter fuzzing. The interpreters
linked against libraries under test can interpret the inputs that describe
arbitrary API usage. To generate semantically correct inputs for the
interpreter, HOPPER learns the intra- and inter-API constraints in the
libraries and mutates the program with grammar awareness. We implemented HOPPER
and evaluated its effectiveness on 11 real-world libraries against manually
crafted fuzzers and other automatic solutions. Our results show that HOPPER
greatly outperformed the other fuzzers in both code coverage and bug finding,
having uncovered 25 previously unknown bugs that other fuzzers couldn't.
Moreover, we have demonstrated that the proposed intra- and inter-API
constraint learning methods can correctly learn constraints implied by the
library and, therefore, significantly improve the fuzzing efficiency. The
experiment results indicate that HOPPER is able to explore a vast range of API
usages for library fuzzing out of the box.
