## 1 Introduction
QSYM [10] is the state-of-the-art hybrid fuzzing work, which has a highly tailored concolic execution engine designed for fuzzing and a synchronization method with the AFL [2] fuzzer. It shows impressive efficiency in finding vulnerabilities and increasing program execution coverage because running concolic execution in parallel can generate much more new inputs than the other two methods. Although hybrid fuzzing with the synchronization method seems like the most efficient way, for now, there are still numerous unsolved problems related to its mechanism. Firstly, there are too many candidate inputs for concolic execution. The fuzzing engine can generate numerous candidate inputs in the queue, mostly as many as thousands of inputs in 12 h, while at the same time, concolic execution can only analyze hundreds of inputs at most. For example, we test libjpeg-turbo-07-2017 in the Google Fuzzer Test Suite [20] with QSYM for 12 h and find that there are 4420 test cases generated in the AFL slave queue, while QSYM, which selects the candidate input to perform concolic execution from this queue, analyzes 483 files and generates 1444 new test cases. In this case, only 10% of the candidate inputs are analyzed. If we choose the candidate inputs randomly, the effectiveness of finding deeper paths cannot be optimized. The reason for this problem is that the time of concolic execution for one input is normally counted by minutes or even hours, and as a result, in a certain amount of time, not many inputs can be executed. Thus, we need a clever input selection method for concolic execution. Secondly, there are many branches in one input. Since the theory of concolic execution is to negate the branches of executing one input to generate new test cases, solving every branch in the program will take too much time, especially when there are loops in the code. Besides, most candidate inputs share same branches, causing the overlap of newly generated test cases. This means there will be duplicates of inputs that guide execution to the same coverage, and the fuzzer will take extra time to analyze and synchronize those duplicates and cause unnecessary overhead, i.e., time and memory assumption. Thirdly, different branches have different complexities, and some of them are not suitable for concolic execution to solve. Different complexities of branches result in different times to solve by concolic execution. Some of the branches are easy enough for the fuzzer to find, so the newly generated test cases from these branches may not be synchronized by the fuzzer because they have already been found by the fuzzer. In other words, concolic execution should focus more on the complicated branches than the simple ones. In summary, the ideal way to perform hybrid fuzzing with synchronization is that every new test case generated by concolic execution should guide the execution to new coverage, which fuzzing can hardly reach. Our approach intends to get as close to this aim as possible. In this paper, we propose a Selective Hybrid Fuzzing (SHF) approach to solve these problems and enhance the performance of hybrid fuzzing, with two main algorithms. (1) The critical branch selection algorithm: We use three metrics, hit accuracy, solvability, and complexity, to describe the critical information provided by each branch. Specifically, we use dynamic binary instrumentation, a technique to analyze binary programs with instrumentation when running the program, to get the information of program execution, based on which we try to find out the branches that can guide the execution to the unexplored path, solvable to get new test cases and hard to be found by the fuzzer. (2) The priority score calculation algorithm: We choose the input with the most optimal branches as the candidate input for concolic execution based on the branch scheduling results from the previous method. Our contributions:  
* We systematically study the branch scheduling problem in hybrid fuzzing with the synchronization mechanism.