001: /* Soot - a J*va Optimization Framework
002: * Copyright (C) 1997-1999 Raja Vallee-Rai
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the
016: * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
017: * Boston, MA 02111-1307, USA.
018: */
019:
020: package soot.jbco.bafTransformations;
021:
022: import java.util.*;
023: import soot.*;
024: import soot.baf.*;
025: import soot.jimple.*;
026: import soot.jbco.IJbcoTransform;
027: import soot.jbco.util.*;
028:
029: public class ConstructorConfuser extends BodyTransformer implements
030: IJbcoTransform {
031:
032: static int count = 0;
033:
034: static int instances[] = new int[4];
035:
036: public static String dependancies[] = new String[] { "bb.jbco_dcc",
037: "bb.jbco_ful", "bb.lp" };
038:
039: public String[] getDependancies() {
040: return dependancies;
041: }
042:
043: public static String name = "bb.jbco_dcc";
044:
045: public String getName() {
046: return name;
047: }
048:
049: public void outputSummary() {
050: out.println("Constructor methods have been jumbled: " + count);
051: }
052:
053: @SuppressWarnings("fallthrough")
054: protected void internalTransform(Body b, String phaseName,
055: Map options) {
056: if (!b.getMethod().getSubSignature().equals("void <init>()"))
057: return;
058: int weight = soot.jbco.Main.getWeight(phaseName, b.getMethod()
059: .getSignature());
060: if (weight == 0)
061: return;
062:
063: SootClass origClass = b.getMethod().getDeclaringClass();
064: SootClass c = origClass;
065: if (c.hasSuperclass()) {
066: c = c.getSuperclass();
067: } else {
068: c = null;
069: }
070:
071: PatchingChain units = b.getUnits();
072: Iterator it = units.snapshotIterator();
073: Unit prev = null;
074: SpecialInvokeInst sii = null;
075: while (it.hasNext()) {
076: Unit u = (Unit) it.next();
077: if (u instanceof SpecialInvokeInst) {
078: sii = (SpecialInvokeInst) u;
079: SootMethodRef smr = sii.getMethodRef();
080: if (c == null
081: || !smr.declaringClass().getName().equals(
082: c.getName())
083: || !smr.name().equals("<init>")) {
084: sii = null;
085: } else {
086: break;
087: }
088: }
089: prev = u;
090: }
091:
092: if (sii == null)
093: return;
094:
095: int lowi = -1, lowest = 99999999, rand = Rand.getInt(4);
096: for (int i = 0; i < instances.length; i++)
097: if (lowest > instances[i]) {
098: lowest = instances[i];
099: lowi = i;
100: }
101: if (instances[rand] > instances[lowi])
102: rand = lowi;
103:
104: boolean done = false;
105: switch (rand) {
106: case 0:
107: if (prev != null
108: && prev instanceof LoadInst
109: && sii.getMethodRef().parameterTypes().size() == 0
110: && !BodyBuilder.isExceptionCaughtAt(units, sii, b
111: .getTraps().iterator())) {
112:
113: Local bl = ((LoadInst) prev).getLocal();
114: HashMap locals = soot.jbco.Main.methods2Baf2JLocals
115: .get(b.getMethod());
116: if (locals != null && locals.containsKey(bl)) {
117: Type t = ((Local) locals.get(bl)).getType();
118: if (t instanceof RefType
119: && ((RefType) t).getSootClass().getName()
120: .equals(origClass.getName())) {
121: units.insertBefore(Baf.v().newDup1Inst(
122: RefType.v()), sii);
123: Unit ifinst = Baf.v().newIfNullInst(sii);
124: units.insertBeforeNoRedirect(ifinst, sii);
125: units.insertAfter(Baf.v().newThrowInst(),
126: ifinst);
127: units.insertAfter(Baf.v().newPushInst(
128: NullConstant.v()), ifinst);
129:
130: Unit pop = Baf.v().newPopInst(RefType.v());
131: units.add(pop);
132: units.add(prev.clone());
133: b.getTraps().add(
134: Baf.v().newTrap(
135: ThrowSet.getRandomThrowable(),
136: ifinst, sii, pop));
137: if (Rand.getInt() % 2 == 0) {
138: pop = (Unit) pop.clone();
139: units.insertBefore(pop, sii);
140: units.insertBefore(
141: Baf.v().newGotoInst(sii), pop);
142: units.add(Baf.v().newJSRInst(pop));
143: } else
144: units.add(Baf.v().newGotoInst(sii));
145: done = true;
146: break;
147: }
148: }
149: }
150: case 1:
151: if (!BodyBuilder.isExceptionCaughtAt(units, sii, b
152: .getTraps().iterator())) {
153: Unit handler = Baf.v().newThrowInst();
154: units.add(handler);
155: b.getTraps().add(
156: Baf.v().newTrap(ThrowSet.getRandomThrowable(),
157: sii, (Unit) units.getSuccOf(sii),
158: handler));
159: done = true;
160: break;
161: }
162: case 2:
163: if (sii.getMethodRef().parameterTypes().size() == 0
164: && !BodyBuilder.isExceptionCaughtAt(units, sii, b
165: .getTraps().iterator())) {
166: while (c != null) {
167: if (c.getName().equals("java.lang.Throwable")) {
168: Unit throwThis = Baf.v().newThrowInst();
169: units.insertBefore(throwThis, sii);
170: b.getTraps().add(
171: Baf.v().newTrap(origClass, throwThis,
172: sii, sii));
173: done = true;
174: break;
175: }
176:
177: if (c.hasSuperclass())
178: c = c.getSuperclass();
179: else
180: c = null;
181: }
182: }
183: if (done)
184: break;
185: case 3:
186: Unit pop = Baf.v().newPopInst(RefType.v());
187: units.insertBefore(pop, sii);
188: units.insertBeforeNoRedirect(Baf.v().newJSRInst(pop), pop);
189: done = true;
190: break;
191: }
192:
193: if (done) {
194: instances[rand]++;
195: count++;
196: }
197:
198: if (debug)
199: StackTypeHeightCalculator.calculateStackHeights(b);
200: }
201: }
|