summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/analysis/JarIndex.java
diff options
context:
space:
mode:
authorGravatar jeff2015-02-10 22:10:16 -0500
committerGravatar jeff2015-02-10 22:10:16 -0500
commit2b3c5c52865b40adfa93910d41738242f17338d4 (patch)
tree4c1006dea9ad830ef6bacbaa230a086c23dae883 /src/cuchaz/enigma/analysis/JarIndex.java
parentwork around bad tokens generated by procyon for now (diff)
downloadenigma-fork-2b3c5c52865b40adfa93910d41738242f17338d4.tar.gz
enigma-fork-2b3c5c52865b40adfa93910d41738242f17338d4.tar.xz
enigma-fork-2b3c5c52865b40adfa93910d41738242f17338d4.zip
add BRIDGE flag to bridge methods
Diffstat (limited to 'src/cuchaz/enigma/analysis/JarIndex.java')
-rw-r--r--src/cuchaz/enigma/analysis/JarIndex.java55
1 files changed, 55 insertions, 0 deletions
diff --git a/src/cuchaz/enigma/analysis/JarIndex.java b/src/cuchaz/enigma/analysis/JarIndex.java
index 24d110e..797deb8 100644
--- a/src/cuchaz/enigma/analysis/JarIndex.java
+++ b/src/cuchaz/enigma/analysis/JarIndex.java
@@ -23,6 +23,8 @@ import javassist.CtBehavior;
23import javassist.CtClass; 23import javassist.CtClass;
24import javassist.CtConstructor; 24import javassist.CtConstructor;
25import javassist.CtField; 25import javassist.CtField;
26import javassist.CtMethod;
27import javassist.NotFoundException;
26import javassist.bytecode.AccessFlag; 28import javassist.bytecode.AccessFlag;
27import javassist.bytecode.Descriptor; 29import javassist.bytecode.Descriptor;
28import javassist.bytecode.FieldInfo; 30import javassist.bytecode.FieldInfo;
@@ -32,6 +34,8 @@ import javassist.expr.FieldAccess;
32import javassist.expr.MethodCall; 34import javassist.expr.MethodCall;
33import javassist.expr.NewExpr; 35import javassist.expr.NewExpr;
34 36
37import com.google.common.collect.BiMap;
38import com.google.common.collect.HashBiMap;
35import com.google.common.collect.HashMultimap; 39import com.google.common.collect.HashMultimap;
36import com.google.common.collect.Lists; 40import com.google.common.collect.Lists;
37import com.google.common.collect.Maps; 41import com.google.common.collect.Maps;
@@ -62,6 +66,7 @@ public class JarIndex {
62 private Multimap<String,String> m_innerClasses; 66 private Multimap<String,String> m_innerClasses;
63 private Map<String,String> m_outerClasses; 67 private Map<String,String> m_outerClasses;
64 private Map<String,BehaviorEntry> m_anonymousClasses; 68 private Map<String,BehaviorEntry> m_anonymousClasses;
69 private BiMap<MethodEntry,MethodEntry> m_bridgedMethods;
65 70
66 public JarIndex() { 71 public JarIndex() {
67 m_obfClassEntries = Sets.newHashSet(); 72 m_obfClassEntries = Sets.newHashSet();
@@ -74,6 +79,7 @@ public class JarIndex {
74 m_innerClasses = HashMultimap.create(); 79 m_innerClasses = HashMultimap.create();
75 m_outerClasses = Maps.newHashMap(); 80 m_outerClasses = Maps.newHashMap();
76 m_anonymousClasses = Maps.newHashMap(); 81 m_anonymousClasses = Maps.newHashMap();
82 m_bridgedMethods = HashBiMap.create();
77 } 83 }
78 84
79 public void indexJar(JarFile jar, boolean buildInnerClasses) { 85 public void indexJar(JarFile jar, boolean buildInnerClasses) {
@@ -171,6 +177,12 @@ public class JarIndex {
171 177
172 // index implementation 178 // index implementation
173 m_methodImplementations.put(behaviorEntry.getClassName(), methodEntry); 179 m_methodImplementations.put(behaviorEntry.getClassName(), methodEntry);
180
181 // look for bridge and bridged methods
182 CtMethod bridgedMethod = getBridgedMethod((CtMethod)behavior);
183 if (bridgedMethod != null) {
184 m_bridgedMethods.put(methodEntry, EntryFactory.getMethodEntry(bridgedMethod));
185 }
174 } 186 }
175 // looks like we don't care about constructors here 187 // looks like we don't care about constructors here
176 } 188 }
@@ -241,6 +253,45 @@ public class JarIndex {
241 } 253 }
242 } 254 }
243 255
256 private CtMethod getBridgedMethod(CtMethod method) {
257
258 // bridge methods just call another method, cast it to the return type, and return the result
259 // let's see if we can detect this scenario
260
261 // skip non-synthetic methods
262 if ((method.getModifiers() & AccessFlag.SYNTHETIC) == 0) {
263 return null;
264 }
265
266 // get all the called methods
267 final List<MethodCall> methodCalls = Lists.newArrayList();
268 try {
269 method.instrument(new ExprEditor() {
270 @Override
271 public void edit(MethodCall call) {
272 methodCalls.add(call);
273 }
274 });
275 } catch (CannotCompileException ex) {
276 // this is stupid... we're not even compiling anything
277 throw new Error(ex);
278 }
279
280 // is there just one?
281 if (methodCalls.size() != 1) {
282 return null;
283 }
284 MethodCall call = methodCalls.get(0);
285
286 try {
287 // we have a bridge method!
288 return call.getMethod();
289 } catch (NotFoundException ex) {
290 // can't find the type? not a bridge method
291 return null;
292 }
293 }
294
244 private String findOuterClass(CtClass c) { 295 private String findOuterClass(CtClass c) {
245 296
246 // inner classes: 297 // inner classes:
@@ -706,4 +757,8 @@ public class JarIndex {
706 throw new Error("Entry type not supported: " + obfEntry.getClass().getName()); 757 throw new Error("Entry type not supported: " + obfEntry.getClass().getName());
707 } 758 }
708 } 759 }
760
761 public BiMap<MethodEntry,MethodEntry> getBridgedMethods() {
762 return m_bridgedMethods;
763 }
709} 764}