## 2 Motivation  
One of the most efficient solutions for increasing code coverage is the coverage-guided fuzzing approach. Some state-of-art-coverage-guided fuzzing techniques including AFL [3], Hongfuzz [28], LibFuzzer [29] focus on the increasing ability of code coverage and quickly discover software-application flaws. To trigger new code paths, fuzzing tools focus on the mutating seed inputs while generating new test cases. However, fuzz testing methods have a generally known drawback. Figure 1 illustrates the challenges faced by the fuzzer in discovering bugs hidden in the deep parts of target programs. The structure of software applications is complex, especially if it contains several magic bytes and nested complex checks (say, checksums). This type of check has always made the software vulnerability testing system difficult. Checksums [30; 31] are a typical way of analyzing the probity of data widely used in real-world software applications, in network protocols (for example, TCP/IP) and in various file formats (such as ZLIB, PNG). It is too difficult for software testing approaches to generate valid input to bypass checksums as well as magic bytes, and the path of the fuzzer can be blocked. Specifically, mutational fuzzing tools are incapable of passing through complex roadblock checks, and when programs have checksum instruments, there is a high probability of the rejection of generated seeds in the early stage of running the program. As a result, if the path is hard to explore, fuzzers get'stuck' and choose other paths that are easier to take without covering the new path. Listing 1 illustrates a simplified scenario and issues regarding existing fuzzing approaches that explain our motivation as well as common roadblock checks. In this example, there are various complex roadblock checks and magic bytes. It is widely known that passing some nested checks for generated inputs is not straightforward. ```
1#defineBUFSIZE100
2#defineSIZE5
3 intmain(intargc,char**argv){
4 unsignedcharinput[BUF_SIZE];
5 charsource[SIZE];
6 gets(source);
7//agicbyteexample
8 ff(strcmp(source,\"HELLO\")==0){
9 printf(\"Matchedsuccesfully!\
\");
10}
11 else{
12 EXIT_ERROR(\"Inappropriatedata\
\");
13}
14
15//nestedcomplexsanitycheckexample
16 if(input[0]==0 xAB&input[1]==0 xCD){
17 printf(\"Passthenextchecksuccessfully!\
\");
18 if(input[16]=='! *&input[17]=='P'){
19//triggertheBUG
20}
21 else{
22//somecommoncodeswithoutvulnerabilities
23}
24}
25 else{
26 ERROR(\"Inappropriatebytes\
\");
27//someothercodes
28}
29 return0;
30}
```  
Figure 1: Challenge for fuzz testing methods. For this motivating example, the majority of modern coverage-based fuzzers and hybrid testing systems have many limitations and penetration power restrictions to pass through the path blocked by magic bytes comparisons. For instance, the string _\"HELLO\"_ in line 8 of the program is five magic bytes. To bypass line 8, the state-of-the-art fuzzers must mutate all the five magic bytes all at once and do so correctly. The reason is that mutating _\"HAAAA\"_, _\"HEAAA\"_, _\"HELAA\"_, _\"HELA\"_ correctly cannot lead to a new execution path. Under these circumstances, it is too complex for coverage-based fuzzers to cover the magic bytes, not to mention the numerous executions that need to be investigated to pass magic bytes. The challenge is that the most modern coverage-based fuzzing tools are incapable of knowing the location of magic bytes that are present within the input of the test, causing these approaches to waste time trying to match magic bytes successfully. Another common challenge for fuzz testing techniques is effectively fuzzing checksums. It is very difficult to generate accurate inputs to pass complex checksums for modern constraint solvers. A typical sample of nested condition statements is depicted from line 16 to line 18 in Listing 1. To reach line 18, which triggers the bug, the first input must satisfy the constraint at line 16. Secondly, after passing the first check successfully, it must satisfy the next check at line 18.