KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jode > obfuscator > MethodIdentifier


1 /* MethodIdentifier Copyright (C) 1999-2002 Jochen Hoenicke.
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2, or (at your option)
6  * any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; see the file COPYING. If not, write to
15  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
16  *
17  * $Id: MethodIdentifier.java.in,v 1.7.2.2 2002/05/28 17:34:14 hoenicke Exp $
18  */

19
20 package jode.obfuscator;
21 import jode.AssertError;
22 import jode.GlobalOptions;
23 import jode.bytecode.*;
24
25 import java.util.Collections JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.Map JavaDoc;
28
29 import java.lang.reflect.Modifier JavaDoc;
30 import java.util.BitSet JavaDoc;
31
32 public class MethodIdentifier extends Identifier implements Opcodes {
33     ClassIdentifier clazz;
34     MethodInfo info;
35     String JavaDoc name;
36     String JavaDoc type;
37
38     boolean globalSideEffects;
39     BitSet JavaDoc localSideEffects;
40
41     /**
42      * The code analyzer of this method, or null if there isn't any.
43      */

44     CodeAnalyzer codeAnalyzer;
45
46     public MethodIdentifier(ClassIdentifier clazz, MethodInfo info) {
47     super(info.getName());
48     this.name = info.getName();
49     this.type = info.getType();
50     this.clazz = clazz;
51     this.info = info;
52
53     BytecodeInfo bytecode = info.getBytecode();
54     if (bytecode != null) {
55         if ((Main.stripping & Main.STRIP_LVT) != 0)
56         info.getBytecode().setLocalVariableTable(null);
57         if ((Main.stripping & Main.STRIP_LNT) != 0)
58         info.getBytecode().setLineNumberTable(null);
59         codeAnalyzer = Main.getClassBundle().getCodeAnalyzer();
60
61         CodeTransformer[] trafos
62         = Main.getClassBundle().getPreTransformers();
63         for (int i = 0; i < trafos.length; i++) {
64         trafos[i].transformCode(bytecode);
65         }
66         info.setBytecode(bytecode);
67     }
68     }
69
70     public Iterator JavaDoc getChilds() {
71     return Collections.EMPTY_LIST.iterator();
72     }
73
74     public void setSingleReachable() {
75     super.setSingleReachable();
76     Main.getClassBundle().analyzeIdentifier(this);
77     }
78
79     public void analyze() {
80     if (GlobalOptions.verboseLevel > 1)
81         GlobalOptions.err.println("Analyze: "+this);
82
83     String JavaDoc type = getType();
84     int index = type.indexOf('L');
85     while (index != -1) {
86         int end = type.indexOf(';', index);
87         Main.getClassBundle().reachableClass
88         (type.substring(index+1, end).replace('/', '.'));
89         index = type.indexOf('L', end);
90     }
91
92     String JavaDoc[] exceptions = info.getExceptions();
93     if (exceptions != null) {
94         for (int i=0; i< exceptions.length; i++)
95         Main.getClassBundle()
96             .reachableClass(exceptions[i]);
97     }
98
99     BytecodeInfo code = info.getBytecode();
100     if (code != null)
101         codeAnalyzer.analyzeCode(this, code);
102     }
103
104     public Identifier getParent() {
105     return clazz;
106     }
107
108     public String JavaDoc getFullName() {
109     return clazz.getFullName() + "." + getName() + "." + getType();
110     }
111
112     public String JavaDoc getFullAlias() {
113     return clazz.getFullAlias() + "." + getAlias() + "."
114         + Main.getClassBundle().getTypeAlias(getType());
115     }
116
117     public String JavaDoc getName() {
118     return name;
119     }
120
121     public String JavaDoc getType() {
122     return type;
123     }
124
125     public int getModifiers() {
126     return info.getModifiers();
127     }
128
129     public boolean conflicting(String JavaDoc newAlias) {
130     return clazz.methodConflicts(this, newAlias);
131     }
132
133     public String JavaDoc toString() {
134     return "MethodIdentifier "+getFullName();
135     }
136
137     public boolean hasGlobalSideEffects() {
138     return globalSideEffects;
139     }
140
141     public boolean getLocalSideEffects(int paramNr) {
142     return globalSideEffects || localSideEffects.get(paramNr);
143     }
144
145     public void setGlobalSideEffects() {
146     globalSideEffects = true;
147     }
148
149     public void setLocalSideEffects(int paramNr) {
150     localSideEffects.set(paramNr);
151     }
152
153     /**
154      * This method does the code transformation. This include
155      * <ul><li>new slot distribution for locals</li>
156      * <li>obfuscating transformation of flow</li>
157      * <li>renaming field, method and class references</li>
158      * </ul>
159      */

160     boolean wasTransformed = false;
161     public void doTransformations() {
162     if (wasTransformed)
163         throw new jode.AssertError
164         ("doTransformation called on transformed method");
165     wasTransformed = true;
166     info.setName(getAlias());
167     ClassBundle bundle = Main.getClassBundle();
168     info.setType(bundle.getTypeAlias(type));
169     if (codeAnalyzer != null) {
170         BytecodeInfo bytecode = info.getBytecode();
171         try {
172         /* Only run analyzer on reachable methods. Other methods
173          * weren't analyzed, so running analyzer on them is wrong.
174          */

175         if (isReachable())
176             codeAnalyzer.transformCode(bytecode);
177         CodeTransformer[] trafos = bundle.getPostTransformers();
178         for (int i = 0; i < trafos.length; i++) {
179             trafos[i].transformCode(bytecode);
180         }
181         } catch (RuntimeException JavaDoc ex) {
182         ex.printStackTrace(GlobalOptions.err);
183         bytecode.dumpCode(GlobalOptions.err);
184         }
185         
186         for (Iterator JavaDoc iter = bytecode.getInstructions().iterator();
187          iter.hasNext(); ) {
188         Instruction instr = (Instruction) iter.next();
189         switch (instr.getOpcode()) {
190         case opc_invokespecial:
191         case opc_invokestatic:
192         case opc_invokeinterface:
193         case opc_invokevirtual: {
194             instr.setReference
195             (Main.getClassBundle()
196              .getReferenceAlias(instr.getReference()));
197             break;
198
199         }
200         case opc_putstatic:
201         case opc_putfield:
202         case opc_getstatic:
203         case opc_getfield: {
204             instr.setReference
205             (Main.getClassBundle()
206              .getReferenceAlias(instr.getReference()));
207             break;
208         }
209         case opc_new:
210         case opc_checkcast:
211         case opc_instanceof:
212         case opc_multianewarray: {
213             instr.setClazzType
214             (Main.getClassBundle()
215              .getTypeAlias(instr.getClazzType()));
216             break;
217         }
218         }
219         }
220     
221         Handler[] handlers = bytecode.getExceptionHandlers();
222         for (int i=0; i< handlers.length; i++) {
223         if (handlers[i].type != null) {
224             ClassIdentifier ci = Main.getClassBundle()
225             .getClassIdentifier(handlers[i].type);
226             if (ci != null)
227             handlers[i].type = ci.getFullAlias();
228         }
229         }
230         info.setBytecode(bytecode);
231     }
232
233     String JavaDoc[] exceptions = info.getExceptions();
234     if (exceptions != null) {
235         for (int i=0; i< exceptions.length; i++) {
236         ClassIdentifier ci = Main.getClassBundle()
237             .getClassIdentifier(exceptions[i]);
238         if (ci != null)
239             exceptions[i] = ci.getFullAlias();
240         }
241     }
242     }
243 }
244
Popular Tags