summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/cuchaz/enigma/Deobfuscator.java8
-rw-r--r--src/main/java/cuchaz/enigma/analysis/JarIndex.java3
-rw-r--r--src/main/java/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java78
-rw-r--r--src/main/java/cuchaz/enigma/analysis/TranslationIndex.java2
-rw-r--r--src/main/java/cuchaz/enigma/gui/Gui.java10
-rw-r--r--src/main/java/cuchaz/enigma/mapping/LocalVariableEntry.java104
-rw-r--r--src/main/java/cuchaz/enigma/mapping/Translator.java19
7 files changed, 219 insertions, 5 deletions
diff --git a/src/main/java/cuchaz/enigma/Deobfuscator.java b/src/main/java/cuchaz/enigma/Deobfuscator.java
index e9a998da..22194ad5 100644
--- a/src/main/java/cuchaz/enigma/Deobfuscator.java
+++ b/src/main/java/cuchaz/enigma/Deobfuscator.java
@@ -533,6 +533,10 @@ public class Deobfuscator {
533 return false; 533 return false;
534 } else if (obfEntry instanceof ArgumentEntry) { 534 } else if (obfEntry instanceof ArgumentEntry) {
535 return translator.translate((ArgumentEntry) obfEntry) != null; 535 return translator.translate((ArgumentEntry) obfEntry) != null;
536 } else if (obfEntry instanceof LocalVariableEntry) {
537 // TODO: Implement it
538 //return translator.translate((LocalVariableEntry)obfEntry) != null;
539 return false;
536 } else { 540 } else {
537 throw new Error("Unknown entry type: " + obfEntry.getClass().getName()); 541 throw new Error("Unknown entry type: " + obfEntry.getClass().getName());
538 } 542 }
@@ -549,6 +553,8 @@ public class Deobfuscator {
549 throw new IllegalArgumentException("Cannot rename constructors"); 553 throw new IllegalArgumentException("Cannot rename constructors");
550 } else if (obfEntry instanceof ArgumentEntry) { 554 } else if (obfEntry instanceof ArgumentEntry) {
551 this.renamer.setArgumentTreeName((ArgumentEntry) obfEntry, newName); 555 this.renamer.setArgumentTreeName((ArgumentEntry) obfEntry, newName);
556 } else if (obfEntry instanceof LocalVariableEntry) {
557 // TODO: Implement it
552 } else { 558 } else {
553 throw new Error("Unknown entry type: " + obfEntry.getClass().getName()); 559 throw new Error("Unknown entry type: " + obfEntry.getClass().getName());
554 } 560 }
@@ -587,6 +593,8 @@ public class Deobfuscator {
587 throw new IllegalArgumentException("Cannot rename constructors"); 593 throw new IllegalArgumentException("Cannot rename constructors");
588 } else if (obfEntry instanceof ArgumentEntry) { 594 } else if (obfEntry instanceof ArgumentEntry) {
589 this.renamer.markArgumentAsDeobfuscated((ArgumentEntry) obfEntry); 595 this.renamer.markArgumentAsDeobfuscated((ArgumentEntry) obfEntry);
596 } else if (obfEntry instanceof LocalVariableEntry) {
597 // TODO: Implement it
590 } else { 598 } else {
591 throw new Error("Unknown entry type: " + obfEntry); 599 throw new Error("Unknown entry type: " + obfEntry);
592 } 600 }
diff --git a/src/main/java/cuchaz/enigma/analysis/JarIndex.java b/src/main/java/cuchaz/enigma/analysis/JarIndex.java
index 619d862c..f955a408 100644
--- a/src/main/java/cuchaz/enigma/analysis/JarIndex.java
+++ b/src/main/java/cuchaz/enigma/analysis/JarIndex.java
@@ -791,6 +791,9 @@ public class JarIndex {
791 return containsObfBehavior((BehaviorEntry) obfEntry); 791 return containsObfBehavior((BehaviorEntry) obfEntry);
792 } else if (obfEntry instanceof ArgumentEntry) { 792 } else if (obfEntry instanceof ArgumentEntry) {
793 return containsObfArgument((ArgumentEntry) obfEntry); 793 return containsObfArgument((ArgumentEntry) obfEntry);
794 } else if (obfEntry instanceof LocalVariableEntry) {
795 // TODO: Implement it
796 return false;
794 } else { 797 } else {
795 throw new Error("Entry type not supported: " + obfEntry.getClass().getName()); 798 throw new Error("Entry type not supported: " + obfEntry.getClass().getName());
796 } 799 }
diff --git a/src/main/java/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java b/src/main/java/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java
index c328f5f1..e690abdf 100644
--- a/src/main/java/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java
+++ b/src/main/java/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java
@@ -10,6 +10,9 @@
10 ******************************************************************************/ 10 ******************************************************************************/
11package cuchaz.enigma.analysis; 11package cuchaz.enigma.analysis;
12 12
13import com.google.common.collect.HashMultimap;
14import com.google.common.collect.Multimap;
15import com.google.common.collect.Multimaps;
13import com.strobel.assembler.metadata.MemberReference; 16import com.strobel.assembler.metadata.MemberReference;
14import com.strobel.assembler.metadata.MethodReference; 17import com.strobel.assembler.metadata.MethodReference;
15import com.strobel.assembler.metadata.ParameterDefinition; 18import com.strobel.assembler.metadata.ParameterDefinition;
@@ -17,6 +20,7 @@ import com.strobel.assembler.metadata.TypeReference;
17import com.strobel.decompiler.languages.TextLocation; 20import com.strobel.decompiler.languages.TextLocation;
18import com.strobel.decompiler.languages.java.ast.*; 21import com.strobel.decompiler.languages.java.ast.*;
19import cuchaz.enigma.mapping.*; 22import cuchaz.enigma.mapping.*;
23import javassist.bytecode.Descriptor;
20 24
21import java.util.HashMap; 25import java.util.HashMap;
22import java.util.Map; 26import java.util.Map;
@@ -27,11 +31,14 @@ public class SourceIndexBehaviorVisitor extends SourceIndexVisitor {
27 31
28 // TODO: Really fix Procyon index problem with inner classes 32 // TODO: Really fix Procyon index problem with inner classes
29 private int argumentPosition; 33 private int argumentPosition;
30 private Map<String, Entry> argumentCache = new HashMap<>(); 34 private int localsPosition;
35 private Multimap<String, Identifier> unmatchedIdentifier = HashMultimap.create();
36 private Map<String, Entry> identifierEntryCache = new HashMap<>();
31 37
32 public SourceIndexBehaviorVisitor(BehaviorEntry behaviorEntry) { 38 public SourceIndexBehaviorVisitor(BehaviorEntry behaviorEntry) {
33 this.behaviorEntry = behaviorEntry; 39 this.behaviorEntry = behaviorEntry;
34 this.argumentPosition = 0; 40 this.argumentPosition = 0;
41 this.localsPosition = 0;
35 } 42 }
36 43
37 @Override 44 @Override
@@ -66,6 +73,9 @@ public class SourceIndexBehaviorVisitor extends SourceIndexVisitor {
66 } 73 }
67 } 74 }
68 75
76 // Check for identifier
77 node.getArguments().stream().filter(expression -> expression instanceof IdentifierExpression)
78 .forEach(expression -> this.checkIdentifier((IdentifierExpression) expression, index));
69 return recurse(node, index); 79 return recurse(node, index);
70 } 80 }
71 81
@@ -106,7 +116,7 @@ public class SourceIndexBehaviorVisitor extends SourceIndexVisitor {
106 argumentPosition++, node.getName()); 116 argumentPosition++, node.getName());
107 Identifier identifier = node.getNameToken(); 117 Identifier identifier = node.getNameToken();
108 // cache the argument entry and the identifier 118 // cache the argument entry and the identifier
109 argumentCache.put(identifier.getName(), argumentEntry); 119 identifierEntryCache.put(identifier.getName(), argumentEntry);
110 index.addDeclaration(identifier, argumentEntry); 120 index.addDeclaration(identifier, argumentEntry);
111 } 121 }
112 122
@@ -121,12 +131,31 @@ public class SourceIndexBehaviorVisitor extends SourceIndexVisitor {
121 FieldEntry fieldEntry = new FieldEntry(classEntry, ref.getName(), new Type(ref.getErasedSignature())); 131 FieldEntry fieldEntry = new FieldEntry(classEntry, ref.getName(), new Type(ref.getErasedSignature()));
122 index.addReference(node.getIdentifierToken(), fieldEntry, this.behaviorEntry); 132 index.addReference(node.getIdentifierToken(), fieldEntry, this.behaviorEntry);
123 } 133 }
124 else if (argumentCache.containsKey(node.getIdentifier())) // If it's in the argument cache, create a token! 134 else
125 index.addDeclaration(node.getIdentifierToken(), argumentCache.get(node.getIdentifier())); 135 this.checkIdentifier(node, index);
126
127 return recurse(node, index); 136 return recurse(node, index);
128 } 137 }
129 138
139 private void checkIdentifier(IdentifierExpression node, SourceIndex index)
140 {
141 if (identifierEntryCache.containsKey(node.getIdentifier())) // If it's in the argument cache, create a token!
142 index.addDeclaration(node.getIdentifierToken(), identifierEntryCache.get(node.getIdentifier()));
143 else
144 unmatchedIdentifier.put(node.getIdentifier(), node.getIdentifierToken()); // Not matched actually, put it!
145 }
146
147 private void addDeclarationToUnmatched(String key, SourceIndex index)
148 {
149 Entry entry = identifierEntryCache.get(key);
150
151 // This cannot happened in theory
152 if (entry == null)
153 return;
154 for (Identifier identifier : unmatchedIdentifier.get(key))
155 index.addDeclaration(identifier, entry);
156 unmatchedIdentifier.removeAll(key);
157 }
158
130 @Override 159 @Override
131 public Void visitObjectCreationExpression(ObjectCreationExpression node, SourceIndex index) { 160 public Void visitObjectCreationExpression(ObjectCreationExpression node, SourceIndex index) {
132 MemberReference ref = node.getUserData(Keys.MEMBER_REFERENCE); 161 MemberReference ref = node.getUserData(Keys.MEMBER_REFERENCE);
@@ -141,4 +170,43 @@ public class SourceIndexBehaviorVisitor extends SourceIndexVisitor {
141 170
142 return recurse(node, index); 171 return recurse(node, index);
143 } 172 }
173
174 @Override
175 public Void visitForEachStatement(ForEachStatement node, SourceIndex index) {
176 if (node.getVariableType() instanceof SimpleType)
177 {
178 SimpleType type = (SimpleType) node.getVariableType();
179 TypeReference typeReference = type.getUserData(Keys.TYPE_REFERENCE);
180 Identifier identifier = node.getVariableNameToken();
181 String signature = Descriptor.of(typeReference.getErasedDescription());
182 LocalVariableEntry localVariableEntry = new LocalVariableEntry(behaviorEntry, localsPosition++, identifier.getName(), new Type(signature));
183 identifierEntryCache.put(identifier.getName(), localVariableEntry);
184 addDeclarationToUnmatched(identifier.getName(), index);
185 index.addDeclaration(identifier, localVariableEntry);
186 }
187 return recurse(node, index);
188 }
189
190 @Override
191 public Void visitVariableDeclaration(VariableDeclarationStatement node, SourceIndex index) {
192 AstNodeCollection<VariableInitializer> variables = node.getVariables();
193
194 // Single assignation
195 if (variables.size() == 1)
196 {
197 VariableInitializer initializer = variables.firstOrNullObject();
198 if (initializer != null && node.getType() instanceof SimpleType)
199 {
200 SimpleType type = (SimpleType) node.getType();
201 TypeReference typeReference = type.getUserData(Keys.TYPE_REFERENCE);
202 String signature = Descriptor.of(typeReference.getErasedDescription());
203 Identifier identifier = initializer.getNameToken();
204 LocalVariableEntry localVariableEntry = new LocalVariableEntry(behaviorEntry, localsPosition++, initializer.getName(), new Type(signature));
205 identifierEntryCache.put(identifier.getName(), localVariableEntry);
206 addDeclarationToUnmatched(identifier.getName(), index);
207 index.addDeclaration(identifier, localVariableEntry);
208 }
209 }
210 return recurse(node, index);
211 }
144} 212}
diff --git a/src/main/java/cuchaz/enigma/analysis/TranslationIndex.java b/src/main/java/cuchaz/enigma/analysis/TranslationIndex.java
index 25edaef4..d51131f6 100644
--- a/src/main/java/cuchaz/enigma/analysis/TranslationIndex.java
+++ b/src/main/java/cuchaz/enigma/analysis/TranslationIndex.java
@@ -181,6 +181,8 @@ public class TranslationIndex {
181 return behaviorExists((BehaviorEntry) entry); 181 return behaviorExists((BehaviorEntry) entry);
182 } else if (entry instanceof ArgumentEntry) { 182 } else if (entry instanceof ArgumentEntry) {
183 return behaviorExists(((ArgumentEntry) entry).getBehaviorEntry()); 183 return behaviorExists(((ArgumentEntry) entry).getBehaviorEntry());
184 } else if (entry instanceof LocalVariableEntry) {
185 return behaviorExists(((LocalVariableEntry) entry).getBehaviorEntry());
184 } 186 }
185 throw new IllegalArgumentException("Cannot check existence for " + entry.getClass()); 187 throw new IllegalArgumentException("Cannot check existence for " + entry.getClass());
186 } 188 }
diff --git a/src/main/java/cuchaz/enigma/gui/Gui.java b/src/main/java/cuchaz/enigma/gui/Gui.java
index d3f74060..2a355075 100644
--- a/src/main/java/cuchaz/enigma/gui/Gui.java
+++ b/src/main/java/cuchaz/enigma/gui/Gui.java
@@ -442,6 +442,8 @@ public class Gui {
442 showConstructorEntry((ConstructorEntry) m_reference.entry); 442 showConstructorEntry((ConstructorEntry) m_reference.entry);
443 } else if (m_reference.entry instanceof ArgumentEntry) { 443 } else if (m_reference.entry instanceof ArgumentEntry) {
444 showArgumentEntry((ArgumentEntry) m_reference.entry); 444 showArgumentEntry((ArgumentEntry) m_reference.entry);
445 } else if (m_reference.entry instanceof LocalVariableEntry) {
446 showLocalVariableEntry((LocalVariableEntry) m_reference.entry);
445 } else { 447 } else {
446 throw new Error("Unknown entry type: " + m_reference.entry.getClass().getName()); 448 throw new Error("Unknown entry type: " + m_reference.entry.getClass().getName());
447 } 449 }
@@ -449,6 +451,14 @@ public class Gui {
449 redraw(); 451 redraw();
450 } 452 }
451 453
454 private void showLocalVariableEntry(LocalVariableEntry entry) {
455 addNameValue(m_infoPanel, "Variable", entry.getName());
456 addNameValue(m_infoPanel, "Class", entry.getClassEntry().getName());
457 addNameValue(m_infoPanel, "Method", entry.getBehaviorEntry().getName());
458 addNameValue(m_infoPanel, "Index", Integer.toString(entry.getIndex()));
459 addNameValue(m_infoPanel, "Type", entry.getType().toString());
460 }
461
452 private void showClassEntry(ClassEntry entry) { 462 private void showClassEntry(ClassEntry entry) {
453 addNameValue(m_infoPanel, "Class", entry.getName()); 463 addNameValue(m_infoPanel, "Class", entry.getName());
454 } 464 }
diff --git a/src/main/java/cuchaz/enigma/mapping/LocalVariableEntry.java b/src/main/java/cuchaz/enigma/mapping/LocalVariableEntry.java
new file mode 100644
index 00000000..8bbaaaf6
--- /dev/null
+++ b/src/main/java/cuchaz/enigma/mapping/LocalVariableEntry.java
@@ -0,0 +1,104 @@
1package cuchaz.enigma.mapping;
2
3import cuchaz.enigma.utils.Utils;
4
5/**
6 * Desc...
7 * Created by Thog
8 * 19/10/2016
9 */
10public class LocalVariableEntry implements Entry
11{
12
13 protected final BehaviorEntry behaviorEntry;
14 protected final String name;
15 protected final Type type;
16 protected final int index;
17
18 public LocalVariableEntry(BehaviorEntry behaviorEntry, int index, String name, Type type) {
19 if (behaviorEntry == null) {
20 throw new IllegalArgumentException("Behavior cannot be null!");
21 }
22 if (index < 0) {
23 throw new IllegalArgumentException("Index must be non-negative!");
24 }
25 if (name == null) {
26 throw new IllegalArgumentException("Variable name cannot be null!");
27 }
28 if (type == null) {
29 throw new IllegalArgumentException("Variable type cannot be null!");
30 }
31
32 this.behaviorEntry = behaviorEntry;
33 this.name = name;
34 this.type = type;
35 this.index = index;
36 }
37
38
39 public LocalVariableEntry(LocalVariableEntry other, ClassEntry newClassEntry) {
40 this.behaviorEntry = (BehaviorEntry) other.behaviorEntry.cloneToNewClass(newClassEntry);
41 this.name = other.name;
42 this.type = other.type;
43 this.index = other.index;
44 }
45
46 public BehaviorEntry getBehaviorEntry() {
47 return this.behaviorEntry;
48 }
49
50 public Type getType() {
51 return type;
52 }
53
54 public int getIndex() {
55 return index;
56 }
57
58 @Override
59 public String getName() {
60 return this.name;
61 }
62
63 @Override
64 public ClassEntry getClassEntry() {
65 return this.behaviorEntry.getClassEntry();
66 }
67
68 @Override
69 public String getClassName() {
70 return this.behaviorEntry.getClassName();
71 }
72
73 @Override
74 public LocalVariableEntry cloneToNewClass(ClassEntry classEntry) {
75 return new LocalVariableEntry(this, classEntry);
76 }
77
78 public String getMethodName() {
79 return this.behaviorEntry.getName();
80 }
81
82 public Signature getMethodSignature() {
83 return this.behaviorEntry.getSignature();
84 }
85
86 @Override
87 public int hashCode() {
88 return Utils.combineHashesOrdered(this.behaviorEntry, this.type.hashCode(), this.name.hashCode(), Integer.hashCode(this.index));
89 }
90
91 @Override
92 public boolean equals(Object other) {
93 return other instanceof LocalVariableEntry && equals((LocalVariableEntry) other);
94 }
95
96 public boolean equals(LocalVariableEntry other) {
97 return this.behaviorEntry.equals(other.behaviorEntry) && this.type.equals(other.type) && this.name.equals(other.name) && this.index == other.index;
98 }
99
100 @Override
101 public String toString() {
102 return this.behaviorEntry.toString() + "(" + this.index + ":" + this.name + ":" + this.type + ")";
103 }
104}
diff --git a/src/main/java/cuchaz/enigma/mapping/Translator.java b/src/main/java/cuchaz/enigma/mapping/Translator.java
index b05714cc..6b636f2f 100644
--- a/src/main/java/cuchaz/enigma/mapping/Translator.java
+++ b/src/main/java/cuchaz/enigma/mapping/Translator.java
@@ -58,6 +58,8 @@ public class Translator {
58 return (T) translateEntry((ConstructorEntry) entry); 58 return (T) translateEntry((ConstructorEntry) entry);
59 } else if (entry instanceof ArgumentEntry) { 59 } else if (entry instanceof ArgumentEntry) {
60 return (T) translateEntry((ArgumentEntry) entry); 60 return (T) translateEntry((ArgumentEntry) entry);
61 } else if (entry instanceof LocalVariableEntry) {
62 return (T) translateEntry((LocalVariableEntry) entry);
61 } else { 63 } else {
62 throw new Error("Unknown entry type: " + entry.getClass().getName()); 64 throw new Error("Unknown entry type: " + entry.getClass().getName());
63 } 65 }
@@ -74,11 +76,28 @@ public class Translator {
74 return translate(entry); 76 return translate(entry);
75 } else if (entry instanceof ArgumentEntry) { 77 } else if (entry instanceof ArgumentEntry) {
76 return translate((ArgumentEntry) entry); 78 return translate((ArgumentEntry) entry);
79 } else if (entry instanceof LocalVariableEntry) {
80 return translate((LocalVariableEntry) entry);
77 } else { 81 } else {
78 throw new Error("Unknown entry type: " + entry.getClass().getName()); 82 throw new Error("Unknown entry type: " + entry.getClass().getName());
79 } 83 }
80 } 84 }
81 85
86 public String translate(LocalVariableEntry in)
87 {
88 LocalVariableEntry translated = translateEntry(in);
89 if (translated.equals(in)) {
90 return null;
91 }
92 return translated.getName();
93 }
94
95 public LocalVariableEntry translateEntry(LocalVariableEntry in)
96 {
97 // TODO: Implement it
98 return in;
99 }
100
82 public String translate(ClassEntry in) { 101 public String translate(ClassEntry in) {
83 ClassEntry translated = translateEntry(in); 102 ClassEntry translated = translateEntry(in);
84 if (translated.equals(in)) { 103 if (translated.equals(in)) {