1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package dexfuzz;
18
19import dexfuzz.fuzzers.Fuzzer;
20import dexfuzz.fuzzers.FuzzerMultipleExecute;
21import dexfuzz.fuzzers.FuzzerMultipleNoExecute;
22import dexfuzz.fuzzers.FuzzerSingleExecute;
23import dexfuzz.fuzzers.FuzzerSingleNoExecute;
24import dexfuzz.listeners.BaseListener;
25import dexfuzz.listeners.ConsoleLoggerListener;
26import dexfuzz.listeners.LogFileListener;
27import dexfuzz.listeners.MultiplexerListener;
28import dexfuzz.listeners.UniqueProgramTrackerListener;
29import dexfuzz.listeners.UpdatingConsoleListener;
30
31/**
32 * Entrypoint class for dexfuzz.
33 */
34public class DexFuzz {
35  private static int majorVersion = 1;
36  private static int minorVersion = 1;
37  private static int seedChangeVersion = 0;
38
39  /**
40   * Entrypoint to dexfuzz.
41   */
42  public static void main(String[] args) {
43    // Report the version number, which should be incremented every time something will cause
44    // the same input seed to produce a different result than before.
45    Log.always(String.format("DexFuzz v%d.%d.%d",
46        majorVersion, minorVersion, seedChangeVersion));
47    Log.always("");
48
49    if (!Options.readOptions(args)) {
50      Log.error("Failed to validate options.");
51      Options.usage();
52    }
53
54    // Create the Listener, which will listen for events and report them.
55    BaseListener listener = null;
56    if (Options.repeat > 1 && Options.execute) {
57      // Create a Listener that is responsible for multiple Listeners.
58      MultiplexerListener multipleListener = new MultiplexerListener();
59      multipleListener.setup();
60      // Add the live updating listener, but only if we're not printing out lots of logs.
61      if (!Log.likelyToLog()) {
62        multipleListener.addListener(new UpdatingConsoleListener());
63      } else {
64        // If we are dumping out lots of logs, then use the ConsoleLogger instead.
65        multipleListener.addListener(new ConsoleLoggerListener());
66      }
67      // Add the file logging listener.
68      multipleListener.addListener(new LogFileListener(Options.reportLogFile));
69      // Add the unique program tracker.
70      multipleListener.addListener(new UniqueProgramTrackerListener(Options.uniqueDatabaseFile));
71      listener = multipleListener;
72    } else {
73      // Just use the basic listener.
74      listener = new ConsoleLoggerListener();
75    }
76
77    // Create the Fuzzer that uses a particular strategy for fuzzing.
78    Fuzzer fuzzer = null;
79    if ((Options.repeat > 1) && Options.execute) {
80      fuzzer = new FuzzerMultipleExecute(listener);
81    } else if ((Options.repeat > 1) && !Options.execute) {
82      fuzzer = new FuzzerMultipleNoExecute(listener);
83    } else if ((Options.repeat == 1) && Options.execute) {
84      fuzzer = new FuzzerSingleExecute(listener);
85    } else if ((Options.repeat == 1) && !Options.execute) {
86      fuzzer = new FuzzerSingleNoExecute(listener);
87    } else {
88      Log.errorAndQuit("Invalid options provided, desired fuzzer unknown.");
89    }
90    // TODO: Implement FuzzerFindMinimalMutations.
91    // TODO: Implement FuzzerGenerational.
92
93    // Actually run the Fuzzer.
94    fuzzer.run();
95    fuzzer.printTimingInfo();
96    fuzzer.shutdown();
97
98    // Cleanup the Listener.
99    listener.shutdown();
100  }
101}
102