diff options
| author | 2014-08-21 01:10:37 -0400 | |
|---|---|---|
| committer | 2014-08-21 01:10:37 -0400 | |
| commit | 237b2ed2a6b6f537cdbdf9fc9c6d0c7743f34375 (patch) | |
| tree | ebad059c7fa0bc7723858cb25eed0bb6e95fe42a | |
| parent | fixed recognition of inner class tokens (diff) | |
| download | enigma-fork-237b2ed2a6b6f537cdbdf9fc9c6d0c7743f34375.tar.gz enigma-fork-237b2ed2a6b6f537cdbdf9fc9c6d0c7743f34375.tar.xz enigma-fork-237b2ed2a6b6f537cdbdf9fc9c6d0c7743f34375.zip | |
fixed call graph searching
added system to navigate multiple tokens for the same entry in a behavior
| -rw-r--r-- | src/cuchaz/enigma/Deobfuscator.java | 18 | ||||
| -rw-r--r-- | src/cuchaz/enigma/analysis/EntryReference.java | 13 | ||||
| -rw-r--r-- | src/cuchaz/enigma/analysis/JarIndex.java | 30 | ||||
| -rw-r--r-- | src/cuchaz/enigma/analysis/SourceIndex.java | 37 | ||||
| -rw-r--r-- | src/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java | 16 | ||||
| -rw-r--r-- | src/cuchaz/enigma/analysis/SourceIndexClassVisitor.java | 23 | ||||
| -rw-r--r-- | src/cuchaz/enigma/gui/Gui.java | 53 | ||||
| -rw-r--r-- | src/cuchaz/enigma/gui/GuiController.java | 75 | ||||
| -rw-r--r-- | src/cuchaz/enigma/gui/ReadableToken.java | 38 | ||||
| -rw-r--r-- | src/cuchaz/enigma/gui/TokenListCellRenderer.java | 40 | ||||
| -rw-r--r-- | src/cuchaz/enigma/mapping/ConstructorEntry.java | 54 | ||||
| -rw-r--r-- | src/cuchaz/enigma/mapping/Translator.java | 28 |
12 files changed, 302 insertions, 123 deletions
diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java index 34e6033..a5feaa9 100644 --- a/src/cuchaz/enigma/Deobfuscator.java +++ b/src/cuchaz/enigma/Deobfuscator.java | |||
| @@ -181,7 +181,7 @@ public class Deobfuscator | |||
| 181 | return index; | 181 | return index; |
| 182 | } | 182 | } |
| 183 | 183 | ||
| 184 | public Entry obfuscateEntry( Entry deobfEntry ) | 184 | public <T extends Entry> T obfuscateEntry( T deobfEntry ) |
| 185 | { | 185 | { |
| 186 | if( deobfEntry == null ) | 186 | if( deobfEntry == null ) |
| 187 | { | 187 | { |
| @@ -190,7 +190,7 @@ public class Deobfuscator | |||
| 190 | return getTranslator( TranslationDirection.Obfuscating ).translateEntry( deobfEntry ); | 190 | return getTranslator( TranslationDirection.Obfuscating ).translateEntry( deobfEntry ); |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | public Entry deobfuscateEntry( Entry obfEntry ) | 193 | public <T extends Entry> T deobfuscateEntry( T obfEntry ) |
| 194 | { | 194 | { |
| 195 | if( obfEntry == null ) | 195 | if( obfEntry == null ) |
| 196 | { | 196 | { |
| @@ -199,29 +199,27 @@ public class Deobfuscator | |||
| 199 | return getTranslator( TranslationDirection.Deobfuscating ).translateEntry( obfEntry ); | 199 | return getTranslator( TranslationDirection.Deobfuscating ).translateEntry( obfEntry ); |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | public EntryReference<Entry,Entry> obfuscateReference( EntryReference<Entry,Entry> deobfReference ) | 202 | public <E extends Entry,C extends Entry> EntryReference<E,C> obfuscateReference( EntryReference<E,C> deobfReference ) |
| 203 | { | 203 | { |
| 204 | if( deobfReference == null ) | 204 | if( deobfReference == null ) |
| 205 | { | 205 | { |
| 206 | return null; | 206 | return null; |
| 207 | } | 207 | } |
| 208 | return new EntryReference<Entry,Entry>( | 208 | return new EntryReference<E,C>( |
| 209 | obfuscateEntry( deobfReference.entry ), | 209 | obfuscateEntry( deobfReference.entry ), |
| 210 | obfuscateEntry( deobfReference.context ), | 210 | obfuscateEntry( deobfReference.context ) |
| 211 | deobfReference.pos | ||
| 212 | ); | 211 | ); |
| 213 | } | 212 | } |
| 214 | 213 | ||
| 215 | public EntryReference<Entry,Entry> deobfuscateReference( EntryReference<Entry,Entry> obfReference ) | 214 | public <E extends Entry,C extends Entry> EntryReference<E,C> deobfuscateReference( EntryReference<E,C> obfReference ) |
| 216 | { | 215 | { |
| 217 | if( obfReference == null ) | 216 | if( obfReference == null ) |
| 218 | { | 217 | { |
| 219 | return null; | 218 | return null; |
| 220 | } | 219 | } |
| 221 | return new EntryReference<Entry,Entry>( | 220 | return new EntryReference<E,C>( |
| 222 | deobfuscateEntry( obfReference.entry ), | 221 | deobfuscateEntry( obfReference.entry ), |
| 223 | deobfuscateEntry( obfReference.context ), | 222 | deobfuscateEntry( obfReference.context ) |
| 224 | obfReference.pos | ||
| 225 | ); | 223 | ); |
| 226 | } | 224 | } |
| 227 | 225 | ||
diff --git a/src/cuchaz/enigma/analysis/EntryReference.java b/src/cuchaz/enigma/analysis/EntryReference.java index 869e08c..768c113 100644 --- a/src/cuchaz/enigma/analysis/EntryReference.java +++ b/src/cuchaz/enigma/analysis/EntryReference.java | |||
| @@ -18,14 +18,13 @@ public class EntryReference<E extends Entry, C extends Entry> | |||
| 18 | { | 18 | { |
| 19 | public E entry; | 19 | public E entry; |
| 20 | public C context; | 20 | public C context; |
| 21 | public int pos; | ||
| 22 | 21 | ||
| 23 | public EntryReference( E entry ) | 22 | public EntryReference( E entry ) |
| 24 | { | 23 | { |
| 25 | this( entry, null, -1 ); | 24 | this( entry, null ); |
| 26 | } | 25 | } |
| 27 | 26 | ||
| 28 | public EntryReference( E entry, C context, int pos ) | 27 | public EntryReference( E entry, C context ) |
| 29 | { | 28 | { |
| 30 | if( entry == null ) | 29 | if( entry == null ) |
| 31 | { | 30 | { |
| @@ -34,7 +33,6 @@ public class EntryReference<E extends Entry, C extends Entry> | |||
| 34 | 33 | ||
| 35 | this.entry = entry; | 34 | this.entry = entry; |
| 36 | this.context = context; | 35 | this.context = context; |
| 37 | this.pos = pos; | ||
| 38 | } | 36 | } |
| 39 | 37 | ||
| 40 | public ClassEntry getClassEntry( ) | 38 | public ClassEntry getClassEntry( ) |
| @@ -51,7 +49,7 @@ public class EntryReference<E extends Entry, C extends Entry> | |||
| 51 | { | 49 | { |
| 52 | if( context != null ) | 50 | if( context != null ) |
| 53 | { | 51 | { |
| 54 | return Util.combineHashesOrdered( entry.hashCode(), context.hashCode(), Integer.valueOf( pos ).hashCode() ); | 52 | return Util.combineHashesOrdered( entry.hashCode(), context.hashCode() ); |
| 55 | } | 53 | } |
| 56 | return entry.hashCode(); | 54 | return entry.hashCode(); |
| 57 | } | 55 | } |
| @@ -82,7 +80,7 @@ public class EntryReference<E extends Entry, C extends Entry> | |||
| 82 | } | 80 | } |
| 83 | else if( context != null && other.context != null ) | 81 | else if( context != null && other.context != null ) |
| 84 | { | 82 | { |
| 85 | return context.equals( other.context ) && pos == other.pos; | 83 | return context.equals( other.context ); |
| 86 | } | 84 | } |
| 87 | return false; | 85 | return false; |
| 88 | } | 86 | } |
| @@ -96,9 +94,6 @@ public class EntryReference<E extends Entry, C extends Entry> | |||
| 96 | { | 94 | { |
| 97 | buf.append( " called from " ); | 95 | buf.append( " called from " ); |
| 98 | buf.append( context ); | 96 | buf.append( context ); |
| 99 | buf.append( " (" ); | ||
| 100 | buf.append( pos ); | ||
| 101 | buf.append( ")" ); | ||
| 102 | } | 97 | } |
| 103 | return buf.toString(); | 98 | return buf.toString(); |
| 104 | } | 99 | } |
diff --git a/src/cuchaz/enigma/analysis/JarIndex.java b/src/cuchaz/enigma/analysis/JarIndex.java index f408d93..315a286 100644 --- a/src/cuchaz/enigma/analysis/JarIndex.java +++ b/src/cuchaz/enigma/analysis/JarIndex.java | |||
| @@ -146,10 +146,15 @@ public class JarIndex | |||
| 146 | } | 146 | } |
| 147 | else if( behavior instanceof CtConstructor ) | 147 | else if( behavior instanceof CtConstructor ) |
| 148 | { | 148 | { |
| 149 | thisEntry = new ConstructorEntry( | 149 | boolean isStatic = behavior.getName().equals( "<clinit>" ); |
| 150 | new ClassEntry( className ), | 150 | if( isStatic ) |
| 151 | behavior.getSignature() | 151 | { |
| 152 | ); | 152 | thisEntry = new ConstructorEntry( new ClassEntry( className ) ); |
| 153 | } | ||
| 154 | else | ||
| 155 | { | ||
| 156 | thisEntry = new ConstructorEntry( new ClassEntry( className ), behavior.getSignature() ); | ||
| 157 | } | ||
| 153 | } | 158 | } |
| 154 | else | 159 | else |
| 155 | { | 160 | { |
| @@ -159,7 +164,6 @@ public class JarIndex | |||
| 159 | // index method calls | 164 | // index method calls |
| 160 | try | 165 | try |
| 161 | { | 166 | { |
| 162 | final Multiset<Entry> callNumbers = HashMultiset.create(); | ||
| 163 | behavior.instrument( new ExprEditor( ) | 167 | behavior.instrument( new ExprEditor( ) |
| 164 | { | 168 | { |
| 165 | @Override | 169 | @Override |
| @@ -171,11 +175,9 @@ public class JarIndex | |||
| 171 | call.getMethodName(), | 175 | call.getMethodName(), |
| 172 | call.getSignature() | 176 | call.getSignature() |
| 173 | ); | 177 | ); |
| 174 | callNumbers.add( calledMethodEntry ); | ||
| 175 | EntryReference<BehaviorEntry,BehaviorEntry> reference = new EntryReference<BehaviorEntry,BehaviorEntry>( | 178 | EntryReference<BehaviorEntry,BehaviorEntry> reference = new EntryReference<BehaviorEntry,BehaviorEntry>( |
| 176 | calledMethodEntry, | 179 | calledMethodEntry, |
| 177 | thisEntry, | 180 | thisEntry |
| 178 | callNumbers.count( calledMethodEntry ) - 1 | ||
| 179 | ); | 181 | ); |
| 180 | m_behaviorReferences.put( calledMethodEntry, reference ); | 182 | m_behaviorReferences.put( calledMethodEntry, reference ); |
| 181 | } | 183 | } |
| @@ -188,11 +190,9 @@ public class JarIndex | |||
| 188 | new ClassEntry( className ), | 190 | new ClassEntry( className ), |
| 189 | call.getFieldName() | 191 | call.getFieldName() |
| 190 | ); | 192 | ); |
| 191 | callNumbers.add( calledFieldEntry ); | ||
| 192 | EntryReference<FieldEntry,BehaviorEntry> reference = new EntryReference<FieldEntry,BehaviorEntry>( | 193 | EntryReference<FieldEntry,BehaviorEntry> reference = new EntryReference<FieldEntry,BehaviorEntry>( |
| 193 | calledFieldEntry, | 194 | calledFieldEntry, |
| 194 | thisEntry, | 195 | thisEntry |
| 195 | callNumbers.count( calledFieldEntry ) - 1 | ||
| 196 | ); | 196 | ); |
| 197 | m_fieldReferences.put( calledFieldEntry, reference ); | 197 | m_fieldReferences.put( calledFieldEntry, reference ); |
| 198 | } | 198 | } |
| @@ -208,11 +208,9 @@ public class JarIndex | |||
| 208 | new ClassEntry( className ), | 208 | new ClassEntry( className ), |
| 209 | call.getSignature() | 209 | call.getSignature() |
| 210 | ); | 210 | ); |
| 211 | callNumbers.add( calledConstructorEntry ); | ||
| 212 | EntryReference<BehaviorEntry,BehaviorEntry> reference = new EntryReference<BehaviorEntry,BehaviorEntry>( | 211 | EntryReference<BehaviorEntry,BehaviorEntry> reference = new EntryReference<BehaviorEntry,BehaviorEntry>( |
| 213 | calledConstructorEntry, | 212 | calledConstructorEntry, |
| 214 | thisEntry, | 213 | thisEntry |
| 215 | callNumbers.count( calledConstructorEntry ) - 1 | ||
| 216 | ); | 214 | ); |
| 217 | m_behaviorReferences.put( calledConstructorEntry, reference ); | 215 | m_behaviorReferences.put( calledConstructorEntry, reference ); |
| 218 | } | 216 | } |
| @@ -225,11 +223,9 @@ public class JarIndex | |||
| 225 | new ClassEntry( className ), | 223 | new ClassEntry( className ), |
| 226 | call.getSignature() | 224 | call.getSignature() |
| 227 | ); | 225 | ); |
| 228 | callNumbers.add( calledConstructorEntry ); | ||
| 229 | EntryReference<BehaviorEntry,BehaviorEntry> reference = new EntryReference<BehaviorEntry,BehaviorEntry>( | 226 | EntryReference<BehaviorEntry,BehaviorEntry> reference = new EntryReference<BehaviorEntry,BehaviorEntry>( |
| 230 | calledConstructorEntry, | 227 | calledConstructorEntry, |
| 231 | thisEntry, | 228 | thisEntry |
| 232 | callNumbers.count( calledConstructorEntry ) - 1 | ||
| 233 | ); | 229 | ); |
| 234 | m_behaviorReferences.put( calledConstructorEntry, reference ); | 230 | m_behaviorReferences.put( calledConstructorEntry, reference ); |
| 235 | } | 231 | } |
diff --git a/src/cuchaz/enigma/analysis/SourceIndex.java b/src/cuchaz/enigma/analysis/SourceIndex.java index bf890e3..960ec36 100644 --- a/src/cuchaz/enigma/analysis/SourceIndex.java +++ b/src/cuchaz/enigma/analysis/SourceIndex.java | |||
| @@ -10,13 +10,15 @@ | |||
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | package cuchaz.enigma.analysis; | 11 | package cuchaz.enigma.analysis; |
| 12 | 12 | ||
| 13 | import java.util.HashMap; | 13 | import java.util.Collection; |
| 14 | import java.util.List; | 14 | import java.util.List; |
| 15 | import java.util.Map; | 15 | import java.util.Map; |
| 16 | import java.util.TreeMap; | 16 | import java.util.TreeMap; |
| 17 | 17 | ||
| 18 | import com.google.common.collect.HashMultimap; | ||
| 18 | import com.google.common.collect.Lists; | 19 | import com.google.common.collect.Lists; |
| 19 | import com.google.common.collect.Maps; | 20 | import com.google.common.collect.Maps; |
| 21 | import com.google.common.collect.Multimap; | ||
| 20 | import com.strobel.decompiler.languages.Region; | 22 | import com.strobel.decompiler.languages.Region; |
| 21 | import com.strobel.decompiler.languages.java.ast.Identifier; | 23 | import com.strobel.decompiler.languages.java.ast.Identifier; |
| 22 | 24 | ||
| @@ -26,7 +28,7 @@ public class SourceIndex | |||
| 26 | { | 28 | { |
| 27 | private String m_source; | 29 | private String m_source; |
| 28 | private TreeMap<Token,EntryReference<Entry,Entry>> m_tokenToReference; | 30 | private TreeMap<Token,EntryReference<Entry,Entry>> m_tokenToReference; |
| 29 | private HashMap<EntryReference<Entry,Entry>,Token> m_referenceToToken; | 31 | private Multimap<EntryReference<Entry,Entry>,Token> m_referenceToTokens; |
| 30 | private Map<Entry,Token> m_declarationToToken; | 32 | private Map<Entry,Token> m_declarationToToken; |
| 31 | private List<Integer> m_lineOffsets; | 33 | private List<Integer> m_lineOffsets; |
| 32 | 34 | ||
| @@ -34,7 +36,7 @@ public class SourceIndex | |||
| 34 | { | 36 | { |
| 35 | m_source = source; | 37 | m_source = source; |
| 36 | m_tokenToReference = Maps.newTreeMap(); | 38 | m_tokenToReference = Maps.newTreeMap(); |
| 37 | m_referenceToToken = Maps.newHashMap(); | 39 | m_referenceToTokens = HashMultimap.create(); |
| 38 | m_declarationToToken = Maps.newHashMap(); | 40 | m_declarationToToken = Maps.newHashMap(); |
| 39 | m_lineOffsets = Lists.newArrayList(); | 41 | m_lineOffsets = Lists.newArrayList(); |
| 40 | 42 | ||
| @@ -96,7 +98,7 @@ public class SourceIndex | |||
| 96 | if( token != null ) | 98 | if( token != null ) |
| 97 | { | 99 | { |
| 98 | m_tokenToReference.put( token, deobfReference ); | 100 | m_tokenToReference.put( token, deobfReference ); |
| 99 | m_referenceToToken.put( deobfReference, token ); | 101 | m_referenceToTokens.put( deobfReference, token ); |
| 100 | } | 102 | } |
| 101 | } | 103 | } |
| 102 | 104 | ||
| @@ -107,7 +109,7 @@ public class SourceIndex | |||
| 107 | { | 109 | { |
| 108 | EntryReference<Entry,Entry> reference = new EntryReference<Entry,Entry>( deobfEntry ); | 110 | EntryReference<Entry,Entry> reference = new EntryReference<Entry,Entry>( deobfEntry ); |
| 109 | m_tokenToReference.put( token, reference ); | 111 | m_tokenToReference.put( token, reference ); |
| 110 | m_referenceToToken.put( reference, token ); | 112 | m_referenceToTokens.put( reference, token ); |
| 111 | m_declarationToToken.put( deobfEntry, token ); | 113 | m_declarationToToken.put( deobfEntry, token ); |
| 112 | } | 114 | } |
| 113 | } | 115 | } |
| @@ -122,9 +124,9 @@ public class SourceIndex | |||
| 122 | return null; | 124 | return null; |
| 123 | } | 125 | } |
| 124 | 126 | ||
| 125 | public Token getReferenceToken( EntryReference<Entry,Entry> deobfReference ) | 127 | public Collection<Token> getReferenceTokens( EntryReference<Entry,Entry> deobfReference ) |
| 126 | { | 128 | { |
| 127 | return m_referenceToToken.get( deobfReference ); | 129 | return m_referenceToTokens.get( deobfReference ); |
| 128 | } | 130 | } |
| 129 | 131 | ||
| 130 | public EntryReference<Entry,Entry> getDeobfReference( Token token ) | 132 | public EntryReference<Entry,Entry> getDeobfReference( Token token ) |
| @@ -151,6 +153,27 @@ public class SourceIndex | |||
| 151 | return m_declarationToToken.get( deobfEntry ); | 153 | return m_declarationToToken.get( deobfEntry ); |
| 152 | } | 154 | } |
| 153 | 155 | ||
| 156 | public int getLineNumber( int pos ) | ||
| 157 | { | ||
| 158 | // line number is 1-based | ||
| 159 | int line = 0; | ||
| 160 | for( Integer offset : m_lineOffsets ) | ||
| 161 | { | ||
| 162 | if( offset > pos ) | ||
| 163 | { | ||
| 164 | break; | ||
| 165 | } | ||
| 166 | line++; | ||
| 167 | } | ||
| 168 | return line; | ||
| 169 | } | ||
| 170 | |||
| 171 | public int getColumnNumber( int pos ) | ||
| 172 | { | ||
| 173 | // column number is 1-based | ||
| 174 | return pos - m_lineOffsets.get( getLineNumber( pos ) - 1 ) + 1; | ||
| 175 | } | ||
| 176 | |||
| 154 | private int toPos( int line, int col ) | 177 | private int toPos( int line, int col ) |
| 155 | { | 178 | { |
| 156 | // line and col are 1-based | 179 | // line and col are 1-based |
diff --git a/src/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java b/src/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java index d3386c5..a943858 100644 --- a/src/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java +++ b/src/cuchaz/enigma/analysis/SourceIndexBehaviorVisitor.java | |||
| @@ -10,8 +10,6 @@ | |||
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | package cuchaz.enigma.analysis; | 11 | package cuchaz.enigma.analysis; |
| 12 | 12 | ||
| 13 | import com.google.common.collect.HashMultiset; | ||
| 14 | import com.google.common.collect.Multiset; | ||
| 15 | import com.strobel.assembler.metadata.MemberReference; | 13 | import com.strobel.assembler.metadata.MemberReference; |
| 16 | import com.strobel.assembler.metadata.MethodDefinition; | 14 | import com.strobel.assembler.metadata.MethodDefinition; |
| 17 | import com.strobel.assembler.metadata.ParameterDefinition; | 15 | import com.strobel.assembler.metadata.ParameterDefinition; |
| @@ -36,12 +34,10 @@ import cuchaz.enigma.mapping.MethodEntry; | |||
| 36 | public class SourceIndexBehaviorVisitor extends SourceIndexVisitor | 34 | public class SourceIndexBehaviorVisitor extends SourceIndexVisitor |
| 37 | { | 35 | { |
| 38 | private BehaviorEntry m_behaviorEntry; | 36 | private BehaviorEntry m_behaviorEntry; |
| 39 | private Multiset<Entry> m_indices; | ||
| 40 | 37 | ||
| 41 | public SourceIndexBehaviorVisitor( BehaviorEntry behaviorEntry ) | 38 | public SourceIndexBehaviorVisitor( BehaviorEntry behaviorEntry ) |
| 42 | { | 39 | { |
| 43 | m_behaviorEntry = behaviorEntry; | 40 | m_behaviorEntry = behaviorEntry; |
| 44 | m_indices = HashMultiset.create(); | ||
| 45 | } | 41 | } |
| 46 | 42 | ||
| 47 | @Override | 43 | @Override |
| @@ -64,10 +60,9 @@ public class SourceIndexBehaviorVisitor extends SourceIndexVisitor | |||
| 64 | MethodEntry methodEntry = new MethodEntry( classEntry, ref.getName(), ref.getSignature() ); | 60 | MethodEntry methodEntry = new MethodEntry( classEntry, ref.getName(), ref.getSignature() ); |
| 65 | if( node.getTarget() instanceof MemberReferenceExpression ) | 61 | if( node.getTarget() instanceof MemberReferenceExpression ) |
| 66 | { | 62 | { |
| 67 | m_indices.add( methodEntry ); | ||
| 68 | index.addReference( | 63 | index.addReference( |
| 69 | ((MemberReferenceExpression)node.getTarget()).getMemberNameToken(), | 64 | ((MemberReferenceExpression)node.getTarget()).getMemberNameToken(), |
| 70 | new EntryReference<Entry,Entry>( methodEntry, m_behaviorEntry, m_indices.count( methodEntry ) ) | 65 | new EntryReference<Entry,Entry>( methodEntry, m_behaviorEntry ) |
| 71 | ); | 66 | ); |
| 72 | } | 67 | } |
| 73 | 68 | ||
| @@ -82,10 +77,9 @@ public class SourceIndexBehaviorVisitor extends SourceIndexVisitor | |||
| 82 | { | 77 | { |
| 83 | ClassEntry classEntry = new ClassEntry( ref.getDeclaringType().getInternalName() ); | 78 | ClassEntry classEntry = new ClassEntry( ref.getDeclaringType().getInternalName() ); |
| 84 | FieldEntry fieldEntry = new FieldEntry( classEntry, ref.getName() ); | 79 | FieldEntry fieldEntry = new FieldEntry( classEntry, ref.getName() ); |
| 85 | m_indices.add( fieldEntry ); | ||
| 86 | index.addReference( | 80 | index.addReference( |
| 87 | node.getMemberNameToken(), | 81 | node.getMemberNameToken(), |
| 88 | new EntryReference<Entry,Entry>( fieldEntry, m_behaviorEntry, m_indices.count( fieldEntry ) ) | 82 | new EntryReference<Entry,Entry>( fieldEntry, m_behaviorEntry ) |
| 89 | ); | 83 | ); |
| 90 | } | 84 | } |
| 91 | 85 | ||
| @@ -99,10 +93,9 @@ public class SourceIndexBehaviorVisitor extends SourceIndexVisitor | |||
| 99 | if( node.getIdentifierToken().getStartLocation() != TextLocation.EMPTY ) | 93 | if( node.getIdentifierToken().getStartLocation() != TextLocation.EMPTY ) |
| 100 | { | 94 | { |
| 101 | ClassEntry classEntry = new ClassEntry( ref.getInternalName() ); | 95 | ClassEntry classEntry = new ClassEntry( ref.getInternalName() ); |
| 102 | m_indices.add( classEntry ); | ||
| 103 | index.addReference( | 96 | index.addReference( |
| 104 | node.getIdentifierToken(), | 97 | node.getIdentifierToken(), |
| 105 | new EntryReference<Entry,Entry>( classEntry, m_behaviorEntry, m_indices.count( classEntry ) ) | 98 | new EntryReference<Entry,Entry>( classEntry, m_behaviorEntry ) |
| 106 | ); | 99 | ); |
| 107 | } | 100 | } |
| 108 | 101 | ||
| @@ -130,10 +123,9 @@ public class SourceIndexBehaviorVisitor extends SourceIndexVisitor | |||
| 130 | { | 123 | { |
| 131 | ClassEntry classEntry = new ClassEntry( ref.getDeclaringType().getInternalName() ); | 124 | ClassEntry classEntry = new ClassEntry( ref.getDeclaringType().getInternalName() ); |
| 132 | FieldEntry fieldEntry = new FieldEntry( classEntry, ref.getName() ); | 125 | FieldEntry fieldEntry = new FieldEntry( classEntry, ref.getName() ); |
| 133 | m_indices.add( fieldEntry ); | ||
| 134 | index.addReference( | 126 | index.addReference( |
| 135 | node.getIdentifierToken(), | 127 | node.getIdentifierToken(), |
| 136 | new EntryReference<Entry,Entry>( fieldEntry, m_behaviorEntry, m_indices.count( fieldEntry ) ) | 128 | new EntryReference<Entry,Entry>( fieldEntry, m_behaviorEntry ) |
| 137 | ); | 129 | ); |
| 138 | } | 130 | } |
| 139 | 131 | ||
diff --git a/src/cuchaz/enigma/analysis/SourceIndexClassVisitor.java b/src/cuchaz/enigma/analysis/SourceIndexClassVisitor.java index 5257088..a1c8271 100644 --- a/src/cuchaz/enigma/analysis/SourceIndexClassVisitor.java +++ b/src/cuchaz/enigma/analysis/SourceIndexClassVisitor.java | |||
| @@ -10,8 +10,6 @@ | |||
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | package cuchaz.enigma.analysis; | 11 | package cuchaz.enigma.analysis; |
| 12 | 12 | ||
| 13 | import com.google.common.collect.HashMultiset; | ||
| 14 | import com.google.common.collect.Multiset; | ||
| 15 | import com.strobel.assembler.metadata.FieldDefinition; | 13 | import com.strobel.assembler.metadata.FieldDefinition; |
| 16 | import com.strobel.assembler.metadata.MethodDefinition; | 14 | import com.strobel.assembler.metadata.MethodDefinition; |
| 17 | import com.strobel.assembler.metadata.TypeDefinition; | 15 | import com.strobel.assembler.metadata.TypeDefinition; |
| @@ -26,6 +24,7 @@ import com.strobel.decompiler.languages.java.ast.SimpleType; | |||
| 26 | import com.strobel.decompiler.languages.java.ast.TypeDeclaration; | 24 | import com.strobel.decompiler.languages.java.ast.TypeDeclaration; |
| 27 | import com.strobel.decompiler.languages.java.ast.VariableInitializer; | 25 | import com.strobel.decompiler.languages.java.ast.VariableInitializer; |
| 28 | 26 | ||
| 27 | import cuchaz.enigma.mapping.BehaviorEntry; | ||
| 29 | import cuchaz.enigma.mapping.ClassEntry; | 28 | import cuchaz.enigma.mapping.ClassEntry; |
| 30 | import cuchaz.enigma.mapping.ConstructorEntry; | 29 | import cuchaz.enigma.mapping.ConstructorEntry; |
| 31 | import cuchaz.enigma.mapping.Entry; | 30 | import cuchaz.enigma.mapping.Entry; |
| @@ -35,12 +34,10 @@ import cuchaz.enigma.mapping.MethodEntry; | |||
| 35 | public class SourceIndexClassVisitor extends SourceIndexVisitor | 34 | public class SourceIndexClassVisitor extends SourceIndexVisitor |
| 36 | { | 35 | { |
| 37 | private ClassEntry m_classEntry; | 36 | private ClassEntry m_classEntry; |
| 38 | private Multiset<Entry> m_indices; | ||
| 39 | 37 | ||
| 40 | public SourceIndexClassVisitor( ClassEntry classEntry ) | 38 | public SourceIndexClassVisitor( ClassEntry classEntry ) |
| 41 | { | 39 | { |
| 42 | m_classEntry = classEntry; | 40 | m_classEntry = classEntry; |
| 43 | m_indices = HashMultiset.create(); | ||
| 44 | } | 41 | } |
| 45 | 42 | ||
| 46 | @Override | 43 | @Override |
| @@ -68,7 +65,7 @@ public class SourceIndexClassVisitor extends SourceIndexVisitor | |||
| 68 | ClassEntry classEntry = new ClassEntry( ref.getInternalName() ); | 65 | ClassEntry classEntry = new ClassEntry( ref.getInternalName() ); |
| 69 | index.addReference( | 66 | index.addReference( |
| 70 | node.getIdentifierToken(), | 67 | node.getIdentifierToken(), |
| 71 | new EntryReference<Entry,Entry>( classEntry, m_classEntry, m_indices.count( classEntry ) ) | 68 | new EntryReference<Entry,Entry>( classEntry, m_classEntry ) |
| 72 | ); | 69 | ); |
| 73 | } | 70 | } |
| 74 | 71 | ||
| @@ -80,11 +77,17 @@ public class SourceIndexClassVisitor extends SourceIndexVisitor | |||
| 80 | { | 77 | { |
| 81 | MethodDefinition def = node.getUserData( Keys.METHOD_DEFINITION ); | 78 | MethodDefinition def = node.getUserData( Keys.METHOD_DEFINITION ); |
| 82 | ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() ); | 79 | ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() ); |
| 83 | MethodEntry methodEntry = new MethodEntry( classEntry, def.getName(), def.getSignature() ); | 80 | BehaviorEntry behaviorEntry; |
| 84 | index.addDeclaration( node.getNameToken(), methodEntry ); | 81 | if( def.getName().equals( "<clinit>" ) ) |
| 85 | //if( !def.getName().equals( "<clinit>" ) ) | 82 | { |
| 86 | 83 | behaviorEntry = new ConstructorEntry( classEntry ); | |
| 87 | return node.acceptVisitor( new SourceIndexBehaviorVisitor( methodEntry ), index ); | 84 | } |
| 85 | else | ||
| 86 | { | ||
| 87 | behaviorEntry = new MethodEntry( classEntry, def.getName(), def.getSignature() ); | ||
| 88 | } | ||
| 89 | index.addDeclaration( node.getNameToken(), behaviorEntry ); | ||
| 90 | return node.acceptVisitor( new SourceIndexBehaviorVisitor( behaviorEntry ), index ); | ||
| 88 | } | 91 | } |
| 89 | 92 | ||
| 90 | @Override | 93 | @Override |
diff --git a/src/cuchaz/enigma/gui/Gui.java b/src/cuchaz/enigma/gui/Gui.java index 341c149..a5471a7 100644 --- a/src/cuchaz/enigma/gui/Gui.java +++ b/src/cuchaz/enigma/gui/Gui.java | |||
| @@ -28,6 +28,7 @@ import java.awt.event.WindowAdapter; | |||
| 28 | import java.awt.event.WindowEvent; | 28 | import java.awt.event.WindowEvent; |
| 29 | import java.io.File; | 29 | import java.io.File; |
| 30 | import java.io.IOException; | 30 | import java.io.IOException; |
| 31 | import java.util.Collection; | ||
| 31 | import java.util.Collections; | 32 | import java.util.Collections; |
| 32 | import java.util.Comparator; | 33 | import java.util.Comparator; |
| 33 | import java.util.List; | 34 | import java.util.List; |
| @@ -145,6 +146,7 @@ public class Gui | |||
| 145 | private BoxHighlightPainter m_deobfuscatedHighlightPainter; | 146 | private BoxHighlightPainter m_deobfuscatedHighlightPainter; |
| 146 | private JTree m_inheritanceTree; | 147 | private JTree m_inheritanceTree; |
| 147 | private JTree m_callsTree; | 148 | private JTree m_callsTree; |
| 149 | private JList<Token> m_tokens; | ||
| 148 | private JTabbedPane m_tabs; | 150 | private JTabbedPane m_tabs; |
| 149 | 151 | ||
| 150 | // dynamic menu items | 152 | // dynamic menu items |
| @@ -457,9 +459,29 @@ public class Gui | |||
| 457 | } | 459 | } |
| 458 | } | 460 | } |
| 459 | } ); | 461 | } ); |
| 460 | JPanel callPanel = new JPanel(); | 462 | m_tokens = new JList<Token>(); |
| 461 | callPanel.setLayout( new BorderLayout() ); | 463 | m_tokens.setCellRenderer( new TokenListCellRenderer( m_controller ) ); |
| 462 | callPanel.add( new JScrollPane( m_callsTree ) ); | 464 | m_tokens.setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); |
| 465 | m_tokens.setLayoutOrientation( JList.VERTICAL ); | ||
| 466 | m_tokens.addMouseListener( new MouseAdapter() | ||
| 467 | { | ||
| 468 | @Override | ||
| 469 | public void mouseClicked( MouseEvent event ) | ||
| 470 | { | ||
| 471 | if( event.getClickCount() == 2 ) | ||
| 472 | { | ||
| 473 | Token selected = m_tokens.getSelectedValue(); | ||
| 474 | if( selected != null ) | ||
| 475 | { | ||
| 476 | showToken( selected ); | ||
| 477 | } | ||
| 478 | } | ||
| 479 | } | ||
| 480 | } ); | ||
| 481 | m_tokens.setPreferredSize( new Dimension( 0, 200 ) ); | ||
| 482 | JSplitPane callPanel = new JSplitPane( JSplitPane.VERTICAL_SPLIT, true, new JScrollPane( m_callsTree ), new JScrollPane( m_tokens ) ); | ||
| 483 | callPanel.setResizeWeight( 1 ); // let the top side take all the slack | ||
| 484 | callPanel.resetToPreferredSizes(); | ||
| 463 | 485 | ||
| 464 | // layout controls | 486 | // layout controls |
| 465 | JSplitPane splitLeft = new JSplitPane( JSplitPane.VERTICAL_SPLIT, true, obfPanel, deobfPanel ); | 487 | JSplitPane splitLeft = new JSplitPane( JSplitPane.VERTICAL_SPLIT, true, obfPanel, deobfPanel ); |
| @@ -743,6 +765,21 @@ public class Gui | |||
| 743 | m_editor.grabFocus(); | 765 | m_editor.grabFocus(); |
| 744 | } | 766 | } |
| 745 | 767 | ||
| 768 | public void showTokens( Collection<Token> tokens ) | ||
| 769 | { | ||
| 770 | Vector<Token> sortedTokens = new Vector<Token>( tokens ); | ||
| 771 | Collections.sort( sortedTokens ); | ||
| 772 | if( sortedTokens.size() > 1 ) | ||
| 773 | { | ||
| 774 | // sort the tokens and update the tokens panel | ||
| 775 | m_tokens.setListData( sortedTokens ); | ||
| 776 | m_tokens.setSelectedIndex( 0 ); | ||
| 777 | } | ||
| 778 | |||
| 779 | // show the first token | ||
| 780 | showToken( sortedTokens.get( 0 ) ); | ||
| 781 | } | ||
| 782 | |||
| 746 | public void setHighlightedTokens( Iterable<Token> obfuscatedTokens, Iterable<Token> deobfuscatedTokens ) | 783 | public void setHighlightedTokens( Iterable<Token> obfuscatedTokens, Iterable<Token> deobfuscatedTokens ) |
| 747 | { | 784 | { |
| 748 | // remove any old highlighters | 785 | // remove any old highlighters |
| @@ -900,17 +937,9 @@ public class Gui | |||
| 900 | 937 | ||
| 901 | private void startRename( ) | 938 | private void startRename( ) |
| 902 | { | 939 | { |
| 903 | // get the class name | ||
| 904 | ClassEntry classEntry = m_reference.entry.getClassEntry(); | ||
| 905 | String className = classEntry.getName(); | ||
| 906 | if( classEntry.isInnerClass() ) | ||
| 907 | { | ||
| 908 | className = classEntry.getInnerClassName(); | ||
| 909 | } | ||
| 910 | |||
| 911 | // init the text box | 940 | // init the text box |
| 912 | final JTextField text = new JTextField(); | 941 | final JTextField text = new JTextField(); |
| 913 | text.setText( className ); | 942 | text.setText( m_reference.entry.getName() ); |
| 914 | text.setPreferredSize( new Dimension( 360, text.getPreferredSize().height ) ); | 943 | text.setPreferredSize( new Dimension( 360, text.getPreferredSize().height ) ); |
| 915 | text.addKeyListener( new KeyAdapter( ) | 944 | text.addKeyListener( new KeyAdapter( ) |
| 916 | { | 945 | { |
diff --git a/src/cuchaz/enigma/gui/GuiController.java b/src/cuchaz/enigma/gui/GuiController.java index dfa2557..a35db05 100644 --- a/src/cuchaz/enigma/gui/GuiController.java +++ b/src/cuchaz/enigma/gui/GuiController.java | |||
| @@ -14,6 +14,7 @@ import java.io.File; | |||
| 14 | import java.io.FileReader; | 14 | import java.io.FileReader; |
| 15 | import java.io.FileWriter; | 15 | import java.io.FileWriter; |
| 16 | import java.io.IOException; | 16 | import java.io.IOException; |
| 17 | import java.util.Collection; | ||
| 17 | import java.util.Deque; | 18 | import java.util.Deque; |
| 18 | import java.util.List; | 19 | import java.util.List; |
| 19 | 20 | ||
| @@ -45,7 +46,7 @@ public class GuiController | |||
| 45 | private SourceIndex m_index; | 46 | private SourceIndex m_index; |
| 46 | private ClassEntry m_currentObfClass; | 47 | private ClassEntry m_currentObfClass; |
| 47 | private boolean m_isDirty; | 48 | private boolean m_isDirty; |
| 48 | private Deque<EntryReference<Entry,Entry>> m_referenceStack; // TODO: make a location class, can be either Entry or EntryReference | 49 | private Deque<EntryReference<Entry,Entry>> m_referenceStack; |
| 49 | 50 | ||
| 50 | public GuiController( Gui gui ) | 51 | public GuiController( Gui gui ) |
| 51 | { | 52 | { |
| @@ -111,7 +112,6 @@ public class GuiController | |||
| 111 | { | 112 | { |
| 112 | return null; | 113 | return null; |
| 113 | } | 114 | } |
| 114 | |||
| 115 | return m_index.getReferenceToken( pos ); | 115 | return m_index.getReferenceToken( pos ); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| @@ -124,6 +124,19 @@ public class GuiController | |||
| 124 | return m_index.getDeobfReference( token ); | 124 | return m_index.getDeobfReference( token ); |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | public ReadableToken getReadableToken( Token token ) | ||
| 128 | { | ||
| 129 | if( m_index == null ) | ||
| 130 | { | ||
| 131 | return null; | ||
| 132 | } | ||
| 133 | return new ReadableToken( | ||
| 134 | m_index.getLineNumber( token.start ), | ||
| 135 | m_index.getColumnNumber( token.start ), | ||
| 136 | m_index.getColumnNumber( token.end ) | ||
| 137 | ); | ||
| 138 | } | ||
| 139 | |||
| 127 | public boolean entryHasMapping( Entry deobfEntry ) | 140 | public boolean entryHasMapping( Entry deobfEntry ) |
| 128 | { | 141 | { |
| 129 | return m_deobfuscator.hasMapping( m_deobfuscator.obfuscateEntry( deobfEntry ) ); | 142 | return m_deobfuscator.hasMapping( m_deobfuscator.obfuscateEntry( deobfEntry ) ); |
| @@ -134,8 +147,9 @@ public class GuiController | |||
| 134 | return m_deobfuscator.isObfuscatedIdentifier( m_deobfuscator.obfuscateEntry( deobfEntry ) ); | 147 | return m_deobfuscator.isObfuscatedIdentifier( m_deobfuscator.obfuscateEntry( deobfEntry ) ); |
| 135 | } | 148 | } |
| 136 | 149 | ||
| 137 | public ClassInheritanceTreeNode getClassInheritance( ClassEntry obfClassEntry ) | 150 | public ClassInheritanceTreeNode getClassInheritance( ClassEntry deobfClassEntry ) |
| 138 | { | 151 | { |
| 152 | ClassEntry obfClassEntry = m_deobfuscator.obfuscateEntry( deobfClassEntry ); | ||
| 139 | ClassInheritanceTreeNode rootNode = m_deobfuscator.getJarIndex().getClassInheritance( | 153 | ClassInheritanceTreeNode rootNode = m_deobfuscator.getJarIndex().getClassInheritance( |
| 140 | m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating ), | 154 | m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating ), |
| 141 | obfClassEntry | 155 | obfClassEntry |
| @@ -143,8 +157,9 @@ public class GuiController | |||
| 143 | return ClassInheritanceTreeNode.findNode( rootNode, obfClassEntry ); | 157 | return ClassInheritanceTreeNode.findNode( rootNode, obfClassEntry ); |
| 144 | } | 158 | } |
| 145 | 159 | ||
| 146 | public MethodInheritanceTreeNode getMethodInheritance( MethodEntry obfMethodEntry ) | 160 | public MethodInheritanceTreeNode getMethodInheritance( MethodEntry deobfMethodEntry ) |
| 147 | { | 161 | { |
| 162 | MethodEntry obfMethodEntry = m_deobfuscator.obfuscateEntry( deobfMethodEntry ); | ||
| 148 | MethodInheritanceTreeNode rootNode = m_deobfuscator.getJarIndex().getMethodInheritance( | 163 | MethodInheritanceTreeNode rootNode = m_deobfuscator.getJarIndex().getMethodInheritance( |
| 149 | m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating ), | 164 | m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating ), |
| 150 | obfMethodEntry | 165 | obfMethodEntry |
| @@ -152,8 +167,9 @@ public class GuiController | |||
| 152 | return MethodInheritanceTreeNode.findNode( rootNode, obfMethodEntry ); | 167 | return MethodInheritanceTreeNode.findNode( rootNode, obfMethodEntry ); |
| 153 | } | 168 | } |
| 154 | 169 | ||
| 155 | public FieldReferenceTreeNode getFieldReferences( FieldEntry obfFieldEntry ) | 170 | public FieldReferenceTreeNode getFieldReferences( FieldEntry deobfFieldEntry ) |
| 156 | { | 171 | { |
| 172 | FieldEntry obfFieldEntry = m_deobfuscator.obfuscateEntry( deobfFieldEntry ); | ||
| 157 | FieldReferenceTreeNode rootNode = new FieldReferenceTreeNode( | 173 | FieldReferenceTreeNode rootNode = new FieldReferenceTreeNode( |
| 158 | m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating ), | 174 | m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating ), |
| 159 | obfFieldEntry | 175 | obfFieldEntry |
| @@ -162,11 +178,12 @@ public class GuiController | |||
| 162 | return rootNode; | 178 | return rootNode; |
| 163 | } | 179 | } |
| 164 | 180 | ||
| 165 | public BehaviorReferenceTreeNode getMethodReferences( BehaviorEntry obfEntry ) | 181 | public BehaviorReferenceTreeNode getMethodReferences( BehaviorEntry deobfBehaviorEntry ) |
| 166 | { | 182 | { |
| 183 | BehaviorEntry obfBehaviorEntry = m_deobfuscator.obfuscateEntry( deobfBehaviorEntry ); | ||
| 167 | BehaviorReferenceTreeNode rootNode = new BehaviorReferenceTreeNode( | 184 | BehaviorReferenceTreeNode rootNode = new BehaviorReferenceTreeNode( |
| 168 | m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating ), | 185 | m_deobfuscator.getTranslator( TranslationDirection.Deobfuscating ), |
| 169 | obfEntry | 186 | obfBehaviorEntry |
| 170 | ); | 187 | ); |
| 171 | rootNode.load( m_deobfuscator.getJarIndex(), true ); | 188 | rootNode.load( m_deobfuscator.getJarIndex(), true ); |
| 172 | return rootNode; | 189 | return rootNode; |
| @@ -181,13 +198,13 @@ public class GuiController | |||
| 181 | refreshCurrentClass( obfReference ); | 198 | refreshCurrentClass( obfReference ); |
| 182 | } | 199 | } |
| 183 | 200 | ||
| 184 | public void openDeclaration( Entry entry ) | 201 | public void openDeclaration( Entry deobfEntry ) |
| 185 | { | 202 | { |
| 186 | if( entry == null ) | 203 | if( deobfEntry == null ) |
| 187 | { | 204 | { |
| 188 | throw new IllegalArgumentException( "Entry cannot be null!" ); | 205 | throw new IllegalArgumentException( "Entry cannot be null!" ); |
| 189 | } | 206 | } |
| 190 | openReference( new EntryReference<Entry,Entry>( entry ) ); | 207 | openReference( new EntryReference<Entry,Entry>( deobfEntry ) ); |
| 191 | } | 208 | } |
| 192 | 209 | ||
| 193 | public void openReference( EntryReference<Entry,Entry> deobfReference ) | 210 | public void openReference( EntryReference<Entry,Entry> deobfReference ) |
| @@ -208,8 +225,22 @@ public class GuiController | |||
| 208 | } | 225 | } |
| 209 | else | 226 | else |
| 210 | { | 227 | { |
| 211 | // the class file is already open, just navigate to the reference | 228 | showReference( obfReference ); |
| 212 | m_gui.showToken( m_index.getReferenceToken( deobfReference ) ); | 229 | } |
| 230 | } | ||
| 231 | |||
| 232 | private void showReference( EntryReference<Entry,Entry> obfReference ) | ||
| 233 | { | ||
| 234 | EntryReference<Entry,Entry> deobfReference = m_deobfuscator.deobfuscateReference( obfReference ); | ||
| 235 | Collection<Token> tokens = m_index.getReferenceTokens( deobfReference ); | ||
| 236 | if( tokens.isEmpty() ) | ||
| 237 | { | ||
| 238 | // DEBUG | ||
| 239 | System.err.println( String.format( "WARNING: no tokens found for %s in %s", deobfReference, m_currentObfClass ) ); | ||
| 240 | } | ||
| 241 | else | ||
| 242 | { | ||
| 243 | m_gui.showTokens( tokens ); | ||
| 213 | } | 244 | } |
| 214 | } | 245 | } |
| 215 | 246 | ||
| @@ -245,15 +276,15 @@ public class GuiController | |||
| 245 | refreshCurrentClass( null ); | 276 | refreshCurrentClass( null ); |
| 246 | } | 277 | } |
| 247 | 278 | ||
| 248 | private void refreshCurrentClass( EntryReference<Entry,Entry> obfReferenceToShow ) | 279 | private void refreshCurrentClass( EntryReference<Entry,Entry> obfReference ) |
| 249 | { | 280 | { |
| 250 | if( m_currentObfClass != null ) | 281 | if( m_currentObfClass != null ) |
| 251 | { | 282 | { |
| 252 | deobfuscate( m_currentObfClass, obfReferenceToShow ); | 283 | deobfuscate( m_currentObfClass, obfReference ); |
| 253 | } | 284 | } |
| 254 | } | 285 | } |
| 255 | 286 | ||
| 256 | private void deobfuscate( final ClassEntry classEntry, final EntryReference<Entry,Entry> obfReferenceToShow ) | 287 | private void deobfuscate( final ClassEntry classEntry, final EntryReference<Entry,Entry> obfReference ) |
| 257 | { | 288 | { |
| 258 | m_gui.setSource( "(deobfuscating...)" ); | 289 | m_gui.setSource( "(deobfuscating...)" ); |
| 259 | 290 | ||
| @@ -266,19 +297,9 @@ public class GuiController | |||
| 266 | // decompile,deobfuscate the bytecode | 297 | // decompile,deobfuscate the bytecode |
| 267 | m_index = m_deobfuscator.getSource( classEntry.getClassName() ); | 298 | m_index = m_deobfuscator.getSource( classEntry.getClassName() ); |
| 268 | m_gui.setSource( m_index.getSource() ); | 299 | m_gui.setSource( m_index.getSource() ); |
| 269 | if( obfReferenceToShow != null ) | 300 | if( obfReference != null ) |
| 270 | { | 301 | { |
| 271 | EntryReference<Entry,Entry> deobfReferenceToShow = m_deobfuscator.deobfuscateReference( obfReferenceToShow ); | 302 | showReference( obfReference ); |
| 272 | Token token = m_index.getReferenceToken( deobfReferenceToShow ); | ||
| 273 | if( token == null ) | ||
| 274 | { | ||
| 275 | // DEBUG | ||
| 276 | System.out.println( "WARNING: can't find token for " + obfReferenceToShow + " -> " + deobfReferenceToShow ); | ||
| 277 | } | ||
| 278 | else | ||
| 279 | { | ||
| 280 | m_gui.showToken( token ); | ||
| 281 | } | ||
| 282 | } | 303 | } |
| 283 | 304 | ||
| 284 | // set the highlighted tokens | 305 | // set the highlighted tokens |
diff --git a/src/cuchaz/enigma/gui/ReadableToken.java b/src/cuchaz/enigma/gui/ReadableToken.java new file mode 100644 index 0000000..3f43045 --- /dev/null +++ b/src/cuchaz/enigma/gui/ReadableToken.java | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | /******************************************************************************* | ||
| 2 | * Copyright (c) 2014 Jeff Martin. | ||
| 3 | * All rights reserved. This program and the accompanying materials | ||
| 4 | * are made available under the terms of the GNU Public License v3.0 | ||
| 5 | * which accompanies this distribution, and is available at | ||
| 6 | * http://www.gnu.org/licenses/gpl.html | ||
| 7 | * | ||
| 8 | * Contributors: | ||
| 9 | * Jeff Martin - initial API and implementation | ||
| 10 | ******************************************************************************/ | ||
| 11 | package cuchaz.enigma.gui; | ||
| 12 | |||
| 13 | public class ReadableToken | ||
| 14 | { | ||
| 15 | public int line; | ||
| 16 | public int startColumn; | ||
| 17 | public int endColumn; | ||
| 18 | |||
| 19 | public ReadableToken( int line, int startColumn, int endColumn ) | ||
| 20 | { | ||
| 21 | this.line = line; | ||
| 22 | this.startColumn = startColumn; | ||
| 23 | this.endColumn = endColumn; | ||
| 24 | } | ||
| 25 | |||
| 26 | @Override | ||
| 27 | public String toString( ) | ||
| 28 | { | ||
| 29 | StringBuilder buf = new StringBuilder(); | ||
| 30 | buf.append( "line " ); | ||
| 31 | buf.append( line ); | ||
| 32 | buf.append( " columns " ); | ||
| 33 | buf.append( startColumn ); | ||
| 34 | buf.append( "-" ); | ||
| 35 | buf.append( endColumn ); | ||
| 36 | return buf.toString(); | ||
| 37 | } | ||
| 38 | } | ||
diff --git a/src/cuchaz/enigma/gui/TokenListCellRenderer.java b/src/cuchaz/enigma/gui/TokenListCellRenderer.java new file mode 100644 index 0000000..9247c06 --- /dev/null +++ b/src/cuchaz/enigma/gui/TokenListCellRenderer.java | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | /******************************************************************************* | ||
| 2 | * Copyright (c) 2014 Jeff Martin. | ||
| 3 | * All rights reserved. This program and the accompanying materials | ||
| 4 | * are made available under the terms of the GNU Public License v3.0 | ||
| 5 | * which accompanies this distribution, and is available at | ||
| 6 | * http://www.gnu.org/licenses/gpl.html | ||
| 7 | * | ||
| 8 | * Contributors: | ||
| 9 | * Jeff Martin - initial API and implementation | ||
| 10 | ******************************************************************************/ | ||
| 11 | package cuchaz.enigma.gui; | ||
| 12 | |||
| 13 | import java.awt.Component; | ||
| 14 | |||
| 15 | import javax.swing.DefaultListCellRenderer; | ||
| 16 | import javax.swing.JLabel; | ||
| 17 | import javax.swing.JList; | ||
| 18 | import javax.swing.ListCellRenderer; | ||
| 19 | |||
| 20 | import cuchaz.enigma.analysis.Token; | ||
| 21 | |||
| 22 | public class TokenListCellRenderer implements ListCellRenderer<Token> | ||
| 23 | { | ||
| 24 | private GuiController m_controller; | ||
| 25 | private DefaultListCellRenderer m_defaultRenderer; | ||
| 26 | |||
| 27 | public TokenListCellRenderer( GuiController controller ) | ||
| 28 | { | ||
| 29 | m_controller = controller; | ||
| 30 | m_defaultRenderer = new DefaultListCellRenderer(); | ||
| 31 | } | ||
| 32 | |||
| 33 | @Override | ||
| 34 | public Component getListCellRendererComponent( JList<? extends Token> list, Token token, int index, boolean isSelected, boolean hasFocus ) | ||
| 35 | { | ||
| 36 | JLabel label = (JLabel)m_defaultRenderer.getListCellRendererComponent( list, token, index, isSelected, hasFocus ); | ||
| 37 | label.setText( m_controller.getReadableToken( token ).toString() ); | ||
| 38 | return label; | ||
| 39 | } | ||
| 40 | } | ||
diff --git a/src/cuchaz/enigma/mapping/ConstructorEntry.java b/src/cuchaz/enigma/mapping/ConstructorEntry.java index 0f7dab6..ad029e1 100644 --- a/src/cuchaz/enigma/mapping/ConstructorEntry.java +++ b/src/cuchaz/enigma/mapping/ConstructorEntry.java | |||
| @@ -21,16 +21,17 @@ public class ConstructorEntry implements BehaviorEntry, Serializable | |||
| 21 | private ClassEntry m_classEntry; | 21 | private ClassEntry m_classEntry; |
| 22 | private String m_signature; | 22 | private String m_signature; |
| 23 | 23 | ||
| 24 | public ConstructorEntry( ClassEntry classEntry ) | ||
| 25 | { | ||
| 26 | this( classEntry, null ); | ||
| 27 | } | ||
| 28 | |||
| 24 | public ConstructorEntry( ClassEntry classEntry, String signature ) | 29 | public ConstructorEntry( ClassEntry classEntry, String signature ) |
| 25 | { | 30 | { |
| 26 | if( classEntry == null ) | 31 | if( classEntry == null ) |
| 27 | { | 32 | { |
| 28 | throw new IllegalArgumentException( "Class cannot be null!" ); | 33 | throw new IllegalArgumentException( "Class cannot be null!" ); |
| 29 | } | 34 | } |
| 30 | if( signature == null ) | ||
| 31 | { | ||
| 32 | throw new IllegalArgumentException( "Method signature cannot be null!" ); | ||
| 33 | } | ||
| 34 | 35 | ||
| 35 | m_classEntry = classEntry; | 36 | m_classEntry = classEntry; |
| 36 | m_signature = signature; | 37 | m_signature = signature; |
| @@ -47,11 +48,20 @@ public class ConstructorEntry implements BehaviorEntry, Serializable | |||
| 47 | { | 48 | { |
| 48 | return m_classEntry; | 49 | return m_classEntry; |
| 49 | } | 50 | } |
| 50 | 51 | ||
| 51 | @Override | 52 | @Override |
| 52 | public String getName( ) | 53 | public String getName( ) |
| 53 | { | 54 | { |
| 54 | return m_classEntry.getName(); | 55 | if( isStatic() ) |
| 56 | { | ||
| 57 | return "<clinit>"; | ||
| 58 | } | ||
| 59 | return "<init>"; | ||
| 60 | } | ||
| 61 | |||
| 62 | public boolean isStatic( ) | ||
| 63 | { | ||
| 64 | return m_signature == null; | ||
| 55 | } | 65 | } |
| 56 | 66 | ||
| 57 | @Override | 67 | @Override |
| @@ -69,7 +79,14 @@ public class ConstructorEntry implements BehaviorEntry, Serializable | |||
| 69 | @Override | 79 | @Override |
| 70 | public int hashCode( ) | 80 | public int hashCode( ) |
| 71 | { | 81 | { |
| 72 | return Util.combineHashesOrdered( m_classEntry, m_signature ); | 82 | if( isStatic() ) |
| 83 | { | ||
| 84 | return Util.combineHashesOrdered( m_classEntry ); | ||
| 85 | } | ||
| 86 | else | ||
| 87 | { | ||
| 88 | return Util.combineHashesOrdered( m_classEntry, m_signature ); | ||
| 89 | } | ||
| 73 | } | 90 | } |
| 74 | 91 | ||
| 75 | @Override | 92 | @Override |
| @@ -84,12 +101,31 @@ public class ConstructorEntry implements BehaviorEntry, Serializable | |||
| 84 | 101 | ||
| 85 | public boolean equals( ConstructorEntry other ) | 102 | public boolean equals( ConstructorEntry other ) |
| 86 | { | 103 | { |
| 87 | return m_classEntry.equals( other.m_classEntry ) && m_signature.equals( other.m_signature ); | 104 | if( isStatic() != other.isStatic() ) |
| 105 | { | ||
| 106 | return false; | ||
| 107 | } | ||
| 108 | |||
| 109 | if( isStatic() ) | ||
| 110 | { | ||
| 111 | return m_classEntry.equals( other.m_classEntry ); | ||
| 112 | } | ||
| 113 | else | ||
| 114 | { | ||
| 115 | return m_classEntry.equals( other.m_classEntry ) && m_signature.equals( other.m_signature ); | ||
| 116 | } | ||
| 88 | } | 117 | } |
| 89 | 118 | ||
| 90 | @Override | 119 | @Override |
| 91 | public String toString( ) | 120 | public String toString( ) |
| 92 | { | 121 | { |
| 93 | return m_classEntry.getName() + m_signature; | 122 | if( isStatic() ) |
| 123 | { | ||
| 124 | return m_classEntry.getName() + "." + getName(); | ||
| 125 | } | ||
| 126 | else | ||
| 127 | { | ||
| 128 | return m_classEntry.getName() + "." + getName() + m_signature; | ||
| 129 | } | ||
| 94 | } | 130 | } |
| 95 | } | 131 | } |
diff --git a/src/cuchaz/enigma/mapping/Translator.java b/src/cuchaz/enigma/mapping/Translator.java index e34c31b..a671c27 100644 --- a/src/cuchaz/enigma/mapping/Translator.java +++ b/src/cuchaz/enigma/mapping/Translator.java | |||
| @@ -30,27 +30,28 @@ public class Translator | |||
| 30 | m_ancestries = ancestries; | 30 | m_ancestries = ancestries; |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | public Entry translateEntry( Entry entry ) | 33 | @SuppressWarnings( "unchecked" ) |
| 34 | public <T extends Entry> T translateEntry( T entry ) | ||
| 34 | { | 35 | { |
| 35 | if( entry instanceof ClassEntry ) | 36 | if( entry instanceof ClassEntry ) |
| 36 | { | 37 | { |
| 37 | return translateEntry( (ClassEntry)entry ); | 38 | return (T)translateEntry( (ClassEntry)entry ); |
| 38 | } | 39 | } |
| 39 | else if( entry instanceof FieldEntry ) | 40 | else if( entry instanceof FieldEntry ) |
| 40 | { | 41 | { |
| 41 | return translateEntry( (FieldEntry)entry ); | 42 | return (T)translateEntry( (FieldEntry)entry ); |
| 42 | } | 43 | } |
| 43 | else if( entry instanceof MethodEntry ) | 44 | else if( entry instanceof MethodEntry ) |
| 44 | { | 45 | { |
| 45 | return translateEntry( (MethodEntry)entry ); | 46 | return (T)translateEntry( (MethodEntry)entry ); |
| 46 | } | 47 | } |
| 47 | else if( entry instanceof ConstructorEntry ) | 48 | else if( entry instanceof ConstructorEntry ) |
| 48 | { | 49 | { |
| 49 | return translateEntry( (ConstructorEntry)entry ); | 50 | return (T)translateEntry( (ConstructorEntry)entry ); |
| 50 | } | 51 | } |
| 51 | else if( entry instanceof ArgumentEntry ) | 52 | else if( entry instanceof ArgumentEntry ) |
| 52 | { | 53 | { |
| 53 | return translateEntry( (ArgumentEntry)entry ); | 54 | return (T)translateEntry( (ArgumentEntry)entry ); |
| 54 | } | 55 | } |
| 55 | else | 56 | else |
| 56 | { | 57 | { |
| @@ -194,10 +195,17 @@ public class Translator | |||
| 194 | 195 | ||
| 195 | public ConstructorEntry translateEntry( ConstructorEntry in ) | 196 | public ConstructorEntry translateEntry( ConstructorEntry in ) |
| 196 | { | 197 | { |
| 197 | return new ConstructorEntry( | 198 | if( in.isStatic() ) |
| 198 | translateEntry( in.getClassEntry() ), | 199 | { |
| 199 | translateSignature( in.getSignature() ) | 200 | return new ConstructorEntry( translateEntry( in.getClassEntry() ) ); |
| 200 | ); | 201 | } |
| 202 | else | ||
| 203 | { | ||
| 204 | return new ConstructorEntry( | ||
| 205 | translateEntry( in.getClassEntry() ), | ||
| 206 | translateSignature( in.getSignature() ) | ||
| 207 | ); | ||
| 208 | } | ||
| 201 | } | 209 | } |
| 202 | 210 | ||
| 203 | public BehaviorEntry translateEntry( BehaviorEntry in ) | 211 | public BehaviorEntry translateEntry( BehaviorEntry in ) |