summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar jeff2014-09-24 20:32:19 -0400
committerGravatar jeff2014-09-24 20:32:19 -0400
commit064fe6a628f23f21eb2c8f584215f439e54cfaec (patch)
tree733f840aca8dca170e9403de51be256b24ed00b2
parentHOW DO I WRITE SO MANY BUGS?!? (diff)
downloadenigma-064fe6a628f23f21eb2c8f584215f439e54cfaec.tar.gz
enigma-064fe6a628f23f21eb2c8f584215f439e54cfaec.tar.xz
enigma-064fe6a628f23f21eb2c8f584215f439e54cfaec.zip
fixed in-jar detection for bridge-related methods
-rw-r--r--src/cuchaz/enigma/Deobfuscator.java39
-rw-r--r--src/cuchaz/enigma/analysis/BridgeFixer.java22
-rw-r--r--src/cuchaz/enigma/analysis/EntryRenamer.java25
-rw-r--r--src/cuchaz/enigma/analysis/JarIndex.java40
-rw-r--r--src/cuchaz/enigma/analysis/SourceIndexClassVisitor.java12
-rw-r--r--src/cuchaz/enigma/bytecode/ClassTranslator.java41
-rw-r--r--src/cuchaz/enigma/mapping/BehaviorEntry.java12
-rw-r--r--src/cuchaz/enigma/mapping/BehaviorEntryFactory.java76
-rw-r--r--src/cuchaz/enigma/mapping/MethodEntry.java4
-rw-r--r--src/cuchaz/enigma/mapping/MethodMapping.java5
10 files changed, 170 insertions, 106 deletions
diff --git a/src/cuchaz/enigma/Deobfuscator.java b/src/cuchaz/enigma/Deobfuscator.java
index f7f74480..9a339176 100644
--- a/src/cuchaz/enigma/Deobfuscator.java
+++ b/src/cuchaz/enigma/Deobfuscator.java
@@ -41,6 +41,8 @@ import cuchaz.enigma.analysis.SourceIndex;
41import cuchaz.enigma.analysis.SourceIndexVisitor; 41import cuchaz.enigma.analysis.SourceIndexVisitor;
42import cuchaz.enigma.analysis.Token; 42import cuchaz.enigma.analysis.Token;
43import cuchaz.enigma.mapping.ArgumentEntry; 43import cuchaz.enigma.mapping.ArgumentEntry;
44import cuchaz.enigma.mapping.BehaviorEntry;
45import cuchaz.enigma.mapping.BehaviorEntryFactory;
44import cuchaz.enigma.mapping.ClassEntry; 46import cuchaz.enigma.mapping.ClassEntry;
45import cuchaz.enigma.mapping.ClassMapping; 47import cuchaz.enigma.mapping.ClassMapping;
46import cuchaz.enigma.mapping.ConstructorEntry; 48import cuchaz.enigma.mapping.ConstructorEntry;
@@ -165,6 +167,12 @@ public class Deobfuscator
165 // methods 167 // methods
166 for( MethodMapping methodMapping : Lists.newArrayList( classMapping.methods() ) ) 168 for( MethodMapping methodMapping : Lists.newArrayList( classMapping.methods() ) )
167 { 169 {
170 // skip constructors
171 if( methodMapping.isConstructor() )
172 {
173 continue;
174 }
175
168 MethodEntry methodEntry = new MethodEntry( obfClassEntry, methodMapping.getObfName(), methodMapping.getObfSignature() ); 176 MethodEntry methodEntry = new MethodEntry( obfClassEntry, methodMapping.getObfName(), methodMapping.getObfSignature() );
169 ClassEntry resolvedObfClassEntry = m_jarIndex.resolveEntryClass( methodEntry ); 177 ClassEntry resolvedObfClassEntry = m_jarIndex.resolveEntryClass( methodEntry );
170 if( resolvedObfClassEntry != null && !resolvedObfClassEntry.equals( methodEntry.getClassEntry() ) ) 178 if( resolvedObfClassEntry != null && !resolvedObfClassEntry.equals( methodEntry.getClassEntry() ) )
@@ -228,33 +236,12 @@ public class Deobfuscator
228 // check methods 236 // check methods
229 for( MethodMapping methodMapping : Lists.newArrayList( classMapping.methods() ) ) 237 for( MethodMapping methodMapping : Lists.newArrayList( classMapping.methods() ) )
230 { 238 {
231 if( methodMapping.getObfName().equals( "<clinit>" ) ) 239 BehaviorEntry obfBehaviorEntry = BehaviorEntryFactory.createObf( classEntry, methodMapping );
232 { 240 if( !m_jarIndex.containsObfBehavior( obfBehaviorEntry ) )
233 // skip static initializers
234 continue;
235 }
236 else if( methodMapping.getObfName().equals( "<init>" ) )
237 {
238 ConstructorEntry constructorEntry = new ConstructorEntry( classEntry, methodMapping.getObfSignature() );
239 if( !m_jarIndex.containsObfBehavior( constructorEntry ) )
240 {
241 System.err.println( "WARNING: unable to find constructor " + constructorEntry + ". dropping mapping." );
242 classMapping.removeMethodMapping( methodMapping );
243 }
244 }
245 else
246 { 241 {
247 MethodEntry methodEntry = new MethodEntry( 242 System.err.println( "WARNING: unable to find behavior " + obfBehaviorEntry + ". dropping mapping." );
248 classEntry, 243 classMapping.removeMethodMapping( methodMapping );
249 methodMapping.getObfName(), 244 }
250 methodMapping.getObfSignature()
251 );
252 if( !m_jarIndex.containsObfBehavior( methodEntry ) )
253 {
254 System.err.println( "WARNING: unable to find method " + methodEntry + ". dropping mapping." );
255 classMapping.removeMethodMapping( methodMapping );
256 }
257 }
258 } 245 }
259 246
260 // check inner classes 247 // check inner classes
diff --git a/src/cuchaz/enigma/analysis/BridgeFixer.java b/src/cuchaz/enigma/analysis/BridgeFixer.java
index aeaf871a..112b864a 100644
--- a/src/cuchaz/enigma/analysis/BridgeFixer.java
+++ b/src/cuchaz/enigma/analysis/BridgeFixer.java
@@ -15,6 +15,8 @@ import javassist.CtMethod;
15import javassist.bytecode.ConstPool; 15import javassist.bytecode.ConstPool;
16import javassist.bytecode.Descriptor; 16import javassist.bytecode.Descriptor;
17import cuchaz.enigma.bytecode.ConstPoolEditor; 17import cuchaz.enigma.bytecode.ConstPoolEditor;
18import cuchaz.enigma.mapping.BehaviorEntry;
19import cuchaz.enigma.mapping.BehaviorEntryFactory;
18import cuchaz.enigma.mapping.ClassEntry; 20import cuchaz.enigma.mapping.ClassEntry;
19import cuchaz.enigma.mapping.MethodEntry; 21import cuchaz.enigma.mapping.MethodEntry;
20 22
@@ -57,17 +59,23 @@ public class BridgeFixer
57 case ConstPool.CONST_Methodref: 59 case ConstPool.CONST_Methodref:
58 case ConstPool.CONST_InterfaceMethodref: 60 case ConstPool.CONST_InterfaceMethodref:
59 { 61 {
60 // translate the name and type 62 BehaviorEntry behaviorEntry = BehaviorEntryFactory.create(
61 MethodEntry methodEntry = new MethodEntry( 63 Descriptor.toJvmName( editor.getMemberrefClassname( i ) ),
62 new ClassEntry( Descriptor.toJvmName( editor.getMemberrefClassname( i ) ) ),
63 editor.getMemberrefName( i ), 64 editor.getMemberrefName( i ),
64 editor.getMemberrefType( i ) 65 editor.getMemberrefType( i )
65 ); 66 );
66 MethodEntry bridgeMethodEntry = m_index.getBridgeMethod( methodEntry ); 67
67 if( bridgeMethodEntry != null ) 68 if( behaviorEntry instanceof MethodEntry )
68 { 69 {
69 // FIXIT FIXIT FIXIT FIXIT FIXIT FIXIT FIXIT 70 MethodEntry methodEntry = (MethodEntry)behaviorEntry;
70 editor.changeMemberrefNameAndType( i, bridgeMethodEntry.getName(), bridgeMethodEntry.getSignature() ); 71
72 // translate the name and type
73 MethodEntry bridgeMethodEntry = m_index.getBridgeMethod( methodEntry );
74 if( bridgeMethodEntry != null )
75 {
76 // FIXIT FIXIT FIXIT FIXIT FIXIT FIXIT FIXIT
77 editor.changeMemberrefNameAndType( i, bridgeMethodEntry.getName(), bridgeMethodEntry.getSignature() );
78 }
71 } 79 }
72 } 80 }
73 break; 81 break;
diff --git a/src/cuchaz/enigma/analysis/EntryRenamer.java b/src/cuchaz/enigma/analysis/EntryRenamer.java
index 44e0220c..2d59fe9d 100644
--- a/src/cuchaz/enigma/analysis/EntryRenamer.java
+++ b/src/cuchaz/enigma/analysis/EntryRenamer.java
@@ -11,7 +11,6 @@
11package cuchaz.enigma.analysis; 11package cuchaz.enigma.analysis;
12 12
13import java.util.AbstractMap; 13import java.util.AbstractMap;
14import java.util.Iterator;
15import java.util.List; 14import java.util.List;
16import java.util.Map; 15import java.util.Map;
17import java.util.Set; 16import java.util.Set;
@@ -80,16 +79,32 @@ public class EntryRenamer
80 { 79 {
81 // for each key/value pair... 80 // for each key/value pair...
82 Set<Map.Entry<Key,Val>> entriesToAdd = Sets.newHashSet(); 81 Set<Map.Entry<Key,Val>> entriesToAdd = Sets.newHashSet();
83 Iterator<Map.Entry<Key,Val>> iter = map.entries().iterator(); 82 for( Map.Entry<Key,Val> entry : map.entries() )
84 while( iter.hasNext() )
85 { 83 {
86 Map.Entry<Key,Val> entry = iter.next();
87 iter.remove();
88 entriesToAdd.add( new AbstractMap.SimpleEntry<Key,Val>( 84 entriesToAdd.add( new AbstractMap.SimpleEntry<Key,Val>(
89 renameMethodsInThing( renames, entry.getKey() ), 85 renameMethodsInThing( renames, entry.getKey() ),
90 renameMethodsInThing( renames, entry.getValue() ) 86 renameMethodsInThing( renames, entry.getValue() )
91 ) ); 87 ) );
92 } 88 }
89 map.clear();
90 for( Map.Entry<Key,Val> entry : entriesToAdd )
91 {
92 map.put( entry.getKey(), entry.getValue() );
93 }
94 }
95
96 public static <Key,Val> void renameMethodsInMap( Map<MethodEntry,MethodEntry> renames, Map<Key,Val> map )
97 {
98 // for each key/value pair...
99 Set<Map.Entry<Key,Val>> entriesToAdd = Sets.newHashSet();
100 for( Map.Entry<Key,Val> entry : map.entrySet() )
101 {
102 entriesToAdd.add( new AbstractMap.SimpleEntry<Key,Val>(
103 renameMethodsInThing( renames, entry.getKey() ),
104 renameMethodsInThing( renames, entry.getValue() )
105 ) );
106 }
107 map.clear();
93 for( Map.Entry<Key,Val> entry : entriesToAdd ) 108 for( Map.Entry<Key,Val> entry : entriesToAdd )
94 { 109 {
95 map.put( entry.getKey(), entry.getValue() ); 110 map.put( entry.getKey(), entry.getValue() );
diff --git a/src/cuchaz/enigma/analysis/JarIndex.java b/src/cuchaz/enigma/analysis/JarIndex.java
index 9f309cec..a2f6bf34 100644
--- a/src/cuchaz/enigma/analysis/JarIndex.java
+++ b/src/cuchaz/enigma/analysis/JarIndex.java
@@ -44,6 +44,7 @@ import cuchaz.enigma.Constants;
44import cuchaz.enigma.bytecode.ClassRenamer; 44import cuchaz.enigma.bytecode.ClassRenamer;
45import cuchaz.enigma.mapping.ArgumentEntry; 45import cuchaz.enigma.mapping.ArgumentEntry;
46import cuchaz.enigma.mapping.BehaviorEntry; 46import cuchaz.enigma.mapping.BehaviorEntry;
47import cuchaz.enigma.mapping.BehaviorEntryFactory;
47import cuchaz.enigma.mapping.ClassEntry; 48import cuchaz.enigma.mapping.ClassEntry;
48import cuchaz.enigma.mapping.ConstructorEntry; 49import cuchaz.enigma.mapping.ConstructorEntry;
49import cuchaz.enigma.mapping.Entry; 50import cuchaz.enigma.mapping.Entry;
@@ -203,6 +204,7 @@ public class JarIndex
203 EntryRenamer.renameMethodsInMultimap( m_bridgeMethods, m_methodImplementations ); 204 EntryRenamer.renameMethodsInMultimap( m_bridgeMethods, m_methodImplementations );
204 EntryRenamer.renameMethodsInMultimap( m_bridgeMethods, m_behaviorReferences ); 205 EntryRenamer.renameMethodsInMultimap( m_bridgeMethods, m_behaviorReferences );
205 EntryRenamer.renameMethodsInMultimap( m_bridgeMethods, m_fieldReferences ); 206 EntryRenamer.renameMethodsInMultimap( m_bridgeMethods, m_fieldReferences );
207 EntryRenamer.renameMethodsInMap( m_bridgeMethods, m_access );
206 } 208 }
207 209
208 private void indexField( CtField field ) 210 private void indexField( CtField field )
@@ -224,21 +226,20 @@ public class JarIndex
224 private void indexBehavior( CtBehavior behavior ) 226 private void indexBehavior( CtBehavior behavior )
225 { 227 {
226 // get the behavior entry 228 // get the behavior entry
227 String className = Descriptor.toJvmName( behavior.getDeclaringClass().getName() ); 229 final BehaviorEntry behaviorEntry = BehaviorEntryFactory.create( behavior );
228 final BehaviorEntry behaviorEntry = getBehaviorEntry( behavior );
229 if( behaviorEntry instanceof MethodEntry ) 230 if( behaviorEntry instanceof MethodEntry )
230 { 231 {
231 MethodEntry methodEntry = (MethodEntry)behaviorEntry; 232 MethodEntry methodEntry = (MethodEntry)behaviorEntry;
232 233
233 // index implementation 234 // index implementation
234 m_methodImplementations.put( className, methodEntry ); 235 m_methodImplementations.put( behaviorEntry.getClassName(), methodEntry );
235 236
236 // look for bridge methods 237 // look for bridge methods
237 CtMethod bridgedMethod = getBridgedMethod( (CtMethod)behavior ); 238 CtMethod bridgedMethod = getBridgedMethod( (CtMethod)behavior );
238 if( bridgedMethod != null ) 239 if( bridgedMethod != null )
239 { 240 {
240 MethodEntry bridgedMethodEntry = new MethodEntry( 241 MethodEntry bridgedMethodEntry = new MethodEntry(
241 new ClassEntry( className ), 242 behaviorEntry.getClassEntry(),
242 bridgedMethod.getName(), 243 bridgedMethod.getName(),
243 bridgedMethod.getSignature() 244 bridgedMethod.getSignature()
244 ); 245 );
@@ -251,7 +252,7 @@ public class JarIndex
251 private void indexBehaviorReferences( CtBehavior behavior ) 252 private void indexBehaviorReferences( CtBehavior behavior )
252 { 253 {
253 // index method calls 254 // index method calls
254 final BehaviorEntry behaviorEntry = getBehaviorEntry( behavior ); 255 final BehaviorEntry behaviorEntry = BehaviorEntryFactory.create( behavior );
255 try 256 try
256 { 257 {
257 behavior.instrument( new ExprEditor( ) 258 behavior.instrument( new ExprEditor( )
@@ -344,35 +345,6 @@ public class JarIndex
344 } 345 }
345 } 346 }
346 347
347 private BehaviorEntry getBehaviorEntry( CtBehavior behavior )
348 {
349 String className = Descriptor.toJvmName( behavior.getDeclaringClass().getName() );
350 if( behavior instanceof CtMethod )
351 {
352 return new MethodEntry(
353 new ClassEntry( className ),
354 behavior.getName(),
355 behavior.getSignature()
356 );
357 }
358 else if( behavior instanceof CtConstructor )
359 {
360 boolean isStatic = behavior.getName().equals( "<clinit>" );
361 if( isStatic )
362 {
363 return new ConstructorEntry( new ClassEntry( className ) );
364 }
365 else
366 {
367 return new ConstructorEntry( new ClassEntry( className ), behavior.getSignature() );
368 }
369 }
370 else
371 {
372 throw new IllegalArgumentException( "behavior must be a method or a constructor!" );
373 }
374 }
375
376 public ClassEntry resolveEntryClass( Entry obfEntry ) 348 public ClassEntry resolveEntryClass( Entry obfEntry )
377 { 349 {
378 // this entry could refer to a method on a class where the method is not actually implemented 350 // this entry could refer to a method on a class where the method is not actually implemented
diff --git a/src/cuchaz/enigma/analysis/SourceIndexClassVisitor.java b/src/cuchaz/enigma/analysis/SourceIndexClassVisitor.java
index b7897268..5d8a3833 100644
--- a/src/cuchaz/enigma/analysis/SourceIndexClassVisitor.java
+++ b/src/cuchaz/enigma/analysis/SourceIndexClassVisitor.java
@@ -25,11 +25,11 @@ import com.strobel.decompiler.languages.java.ast.TypeDeclaration;
25import com.strobel.decompiler.languages.java.ast.VariableInitializer; 25import com.strobel.decompiler.languages.java.ast.VariableInitializer;
26 26
27import cuchaz.enigma.mapping.BehaviorEntry; 27import cuchaz.enigma.mapping.BehaviorEntry;
28import cuchaz.enigma.mapping.BehaviorEntryFactory;
28import cuchaz.enigma.mapping.ClassEntry; 29import cuchaz.enigma.mapping.ClassEntry;
29import cuchaz.enigma.mapping.ConstructorEntry; 30import cuchaz.enigma.mapping.ConstructorEntry;
30import cuchaz.enigma.mapping.Entry; 31import cuchaz.enigma.mapping.Entry;
31import cuchaz.enigma.mapping.FieldEntry; 32import cuchaz.enigma.mapping.FieldEntry;
32import cuchaz.enigma.mapping.MethodEntry;
33 33
34public class SourceIndexClassVisitor extends SourceIndexVisitor 34public class SourceIndexClassVisitor extends SourceIndexVisitor
35{ 35{
@@ -77,15 +77,7 @@ public class SourceIndexClassVisitor extends SourceIndexVisitor
77 { 77 {
78 MethodDefinition def = node.getUserData( Keys.METHOD_DEFINITION ); 78 MethodDefinition def = node.getUserData( Keys.METHOD_DEFINITION );
79 ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() ); 79 ClassEntry classEntry = new ClassEntry( def.getDeclaringType().getInternalName() );
80 BehaviorEntry behaviorEntry; 80 BehaviorEntry behaviorEntry = BehaviorEntryFactory.create( classEntry, def.getName(), def.getSignature() );
81 if( def.getName().equals( "<clinit>" ) )
82 {
83 behaviorEntry = new ConstructorEntry( classEntry );
84 }
85 else
86 {
87 behaviorEntry = new MethodEntry( classEntry, def.getName(), def.getSignature() );
88 }
89 index.addDeclaration( node.getNameToken(), behaviorEntry ); 81 index.addDeclaration( node.getNameToken(), behaviorEntry );
90 return node.acceptVisitor( new SourceIndexBehaviorVisitor( behaviorEntry ), index ); 82 return node.acceptVisitor( new SourceIndexBehaviorVisitor( behaviorEntry ), index );
91 } 83 }
diff --git a/src/cuchaz/enigma/bytecode/ClassTranslator.java b/src/cuchaz/enigma/bytecode/ClassTranslator.java
index 88926928..db28f21b 100644
--- a/src/cuchaz/enigma/bytecode/ClassTranslator.java
+++ b/src/cuchaz/enigma/bytecode/ClassTranslator.java
@@ -21,6 +21,8 @@ import javassist.bytecode.Descriptor;
21 21
22import com.google.common.collect.Maps; 22import com.google.common.collect.Maps;
23 23
24import cuchaz.enigma.mapping.BehaviorEntry;
25import cuchaz.enigma.mapping.BehaviorEntryFactory;
24import cuchaz.enigma.mapping.ClassEntry; 26import cuchaz.enigma.mapping.ClassEntry;
25import cuchaz.enigma.mapping.FieldEntry; 27import cuchaz.enigma.mapping.FieldEntry;
26import cuchaz.enigma.mapping.MethodEntry; 28import cuchaz.enigma.mapping.MethodEntry;
@@ -53,19 +55,15 @@ public class ClassTranslator
53 new ClassEntry( Descriptor.toJvmName( constants.getFieldrefClassName( i ) ) ), 55 new ClassEntry( Descriptor.toJvmName( constants.getFieldrefClassName( i ) ) ),
54 constants.getFieldrefName( i ) 56 constants.getFieldrefName( i )
55 ); 57 );
56 String translatedName = m_translator.translate( entry ); 58 FieldEntry translatedEntry = m_translator.translateEntry( entry );
57 if( translatedName == null )
58 {
59 translatedName = entry.getName();
60 }
61 59
62 // translate the type 60 // translate the type
63 String type = constants.getFieldrefType( i ); 61 String type = constants.getFieldrefType( i );
64 String translatedType = m_translator.translateSignature( type ); 62 String translatedType = m_translator.translateSignature( type );
65 63
66 if( !entry.getName().equals( translatedName ) || !type.equals( translatedType ) ) 64 if( !entry.equals( translatedEntry ) || !type.equals( translatedType ) )
67 { 65 {
68 editor.changeMemberrefNameAndType( i, translatedName, translatedType ); 66 editor.changeMemberrefNameAndType( i, translatedEntry.getName(), translatedType );
69 } 67 }
70 } 68 }
71 break; 69 break;
@@ -74,21 +72,16 @@ public class ClassTranslator
74 case ConstPool.CONST_InterfaceMethodref: 72 case ConstPool.CONST_InterfaceMethodref:
75 { 73 {
76 // translate the name and type 74 // translate the name and type
77 MethodEntry entry = new MethodEntry( 75 BehaviorEntry entry = BehaviorEntryFactory.create(
78 new ClassEntry( Descriptor.toJvmName( editor.getMemberrefClassname( i ) ) ), 76 Descriptor.toJvmName( editor.getMemberrefClassname( i ) ),
79 editor.getMemberrefName( i ), 77 editor.getMemberrefName( i ),
80 editor.getMemberrefType( i ) 78 editor.getMemberrefType( i )
81 ); 79 );
82 String translatedName = m_translator.translate( entry ); 80 BehaviorEntry translatedEntry = m_translator.translateEntry( entry );
83 if( translatedName == null )
84 {
85 translatedName = entry.getName();
86 }
87 String translatedSignature = m_translator.translateSignature( entry.getSignature() );
88 81
89 if( !entry.getName().equals( translatedName ) || !entry.getSignature().equals( translatedSignature ) ) 82 if( !entry.getName().equals( translatedEntry.getName() ) || !entry.getSignature().equals( translatedEntry.getSignature() ) )
90 { 83 {
91 editor.changeMemberrefNameAndType( i, translatedName, translatedSignature ); 84 editor.changeMemberrefNameAndType( i, translatedEntry.getName(), translatedEntry.getSignature() );
92 } 85 }
93 } 86 }
94 break; 87 break;
@@ -116,14 +109,16 @@ public class ClassTranslator
116 // translate all the methods and constructors 109 // translate all the methods and constructors
117 for( CtBehavior behavior : c.getDeclaredBehaviors() ) 110 for( CtBehavior behavior : c.getDeclaredBehaviors() )
118 { 111 {
119 // translate the name 112 if( behavior instanceof CtMethod )
120 MethodEntry entry = new MethodEntry( classEntry, behavior.getName(), behavior.getSignature() );
121 String translatedName = m_translator.translate( entry );
122 if( translatedName != null )
123 { 113 {
124 if( behavior instanceof CtMethod ) 114 CtMethod method = (CtMethod)behavior;
115
116 // translate the name
117 MethodEntry entry = new MethodEntry( classEntry, method.getName(), method.getSignature() );
118 String translatedName = m_translator.translate( entry );
119 if( translatedName != null )
125 { 120 {
126 ((CtMethod)behavior).setName( translatedName ); 121 method.setName( translatedName );
127 } 122 }
128 } 123 }
129 124
diff --git a/src/cuchaz/enigma/mapping/BehaviorEntry.java b/src/cuchaz/enigma/mapping/BehaviorEntry.java
index 99fdd28d..8fc4eaf0 100644
--- a/src/cuchaz/enigma/mapping/BehaviorEntry.java
+++ b/src/cuchaz/enigma/mapping/BehaviorEntry.java
@@ -1,6 +1,16 @@
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 ******************************************************************************/
1package cuchaz.enigma.mapping; 11package cuchaz.enigma.mapping;
2 12
3public interface BehaviorEntry extends Entry 13public interface BehaviorEntry extends Entry
4{ 14{
5 public String getSignature(); 15 String getSignature();
6} 16}
diff --git a/src/cuchaz/enigma/mapping/BehaviorEntryFactory.java b/src/cuchaz/enigma/mapping/BehaviorEntryFactory.java
new file mode 100644
index 00000000..d3cfb938
--- /dev/null
+++ b/src/cuchaz/enigma/mapping/BehaviorEntryFactory.java
@@ -0,0 +1,76 @@
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 ******************************************************************************/
11package cuchaz.enigma.mapping;
12
13import javassist.CtBehavior;
14import javassist.CtConstructor;
15import javassist.CtMethod;
16import javassist.bytecode.Descriptor;
17
18
19public class BehaviorEntryFactory
20{
21 public static BehaviorEntry create( String className, String name, String signature )
22 {
23 return create( new ClassEntry( className ), name, signature );
24 }
25
26 public static BehaviorEntry create( ClassEntry classEntry, String name, String signature )
27 {
28 if( name.equals( "<init>" ) )
29 {
30 return new ConstructorEntry( classEntry, signature );
31 }
32 else if( name.equals( "<clinit>" ) )
33 {
34 return new ConstructorEntry( classEntry );
35 }
36 else
37 {
38 return new MethodEntry( classEntry, name, signature );
39 }
40 }
41
42 public static BehaviorEntry create( CtBehavior behavior )
43 {
44 String className = Descriptor.toJvmName( behavior.getDeclaringClass().getName() );
45 if( behavior instanceof CtMethod )
46 {
47 return create( className, behavior.getName(), behavior.getSignature() );
48 }
49 else if( behavior instanceof CtConstructor )
50 {
51 CtConstructor constructor = (CtConstructor)behavior;
52 if( constructor.isClassInitializer() )
53 {
54 return create( className, "<clinit>", null );
55 }
56 else
57 {
58 return create( className, "<init>", constructor.getSignature() );
59 }
60 }
61 else
62 {
63 throw new IllegalArgumentException( "Unable to create BehaviorEntry from " + behavior );
64 }
65 }
66
67 public static BehaviorEntry createObf( ClassEntry classEntry, MethodMapping methodMapping )
68 {
69 return create( classEntry, methodMapping.getObfName(), methodMapping.getObfSignature() );
70 }
71
72 public static BehaviorEntry createDeobf( ClassEntry classEntry, MethodMapping methodMapping )
73 {
74 return create( classEntry, methodMapping.getDeobfName(), methodMapping.getObfSignature() );
75 }
76}
diff --git a/src/cuchaz/enigma/mapping/MethodEntry.java b/src/cuchaz/enigma/mapping/MethodEntry.java
index 8adbfe9c..dbc18855 100644
--- a/src/cuchaz/enigma/mapping/MethodEntry.java
+++ b/src/cuchaz/enigma/mapping/MethodEntry.java
@@ -36,6 +36,10 @@ public class MethodEntry implements BehaviorEntry, Serializable
36 { 36 {
37 throw new IllegalArgumentException( "Method signature cannot be null!" ); 37 throw new IllegalArgumentException( "Method signature cannot be null!" );
38 } 38 }
39 if( name.startsWith( "<" ) )
40 {
41 throw new IllegalArgumentException( "Don't use MethodEntry for a constructor!" );
42 }
39 43
40 m_classEntry = classEntry; 44 m_classEntry = classEntry;
41 m_name = name; 45 m_name = name;
diff --git a/src/cuchaz/enigma/mapping/MethodMapping.java b/src/cuchaz/enigma/mapping/MethodMapping.java
index 6210fd09..b076fa33 100644
--- a/src/cuchaz/enigma/mapping/MethodMapping.java
+++ b/src/cuchaz/enigma/mapping/MethodMapping.java
@@ -70,6 +70,11 @@ public class MethodMapping implements Serializable, Comparable<MethodMapping>
70 return m_arguments.values(); 70 return m_arguments.values();
71 } 71 }
72 72
73 public boolean isConstructor( )
74 {
75 return m_obfName.startsWith( "<" );
76 }
77
73 public void addArgumentMapping( ArgumentMapping argumentMapping ) 78 public void addArgumentMapping( ArgumentMapping argumentMapping )
74 { 79 {
75 boolean wasAdded = m_arguments.put( argumentMapping.getIndex(), argumentMapping ) == null; 80 boolean wasAdded = m_arguments.put( argumentMapping.getIndex(), argumentMapping ) == null;