Skip to content

Commit b763882

Browse files
author
Samuel Groß
committed
Update HowFuzzilliWorks.md document
For example to include the new ExplorationMutator.
1 parent d6d10b0 commit b763882

File tree

1 file changed

+29
-26
lines changed

1 file changed

+29
-26
lines changed

Docs/HowFuzzilliWorks.md

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,9 @@ v4 <- BinaryOperation v1 '/' v2
123123
```
124124

125125
### Splicing
126-
Implementation: [Implemented as part of the ProgramBuilder class](https://github.com/googleprojectzero/fuzzilli/blob/ce4738fc571e2ef2aa5a30424f32f7957a70b5f3/Sources/Fuzzilli/Core/ProgramBuilder.swift#L619)
126+
Implementation: [SpliceMutator](https://github.com/googleprojectzero/fuzzilli/blob/main/Sources/Fuzzilli/Mutators/SpliceMutator.swift)
127127

128-
The idea behind splicing is to copy a self-contained part of another program into the one that is currently being mutated. Consider the following program:
128+
The idea behind splicing is to copy a self-contained part of one program into another in order to combine features from different programs. Consider the following program:
129129

130130
```
131131
v0 <- LoadInt '42'
@@ -145,21 +145,19 @@ v15 <- CallMethod v14, 'sin', [v13]
145145
... existing code
146146
```
147147

148-
Splicing ultimately helps combine different features from multiple programs into a single program.
149-
150-
A trivial variant of the splice mutation is the [CombineMutator](https://github.com/googleprojectzero/fuzzilli/blob/main/Sources/Fuzzilli/Mutators/CombineMutator.swift) which simply inserts another program in full into the currently mutated one. In that case, the splice is essentially the entire program.
151-
152-
Fuzzilli [also features](https://github.com/googleprojectzero/fuzzilli/commit/643ac76336520b0cf67ae7feefbe4882908a8fa8) a more sophisticated implementation of splicing which is able to connect the dataflow of the inserted code with the existing program by searching for "matching" variable substitutions in the existing code. This is possible through the type system, discussed below. With that, splicing from the above program could also result in the following:
148+
More complex splices are also possible. For example, Fuzzilli will probabilistically remap some variables in the program being spliced from to "compatible" variables in the host program to combine the data-flows of the two programs, and so could also end up producing the following result:
153149

154150
```
155151
... existing code
156-
v7 <- ... some operation that results in a float
157-
... existing code
158152
v14 <- LoadBuiltin 'Math'
159-
v15 <- CallMethod v14, 'sin', [v7]
153+
v15 <- CallMethod v14, 'sin', [v3]
160154
... existing code
161155
```
162156

157+
Here, the splicing algorithm has decided to replace the `LoadFloat` operation with an existing variable (`v3`), for example because that variable also contains a float.
158+
159+
A trivial variant of the splice mutation is the [CombineMutator](https://github.com/googleprojectzero/fuzzilli/blob/main/Sources/Fuzzilli/Mutators/CombineMutator.swift) which simply inserts another program in full into the currently mutated one. In that case, the splice is essentially the entire program.
160+
163161
### Code Generation
164162
Implementation: [CodeGenMutator.swift](https://github.com/googleprojectzero/fuzzilli/blob/main/Sources/Fuzzilli/Mutators/CodeGenMutator.swift)
165163

@@ -173,32 +171,37 @@ CodeGenerator("IntegerGenerator") { b in
173171
}
174172
```
175173

