summaryrefslogtreecommitdiff
path: root/src
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
parentwork around bad tokens generated by procyon for now (diff)
downloadenigma-2b3c5c52865b40adfa93910d41738242f17338d4.tar.gz
enigma-2b3c5c52865b40adfa93910d41738242f17338d4.tar.xz
enigma-2b3c5c52865b40adfa93910d41738242f17338d4.zip
add BRIDGE flag to bridge methods
Diffstat (limited to 'src')
-rw-r--r--src/cuchaz/enigma/TranslatingTypeLoader.java2
-rw-r--r--src/cuchaz/enigma/analysis/BridgeMarker.java36
-rw-r--r--src/cuchaz/enigma/analysis/JarIndex.java55
3 files changed, 93 insertions, 0 deletions
diff --git a/src/cuchaz/enigma/TranslatingTypeLoader.java b/src/cuchaz/enigma/TranslatingTypeLoader.java
index 8bec17fb..19e3d2ad 100644
--- a/src/cuchaz/enigma/TranslatingTypeLoader.java
+++ b/src/cuchaz/enigma/TranslatingTypeLoader.java
@@ -29,6 +29,7 @@ import com.strobel.assembler.metadata.Buffer;
29import com.strobel.assembler.metadata.ClasspathTypeLoader; 29import com.strobel.assembler.metadata.ClasspathTypeLoader;
30import com.strobel.assembler.metadata.ITypeLoader; 30import com.strobel.assembler.metadata.ITypeLoader;
31 31
32import cuchaz.enigma.analysis.BridgeMarker;
32import cuchaz.enigma.analysis.JarIndex; 33import cuchaz.enigma.analysis.JarIndex;
33import cuchaz.enigma.bytecode.ClassRenamer; 34import cuchaz.enigma.bytecode.ClassRenamer;
34import cuchaz.enigma.bytecode.ClassTranslator; 35import cuchaz.enigma.bytecode.ClassTranslator;
@@ -198,6 +199,7 @@ public class TranslatingTypeLoader implements ITypeLoader {
198 assertClassName(c, obfClassEntry); 199 assertClassName(c, obfClassEntry);
199 200
200 // do all kinds of deobfuscating transformations on the class 201 // do all kinds of deobfuscating transformations on the class
202 new BridgeMarker(m_jarIndex.getBridgedMethods()).markBridges(c);
201 new MethodParameterWriter(m_deobfuscatingTranslator).writeMethodArguments(c); 203 new MethodParameterWriter(m_deobfuscatingTranslator).writeMethodArguments(c);
202 new ClassTranslator(m_deobfuscatingTranslator).translate(c); 204 new ClassTranslator(m_deobfuscatingTranslator).translate(c);
203 205
diff --git a/src/cuchaz/enigma/analysis/BridgeMarker.java b/src/cuchaz/enigma/analysis/BridgeMarker.java
new file mode 100644
index 00000000..e80f87dc
--- /dev/null
+++ b/src/cuchaz/enigma/analysis/BridgeMarker.java
@@ -0,0 +1,36 @@
1package cuchaz.enigma.analysis;
2
3import javassist.CtClass;
4import javassist.CtMethod;
5import javassist.bytecode.AccessFlag;
6
7import com.google.common.collect.BiMap;
8
9import cuchaz.enigma.mapping.EntryFactory;
10import cuchaz.enigma.mapping.MethodEntry;
11
12public class BridgeMarker {
13
14 private BiMap<MethodEntry,MethodEntry> m_bridgedMethods;
15
16 public BridgeMarker(BiMap<MethodEntry,MethodEntry> bridgedMethods) {
17 m_bridgedMethods = bridgedMethods;
18 }
19
20 public void markBridges(CtClass c) {
21
22 for (CtMethod method : c.getDeclaredMethods()) {
23 MethodEntry methodEntry = EntryFactory.getMethodEntry(method);
24
25 // is this a bridge method?
26 MethodEntry bridgedMethodEntry = m_bridgedMethods.get(methodEntry);
27 if (bridgedMethodEntry != null) {
28
29 // it's a bridge method! add the bridge flag
30 int flags = method.getMethodInfo().getAccessFlags();
31 flags |= AccessFlag.BRIDGE;
32 method.getMethodInfo().setAccessFlags(flags);
33 }
34 }
35 }
36}
diff --git a/src/cuchaz/enigma/analysis/JarIndex.java b/src/cuchaz/enigma/analysis/JarIndex.java
index 24d110ee..797deb82 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}