diff options
| author | 2015-02-10 22:10:16 -0500 | |
|---|---|---|
| committer | 2015-02-10 22:10:16 -0500 | |
| commit | 2b3c5c52865b40adfa93910d41738242f17338d4 (patch) | |
| tree | 4c1006dea9ad830ef6bacbaa230a086c23dae883 /src/cuchaz/enigma/analysis/JarIndex.java | |
| parent | work around bad tokens generated by procyon for now (diff) | |
| download | enigma-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.java | 55 |
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; | |||
| 23 | import javassist.CtClass; | 23 | import javassist.CtClass; |
| 24 | import javassist.CtConstructor; | 24 | import javassist.CtConstructor; |
| 25 | import javassist.CtField; | 25 | import javassist.CtField; |
| 26 | import javassist.CtMethod; | ||
| 27 | import javassist.NotFoundException; | ||
| 26 | import javassist.bytecode.AccessFlag; | 28 | import javassist.bytecode.AccessFlag; |
| 27 | import javassist.bytecode.Descriptor; | 29 | import javassist.bytecode.Descriptor; |
| 28 | import javassist.bytecode.FieldInfo; | 30 | import javassist.bytecode.FieldInfo; |
| @@ -32,6 +34,8 @@ import javassist.expr.FieldAccess; | |||
| 32 | import javassist.expr.MethodCall; | 34 | import javassist.expr.MethodCall; |
| 33 | import javassist.expr.NewExpr; | 35 | import javassist.expr.NewExpr; |
| 34 | 36 | ||
| 37 | import com.google.common.collect.BiMap; | ||
| 38 | import com.google.common.collect.HashBiMap; | ||
| 35 | import com.google.common.collect.HashMultimap; | 39 | import com.google.common.collect.HashMultimap; |
| 36 | import com.google.common.collect.Lists; | 40 | import com.google.common.collect.Lists; |
| 37 | import com.google.common.collect.Maps; | 41 | import 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 | } |