176-
This generator emits a LoadInteger instruction that creates a new variable containing a random integer value (technically, not completely random since [genInt()](https://github.com/googleprojectzero/fuzzilli/blob/ce4738fc571e2ef2aa5a30424f32f7957a70b5f3/Sources/Fuzzilli/Core/ProgramBuilder.swift#L128) will favor some ["interesting" integers](https://github.com/googleprojectzero/fuzzilli/blob/ce4738fc571e2ef2aa5a30424f32f7957a70b5f3/Sources/Fuzzilli/Core/JavaScriptEnvironment.swift#L20)). Another example code generator might be:
174+
This generator emits a LoadInteger instruction that creates a new variable containing a random integer value (technically, not completely random since `genInt()` will favor some "interesting" integers). Another example code generator might be:
177175

178176
```swift
179-
CodeGenerator("ComparisonGenerator") { b in
180-
let lhs = b.randVar()
181-
let rhs = b.randVar()
182-
b.compare(lhs, rhs, with: chooseUniform(from: allComparators))
183-
}
177+
CodeGenerator("ComparisonGenerator", inputs: (.anything, .anything)) { b, lhs, rhs in
178+
b.compare(lhs, with: rhs, using: chooseUniform(from: allComparators))
179+
},
184180
```
185181

186-
This generator emits a comparison instruction (e.g. `==`) comparing two existing variables.
182+
This generator emits a comparison instruction (e.g. `==`) comparing two existing variables (of arbitrary type).
187183

188184
The default code generators can be found in [CodeGenerators.swift](https://github.com/googleprojectzero/fuzzilli/blob/main/Sources/Fuzzilli/Core/CodeGenerators.swift) while custom code generators can be added for specific engines, for example to [trigger different levels of JITing](https://github.com/googleprojectzero/fuzzilli/blob/main/Sources/FuzzilliCli/Profiles/JSCProfile.swift).
189185

190-
Code generators are stored in a weighted list and are thus selected with different, currently [manually chosen weights](https://github.com/googleprojectzero/fuzzilli/blob/main/Sources/FuzzilliCli/CodeGeneratorWeights.swift) (it would be nice to eventually have these [weights be selected automatically](https://github.com/googleprojectzero/fuzzilli/issues/172) though). This allows some degree of control over the distribution of the generated code, for example roughly how often arithmetic operations or method calls are performed, or how much control flow (if-else, loops, ...) is generated relative to data flow. Furthermore, CodeGenerators provide a simple way to steer Fuzzilli towards certain bug types by adding CodeGenerators that generate code fragments that have frequently resulted in bugs in the past, such as prototype changes, custom type conversion callbacks (e.g. valueOf), or indexed accessors.
186+
Code generators are stored in a weighted list and are thus selected with different, currently [manually chosen weights](https://github.com/googleprojectzero/fuzzilli/blob/main/Sources/FuzzilliCli/CodeGeneratorWeights.swift). This allows some degree of control over the distribution of the generated code, for example roughly how often arithmetic operations or method calls are performed, or how much control flow (if-else, loops, ...) is generated relative to data flow. Furthermore, CodeGenerators provide a simple way to steer Fuzzilli towards certain bug types by adding CodeGenerators that generate code fragments that have frequently resulted in bugs in the past, such as prototype changes, custom type conversion callbacks (e.g. valueOf), or indexed accessors.
191187

192-
The CodeGenerators allow Fuzzilli to start from a single, arbitrarily chosen initial sample (or, in theory, also from no corpus at all):
188+
Through the code generators, all relevant language features (e.g. object operations, unary and binary operations, etc.) will eventually be generated, then kept in the corpus (because they trigger new coverage) and further mutated afterwards.
193189

194-
```javascript
195-
let v0 = Object();
196-
```
190+
### Exploration
191+
Implementation: [ExplorationMutator.swift](https://github.com/googleprojectzero/fuzzilli/blob/main/Sources/Fuzzilli/Mutators/ExplorationMutator.swift)
197192

198-
Through the code generators, all relevant language features (e.g. object operations, unary and binary operations, etc.) will eventually be generated, then kept in the corpus (because they trigger new coverage) and further mutated afterwards.
193+
This advanced mutator uses runtime type information available in JavaScript to perform more intelligent mutations. It does the following:
194+
1. It inserts `Explore` operations for random existing variables in the program to be mutated
195+
2. It executes the resulting (temporary) program. The `Explore` operations will be lifted
196+
to a sequence of code that inspects the variable at runtime (using features like 'typeof' and
197+
'Object.getOwnPropertyNames' in JavaScript) and selects a "useful" operation to perform
198+
on it (e.g. load a property, call a method, ...), then reports back what it did
199+
3. The mutator processes the output of step 2 and replaces some of the Explore mutations
200+
with the concrete action that was selected at runtime. All other Explore operations are discarded.
199201

200-
### Additional Mutations?
201-
There is room for additional mutations, for example ones that specifically target control flow. Possible options include duplicating existing code fragments or moving them around in the program. This is subject to further research.
202+
The result is a program that performs useful actions on some of the existing variables even without
203+
statically knowing their type. The resulting program is also deterministic and "JIT friendly" as it
204+
no longer relies on any kind of runtime object inspection.
202205

203206
## The Type System
204207
Implementation: [TypeSystem.swift](https://github.com/googleprojectzero/fuzzilli/blob/main/Sources/Fuzzilli/FuzzIL/TypeSystem.swift) and [JSTyper.swift](https://github.com/googleprojectzero/fuzzilli/blob/main/Sources/Fuzzilli/FuzzIL/JSTyper.swift)
@@ -464,7 +467,7 @@ There are a number of possible solutions to this problem:
464467
* Improve the code generation infrastructure and use it to create new programs from scratch, possibly targeting specific bug types or components of the target JavaScript engine. The remainder of this document discusses this approach and the HybridEngine that implements it.
465468

466469

467-
## Hybrid Fuzzing
470+
## Hybrid Fuzzing (Experimental)
468471
The central idea behind the HybridEngine is to combine a conservative code generation engine with the existing mutations and the splicing mechanism. This achieves a number of things:
469472

470473
* It allows the pure code generator to be fairly conservative so as to reduce its complexity while still achieving a reasonable correctness rate (rate of semantically valid samples)

0 commit comments

Comments
 (0)