1 /*
2  * Copyright (C) 2017 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 
17 package dexfuzz.program.mutators;
18 
19 import dexfuzz.MutationStats;
20 import dexfuzz.program.MInsn;
21 import dexfuzz.program.Mutation;
22 import dexfuzz.rawdex.Opcode;
23 import java.util.List;
24 import java.util.Random;
25 
26 public class RandomBranchChanger extends IfBranchChanger {
27 
28   private static final Opcode[] EQUALITY_CMP_OP_LIST = {
29     Opcode.IF_EQ,
30     Opcode.IF_NE,
31     Opcode.IF_LT,
32     Opcode.IF_GE,
33     Opcode.IF_GT,
34     Opcode.IF_LE
35   };
36 
37   private static final Opcode[] ZERO_CMP_OP_LIST = {
38     Opcode.IF_EQZ,
39     Opcode.IF_NEZ,
40     Opcode.IF_LTZ,
41     Opcode.IF_GEZ,
42     Opcode.IF_GTZ,
43     Opcode.IF_LEZ
44   };
45 
RandomBranchChanger(Random rng, MutationStats stats, List<Mutation> mutations)46   public RandomBranchChanger(Random rng, MutationStats stats, List<Mutation> mutations) {
47     super(rng, stats, mutations);
48     likelihood = 30;
49   }
50 
51   @Override
getModifiedOpcode(MInsn mInsn)52   protected Opcode getModifiedOpcode(MInsn mInsn) {
53     Opcode opcode = mInsn.insn.info.opcode;
54     if (Opcode.isBetween(opcode, Opcode.IF_EQ, Opcode.IF_LE)) {
55       int index = opcode.ordinal() - Opcode.IF_EQ.ordinal();
56       int length = EQUALITY_CMP_OP_LIST.length;
57       return EQUALITY_CMP_OP_LIST[(index + 1 + rng.nextInt(length - 1)) % length];
58     } else if (Opcode.isBetween(opcode, Opcode.IF_EQZ, Opcode.IF_LEZ)) {
59       int index = opcode.ordinal() - Opcode.IF_EQZ.ordinal();
60       int length = ZERO_CMP_OP_LIST.length;
61       return ZERO_CMP_OP_LIST[(index + 1 + rng.nextInt(length - 1)) % length];
62     }
63     return opcode;
64   }
65 
66   @Override
getMutationTag()67   protected String getMutationTag() {
68     return "random";
69   }
70 }