summaryrefslogtreecommitdiff
path: root/src/cuchaz
diff options
context:
space:
mode:
authorGravatar jeff2014-09-23 01:01:42 -0400
committerGravatar jeff2014-09-23 01:01:42 -0400
commita09a23871abaf2f0c8c1636ee6dd2f9eaf2474b0 (patch)
treeafc6e8fa290f07925fbaef723fc67b20dbc10d7d /src/cuchaz
parentAdded tag v0.5 beta for changeset b6266b67c906 (diff)
downloadenigma-fork-a09a23871abaf2f0c8c1636ee6dd2f9eaf2474b0.tar.gz
enigma-fork-a09a23871abaf2f0c8c1636ee6dd2f9eaf2474b0.tar.xz
enigma-fork-a09a23871abaf2f0c8c1636ee6dd2f9eaf2474b0.zip
trying to figure out why some mappings to correspond to anything in the jar file...
Diffstat (limited to 'src/cuchaz')
-rw-r--r--src/cuchaz/enigma/Deobfuscator.java102
-rw-r--r--src/cuchaz/enigma/analysis/EntryRenamer.java4
-rw-r--r--src/cuchaz/enigma/analysis/JarIndex.java14
-rw-r--r--src/cuchaz/enigma/mapping/ClassMapping.java22
4 files changed, 117 insertions, 25 deletions
diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java
index 9c84532..03c3511 100644
--- a/src/cuchaz/enigma/Deobfuscator.java
+++ b/src/cuchaz/enigma/Deobfuscator.java
@@ -22,6 +22,7 @@ import java.util.jar.JarFile;
22 22
23import javassist.bytecode.Descriptor; 23import javassist.bytecode.Descriptor;
24 24
25import com.google.common.collect.Lists;
25import com.google.common.collect.Maps; 26import com.google.common.collect.Maps;
26import com.google.common.collect.Sets; 27import com.google.common.collect.Sets;
27import com.strobel.assembler.metadata.MetadataSystem; 28import com.strobel.assembler.metadata.MetadataSystem;
@@ -44,6 +45,7 @@ import cuchaz.enigma.mapping.ClassMapping;
44import cuchaz.enigma.mapping.ConstructorEntry; 45import cuchaz.enigma.mapping.ConstructorEntry;
45import cuchaz.enigma.mapping.Entry; 46import cuchaz.enigma.mapping.Entry;
46import cuchaz.enigma.mapping.FieldEntry; 47import cuchaz.enigma.mapping.FieldEntry;
48import cuchaz.enigma.mapping.FieldMapping;
47import cuchaz.enigma.mapping.Mappings; 49import cuchaz.enigma.mapping.Mappings;
48import cuchaz.enigma.mapping.MappingsRenamer; 50import cuchaz.enigma.mapping.MappingsRenamer;
49import cuchaz.enigma.mapping.MethodEntry; 51import cuchaz.enigma.mapping.MethodEntry;
@@ -113,41 +115,107 @@ public class Deobfuscator
113 val = new Mappings(); 115 val = new Mappings();
114 } 116 }
115 117
116 // make sure all the mappings match the classes in the jar 118 // look for any classes that got moved to inner classes
119 Map<String,String> renames = Maps.newHashMap();
117 for( ClassMapping classMapping : val.classes() ) 120 for( ClassMapping classMapping : val.classes() )
118 { 121 {
119 ClassEntry classEntry = new ClassEntry( classMapping.getObfName() ); 122 String outerClassName = m_jarIndex.getOuterClass( classMapping.getObfName() );
120 if( !m_jarIndex.getObfClassEntries().contains( classEntry ) ) 123 if( outerClassName != null )
121 { 124 {
122 throw new Error( "Class " + classEntry + " not found in Jar!" ); 125 // build the composite class name
126 String newName = outerClassName + "$" + new ClassEntry( classMapping.getObfName() ).getSimpleName();
127
128 // add a rename
129 renames.put( classMapping.getObfName(), newName );
130
131 System.out.println( String.format( "Converted class mapping %s to %s", classMapping.getObfName(), newName ) );
123 } 132 }
124 133 }
125 // and method implementations 134 for( Map.Entry<String,String> entry : renames.entrySet() )
126 for( MethodMapping methodMapping : classMapping.methods() ) 135 {
136 val.renameObfClass( entry.getKey(), entry.getValue() );
137 }
138
139 // drop mappings that don't match the jar
140 List<ClassEntry> unknownClasses = Lists.newArrayList();
141 for( ClassMapping classMapping : val.classes() )
142 {
143 checkClassMapping( unknownClasses, classMapping );
144 }
145 if( !unknownClasses.isEmpty() )
146 {
147 throw new Error( "Unable to find classes in jar: " + unknownClasses );
148 }
149
150 m_mappings = val;
151 m_renamer = new MappingsRenamer( m_jarIndex, m_mappings );
152 m_translatorCache.clear();
153 }
154
155 private void checkClassMapping( List<ClassEntry> unknownClasses, ClassMapping classMapping )
156 {
157 // check the class
158 ClassEntry classEntry = new ClassEntry( classMapping.getObfName() );
159 String outerClassName = m_jarIndex.getOuterClass( classMapping.getObfName() );
160 if( outerClassName != null )
161 {
162 classEntry = new ClassEntry( outerClassName + "$" + classEntry.getSimpleName() );
163 }
164 if( !m_jarIndex.getObfClassEntries().contains( classEntry ) )
165 {
166 unknownClasses.add( classEntry );
167 }
168
169 // check the fields
170 for( FieldMapping fieldMapping : Lists.newArrayList( classMapping.fields() ) )
171 {
172 FieldEntry fieldEntry = new FieldEntry( classEntry, fieldMapping.getObfName() );
173 if( m_jarIndex.getAccess( fieldEntry ) == null )
174 {
175 System.err.println( "WARNING: unable to find field " + fieldEntry + ". dropping mapping." );
176 classMapping.removeFieldMapping( fieldMapping );
177 }
178 }
179
180 // check methods
181 for( MethodMapping methodMapping : Lists.newArrayList( classMapping.methods() ) )
182 {
183 if( methodMapping.getObfName().equals( "<clinit>" ) )
184 {
185 // skip static initializers
186 continue;
187 }
188 else if( methodMapping.getObfName().equals( "<init>" ) )
127 { 189 {
128 if( methodMapping.getObfName().startsWith( "<" ) ) 190 ConstructorEntry constructorEntry = new ConstructorEntry( classEntry, methodMapping.getObfSignature() );
191 if( m_jarIndex.getAccess( constructorEntry ) == null )
129 { 192 {
130 // skip constructors and static initializers 193 System.err.println( "WARNING: unable to find constructor " + constructorEntry + ". dropping mapping." );
131 continue; 194 classMapping.removeMethodMapping( methodMapping );
132 } 195 }
133 196 }
197 else
198 {
134 MethodEntry methodEntry = new MethodEntry( 199 MethodEntry methodEntry = new MethodEntry(
135 classEntry, 200 classEntry,
136 methodMapping.getObfName(), 201 methodMapping.getObfName(),
137 methodMapping.getObfSignature() 202 methodMapping.getObfSignature()
138 ); 203 );
139 if( !m_jarIndex.isMethodImplemented( methodEntry ) ) 204 if( m_jarIndex.getAccess( methodEntry ) == null )
140 { 205 {
141 throw new Error( "Method " + methodEntry + " not found in Jar!" ); 206 System.err.println( "WARNING: unable to find method " + methodEntry + ". dropping mapping." );
207 classMapping.removeMethodMapping( methodMapping );
142 } 208 }
143 } 209 }
144 } 210 }
145 211
146 m_mappings = val; 212 // check inner classes
147 m_renamer = new MappingsRenamer( m_jarIndex, m_mappings ); 213 for( ClassMapping innerClassMapping : classMapping.innerClasses() )
148 m_translatorCache.clear(); 214 {
215 checkClassMapping( unknownClasses, innerClassMapping );
216 }
149 } 217 }
150 218
151 public Translator getTranslator( TranslationDirection direction ) 219 public Translator getTranslator( TranslationDirection direction )
152 { 220 {
153 Translator translator = m_translatorCache.get( direction ); 221 Translator translator = m_translatorCache.get( direction );
diff --git a/src/cuchaz/enigma/analysis/EntryRenamer.java b/src/cuchaz/enigma/analysis/EntryRenamer.java
index e9483ca..b82b254 100644
--- a/src/cuchaz/enigma/analysis/EntryRenamer.java
+++ b/src/cuchaz/enigma/analysis/EntryRenamer.java
@@ -189,10 +189,6 @@ public class EntryRenamer
189 reference.context = renameClassesInThing( renames, reference.context ); 189 reference.context = renameClassesInThing( renames, reference.context );
190 return thing; 190 return thing;
191 } 191 }
192 else
193 {
194 throw new Error( "Not an entry: " + thing );
195 }
196 192
197 return thing; 193 return thing;
198 } 194 }
diff --git a/src/cuchaz/enigma/analysis/JarIndex.java b/src/cuchaz/enigma/analysis/JarIndex.java
index 8ebce35..b51428a 100644
--- a/src/cuchaz/enigma/analysis/JarIndex.java
+++ b/src/cuchaz/enigma/analysis/JarIndex.java
@@ -95,7 +95,7 @@ public class JarIndex
95 m_obfClassEntries.add( classEntry ); 95 m_obfClassEntries.add( classEntry );
96 } 96 }
97 97
98 // step 2: index method/field access 98 // step 2: index field/method/constructor access
99 for( CtClass c : JarClassIterator.classes( jar ) ) 99 for( CtClass c : JarClassIterator.classes( jar ) )
100 { 100 {
101 ClassRenamer.moveAllClassesOutOfDefaultPackage( c, Constants.NonePackage ); 101 ClassRenamer.moveAllClassesOutOfDefaultPackage( c, Constants.NonePackage );
@@ -105,10 +105,15 @@ public class JarIndex
105 FieldEntry fieldEntry = new FieldEntry( classEntry, field.getName() ); 105 FieldEntry fieldEntry = new FieldEntry( classEntry, field.getName() );
106 m_access.put( fieldEntry, Access.get( field ) ); 106 m_access.put( fieldEntry, Access.get( field ) );
107 } 107 }
108 for( CtBehavior behavior : c.getDeclaredBehaviors() ) 108 for( CtMethod method : c.getDeclaredMethods() )
109 {
110 MethodEntry methodEntry = new MethodEntry( classEntry, method.getName(), method.getSignature() );
111 m_access.put( methodEntry, Access.get( method ) );
112 }
113 for( CtConstructor constructor : c.getDeclaredConstructors() )
109 { 114 {
110 MethodEntry methodEntry = new MethodEntry( classEntry, behavior.getName(), behavior.getSignature() ); 115 ConstructorEntry constructorEntry = new ConstructorEntry( classEntry, constructor.getSignature() );
111 m_access.put( methodEntry, Access.get( behavior ) ); 116 m_access.put( constructorEntry, Access.get( constructor ) );
112 } 117 }
113 } 118 }
114 119
@@ -190,6 +195,7 @@ public class JarIndex
190 EntryRenamer.renameClassesInMultimap( renames, m_behaviorReferences ); 195 EntryRenamer.renameClassesInMultimap( renames, m_behaviorReferences );
191 EntryRenamer.renameClassesInMultimap( renames, m_fieldReferences ); 196 EntryRenamer.renameClassesInMultimap( renames, m_fieldReferences );
192 EntryRenamer.renameClassesInMap( renames, m_bridgeMethods ); 197 EntryRenamer.renameClassesInMap( renames, m_bridgeMethods );
198 EntryRenamer.renameClassesInMap( renames, m_access );
193 } 199 }
194 200
195 // step 6: update other indices with bridge method info 201 // step 6: update other indices with bridge method info
diff --git a/src/cuchaz/enigma/mapping/ClassMapping.java b/src/cuchaz/enigma/mapping/ClassMapping.java
index 200d9ca..88006cf 100644
--- a/src/cuchaz/enigma/mapping/ClassMapping.java
+++ b/src/cuchaz/enigma/mapping/ClassMapping.java
@@ -155,6 +155,17 @@ public class ClassMapping implements Serializable, Comparable<ClassMapping>
155 assert( deobfWasAdded ); 155 assert( deobfWasAdded );
156 assert( m_fieldsByObf.size() == m_fieldsByDeobf.size() ); 156 assert( m_fieldsByObf.size() == m_fieldsByDeobf.size() );
157 } 157 }
158
159 public void removeFieldMapping( FieldMapping fieldMapping )
160 {
161 boolean obfWasRemoved = m_fieldsByObf.remove( fieldMapping.getObfName() ) != null;
162 assert( obfWasRemoved );
163 if( fieldMapping.getDeobfName() != null )
164 {
165 boolean deobfWasRemoved = m_fieldsByDeobf.remove( fieldMapping.getDeobfName() ) != null;
166 assert( deobfWasRemoved );
167 }
168 }
158 169
159 public String getObfFieldName( String deobfName ) 170 public String getObfFieldName( String deobfName )
160 { 171 {
@@ -225,6 +236,17 @@ public class ClassMapping implements Serializable, Comparable<ClassMapping>
225 assert( m_methodsByObf.size() >= m_methodsByDeobf.size() ); 236 assert( m_methodsByObf.size() >= m_methodsByDeobf.size() );
226 } 237 }
227 238
239 public void removeMethodMapping( MethodMapping methodMapping )
240 {
241 boolean obfWasRemoved = m_methodsByObf.remove( getMethodKey( methodMapping.getObfName(), methodMapping.getObfSignature() ) ) != null;
242 assert( obfWasRemoved );
243 if( methodMapping.getDeobfName() != null )
244 {
245 boolean deobfWasRemoved = m_methodsByDeobf.remove( getMethodKey( methodMapping.getDeobfName(), methodMapping.getObfSignature() ) ) != null;
246 assert( deobfWasRemoved );
247 }
248 }
249
228 public MethodMapping getMethodByObf( String obfName, String signature ) 250 public MethodMapping getMethodByObf( String obfName, String signature )
229 { 251 {
230 return m_methodsByObf.get( getMethodKey( obfName, signature ) ); 252 return m_methodsByObf.get( getMethodKey( obfName, signature ) );