diff options
| author | 2014-09-24 20:32:19 -0400 | |
|---|---|---|
| committer | 2014-09-24 20:32:19 -0400 | |
| commit | 064fe6a628f23f21eb2c8f584215f439e54cfaec (patch) | |
| tree | 733f840aca8dca170e9403de51be256b24ed00b2 /src/cuchaz/enigma/analysis | |
| parent | HOW DO I WRITE SO MANY BUGS?!? (diff) | |
| download | enigma-fork-064fe6a628f23f21eb2c8f584215f439e54cfaec.tar.gz enigma-fork-064fe6a628f23f21eb2c8f584215f439e54cfaec.tar.xz enigma-fork-064fe6a628f23f21eb2c8f584215f439e54cfaec.zip | |
fixed in-jar detection for bridge-related methods
Diffstat (limited to 'src/cuchaz/enigma/analysis')
| -rw-r--r-- | src/cuchaz/enigma/analysis/BridgeFixer.java | 22 | ||||
| -rw-r--r-- | src/cuchaz/enigma/analysis/EntryRenamer.java | 25 | ||||
| -rw-r--r-- | src/cuchaz/enigma/analysis/JarIndex.java | 40 | ||||
| -rw-r--r-- | src/cuchaz/enigma/analysis/SourceIndexClassVisitor.java | 12 |
4 files changed, 43 insertions, 56 deletions
diff --git a/src/cuchaz/enigma/analysis/BridgeFixer.java b/src/cuchaz/enigma/analysis/BridgeFixer.java index aeaf871..112b864 100644 --- a/src/cuchaz/enigma/analysis/BridgeFixer.java +++ b/src/cuchaz/enigma/analysis/BridgeFixer.java | |||
| @@ -15,6 +15,8 @@ import javassist.CtMethod; | |||
| 15 | import javassist.bytecode.ConstPool; | 15 | import javassist.bytecode.ConstPool; |
| 16 | import javassist.bytecode.Descriptor; | 16 | import javassist.bytecode.Descriptor; |
| 17 | import cuchaz.enigma.bytecode.ConstPoolEditor; | 17 | import cuchaz.enigma.bytecode.ConstPoolEditor; |
| 18 | import cuchaz.enigma.mapping.BehaviorEntry; | ||
| 19 | import cuchaz.enigma.mapping.BehaviorEntryFactory; | ||
| 18 | import cuchaz.enigma.mapping.ClassEntry; | 20 | import cuchaz.enigma.mapping.ClassEntry; |
| 19 | import cuchaz.enigma.mapping.MethodEntry; | 21 | import 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 44e0220..2d59fe9 100644 --- a/src/cuchaz/enigma/analysis/EntryRenamer.java +++ b/src/cuchaz/enigma/analysis/EntryRenamer.java | |||
| @@ -11,7 +11,6 @@ | |||
| 11 | package cuchaz.enigma.analysis; | 11 | package cuchaz.enigma.analysis; |
| 12 | 12 | ||
| 13 | import java.util.AbstractMap; | 13 | import java.util.AbstractMap; |
| 14 | import java.util.Iterator; | ||
| 15 | import java.util.List; | 14 | import java.util.List; |
| 16 | import java.util.Map; | 15 | import java.util.Map; |
| 17 | import java.util.Set; | 16 | import 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 9f309ce..a2f6bf3 100644 --- a/src/cuchaz/enigma/analysis/JarIndex.java +++ b/src/cuchaz/enigma/analysis/JarIndex.java | |||
| @@ -44,6 +44,7 @@ import cuchaz.enigma.Constants; | |||
| 44 | import cuchaz.enigma.bytecode.ClassRenamer; | 44 | import cuchaz.enigma.bytecode.ClassRenamer; |
| 45 | import cuchaz.enigma.mapping.ArgumentEntry; | 45 | import cuchaz.enigma.mapping.ArgumentEntry; |
| 46 | import cuchaz.enigma.mapping.BehaviorEntry; | 46 | import cuchaz.enigma.mapping.BehaviorEntry; |
| 47 | import cuchaz.enigma.mapping.BehaviorEntryFactory; | ||
| 47 | import cuchaz.enigma.mapping.ClassEntry; | 48 | import cuchaz.enigma.mapping.ClassEntry; |
| 48 | import cuchaz.enigma.mapping.ConstructorEntry; | 49 | import cuchaz.enigma.mapping.ConstructorEntry; |
| 49 | import cuchaz.enigma.mapping.Entry; | 50 | import 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 b789726..5d8a383 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; | |||
| 25 | import com.strobel.decompiler.languages.java.ast.VariableInitializer; | 25 | import com.strobel.decompiler.languages.java.ast.VariableInitializer; |
| 26 | 26 | ||
| 27 | import cuchaz.enigma.mapping.BehaviorEntry; | 27 | import cuchaz.enigma.mapping.BehaviorEntry; |
| 28 | import cuchaz.enigma.mapping.BehaviorEntryFactory; | ||
| 28 | import cuchaz.enigma.mapping.ClassEntry; | 29 | import cuchaz.enigma.mapping.ClassEntry; |
| 29 | import cuchaz.enigma.mapping.ConstructorEntry; | 30 | import cuchaz.enigma.mapping.ConstructorEntry; |
| 30 | import cuchaz.enigma.mapping.Entry; | 31 | import cuchaz.enigma.mapping.Entry; |
| 31 | import cuchaz.enigma.mapping.FieldEntry; | 32 | import cuchaz.enigma.mapping.FieldEntry; |
| 32 | import cuchaz.enigma.mapping.MethodEntry; | ||
| 33 | 33 | ||
| 34 | public class SourceIndexClassVisitor extends SourceIndexVisitor | 34 | public 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 | } |