# SwitchFuzz: Switch Short-Term Goals in Directed Grey-Box Fuzzing
## 5 Methodology/Design
### Try Another Way--Switch Queue
#### 5.2.2 When to Switch  
As stated in Section 5.2.1, new seeds found in queue_main need to be dispatched immediately. Due to the limited number of seeds within it, even frequent scheduling does not result in significant time wastage. Each execution implies that a seed closer to the target is created, so we take the number of execution rounds \(n\) of the queue as the limit. If a closer seed is found in the process, the execution rounds are reset and the execution continues. If a closer seed is not found after \(n\) execution rounds, the queue is switched back to the previous one. For the other two queues, we take a time-slice scheduling approach, similar to that of a time-sharing system--a time is assigned to each of the two queues, and it switches to the next queue when the execution time exceeds this time-slice. Unlike traditional time-slices, we do not use execution time as a criterion. Instead, we use the time since the last new coverage was discovered. We set a variable called \"tolerance time\" for each queue before it is scheduled. At the end of each fuzzing loop, the queue will be switched to the next one if the time since the last coverage is found to exceed the tolerance time. This design produces a queuethat is able to refresh its timings after new coverage is found, allowing it to continue execution. This also makes it possible to make a queue switch to try to complete other tasks or to get some help for this queue when we cannot obtain satisfactory results for a long time. Let us now consider how the tolerance time should be obtained. Equations (1)-(3) show how the tolerance time \(t_{t}\) is calculated. In Equation (1), \(t_{am}\) is the shortest distance since the last update. When there is no means of obtaining a shorter distance, we assume that the exploration is stuck halfway or has reached the target point. In either case, we need more time to execute queue_side. \(t_{am}\) is a time factor, which is set by the user before execution. When there has been no distance update, it determines how long the tolerance time will be to increase to twice as much as that of the queue_exp. \[c_{amm}= \begin{cases}1&queue\_exp\\ 2-e^{-t_{am}*t_{am}}&queue\_side\end{cases}  \tag{1}\]  
We have a time factor denoted \(c_{amm}\), but no time base. How to design a suitable time base then becomes a problem. Some programs resulting from bad code writing habits can easily trigger a crash. Even if it can trigger a crash occasionally in one queue, it may not be as fast as the other queues, analogous to squeezing out the last bit of toothpaste. For programs that have more difficulty triggering crashes, frequent queue switching is not very helpful in finding crashes, because they are not stuck halfway but arise because most parts of the program do not have vulnerability points. So we need to be able to adjust this time base through a dynamic process. In Equation (2), \(t_{c}\) indicates the time base of a queue execution for subsequent calculation of the tolerance time and \(count_{fd}\) denotes the number of execution rounds in which a unique crash is consecutively found. Each execution round loop includes three queue-switching schedules. Even though queue_exp may be skipped, we still consider that switching back to queue_main adds a round. \(count_{nfd}\) indicates the number of consecutive  
Figure 8: Switch flowchart. execution rounds where no unique crash is found. \(count_{c}\) indicates the number of times that \(t_{c}\) is changed in the same direction (zoomed in or out). For example, the initial time base is \(n\). When the execution finishes one round, a new unique crash still cannot be generated. At this point, we believe that it is not that the individual queues are not performing well and need to be switched frequently, but that it is harder to trigger crashes overall. Then, we let the time base expand to \(2n\). The next expansion to \(4n\) requires two consecutive rounds, the expansion to \(8n\) requires four consecutive rounds, and so on. If it is scaled down, it will still only take one round.