From d7321b5b0d38c575e54c770f7aa18dacbacab3c8 Mon Sep 17 00:00:00 2001 From: jeff Date: Sun, 27 Jul 2014 22:33:21 -0400 Subject: added identifier renaming capability copied some code over from M3L to handle the heavy bytecode magic. It's ok... M3L will eventually depend on Enigma. Completely restructured the mappings though. This way is better. =) --- src/cuchaz/enigma/mapping/TranslationMappings.java | 187 +++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 src/cuchaz/enigma/mapping/TranslationMappings.java (limited to 'src/cuchaz/enigma/mapping/TranslationMappings.java') diff --git a/src/cuchaz/enigma/mapping/TranslationMappings.java b/src/cuchaz/enigma/mapping/TranslationMappings.java new file mode 100644 index 0000000..d6cd449 --- /dev/null +++ b/src/cuchaz/enigma/mapping/TranslationMappings.java @@ -0,0 +1,187 @@ +/******************************************************************************* + * Copyright (c) 2014 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Public License v3.0 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/gpl.html + * + * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.mapping; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.Serializable; +import java.util.Map; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +import com.beust.jcommander.internal.Maps; + +import cuchaz.enigma.Util; + +public class TranslationMappings implements Serializable +{ + private static final long serialVersionUID = 4649790259460259026L; + + private Map m_classesByObf; + private Map m_classesByDeobf; + private Ancestries m_ancestries; + + public TranslationMappings( Ancestries ancestries ) + { + m_classesByObf = Maps.newHashMap(); + m_classesByDeobf = Maps.newHashMap(); + m_ancestries = ancestries; + } + + public static TranslationMappings newFromResource( String resource ) + throws IOException + { + InputStream in = null; + try + { + in = TranslationMappings.class.getResourceAsStream( resource ); + return newFromStream( in ); + } + finally + { + Util.closeQuietly( in ); + } + } + + public Translator getTranslator( TranslationDirection direction ) + { + return new Translator( + direction, + direction.choose( m_classesByObf, m_classesByDeobf ), + direction.choose( m_ancestries, new DeobfuscatedAncestries( m_ancestries, m_classesByObf, m_classesByDeobf ) ) + ); + } + + public void setClassName( ClassEntry obf, String deobfName ) + { + ClassIndex classIndex = m_classesByObf.get( obf.getName() ); + if( classIndex == null ) + { + classIndex = createClassIndex( obf ); + } + + m_classesByDeobf.remove( classIndex.getDeobfName() ); + classIndex.setDeobfName( deobfName ); + m_classesByDeobf.put( deobfName, classIndex ); + + updateDeobfMethodSignatures(); + + // TEMP + String translatedName = getTranslator( TranslationDirection.Deobfuscating ).translate( obf ); + assert( translatedName != null && translatedName.equals( deobfName ) ); + } + + public void setFieldName( FieldEntry obf, String deobfName ) + { + ClassIndex classIndex = m_classesByObf.get( obf.getClassName() ); + if( classIndex == null ) + { + classIndex = createClassIndex( obf.getClassEntry() ); + } + + classIndex.setFieldName( obf.getName(), deobfName ); + + // TEMP + System.out.println( classIndex ); + String translatedName = getTranslator( TranslationDirection.Deobfuscating ).translate( obf ); + assert( translatedName != null && translatedName.equals( deobfName ) ); + } + + public void setMethodName( MethodEntry obf, String deobfName ) + { + ClassIndex classIndex = m_classesByObf.get( obf.getClassName() ); + if( classIndex == null ) + { + classIndex = createClassIndex( obf.getClassEntry() ); + } + + String deobfSignature = getTranslator( TranslationDirection.Deobfuscating ).translateSignature( obf.getSignature() ); + classIndex.setMethodNameAndSignature( obf.getName(), obf.getSignature(), deobfName, deobfSignature ); + + // TODO: update ancestor/descendant methods in other classes in the inheritance hierarchy too + + // TEMP + System.out.println( classIndex ); + String translatedName = getTranslator( TranslationDirection.Deobfuscating ).translate( obf ); + assert( translatedName != null && translatedName.equals( deobfName ) ); + } + + public void setArgumentName( ArgumentEntry obf, String deobfName ) + { + ClassIndex classIndex = m_classesByObf.get( obf.getClassName() ); + if( classIndex == null ) + { + classIndex = createClassIndex( obf.getClassEntry() ); + } + + classIndex.setArgumentName( obf.getMethodName(), obf.getMethodSignature(), obf.getIndex(), obf.getName(), deobfName ); + + // TEMP + System.out.println( classIndex ); + String translatedName = getTranslator( TranslationDirection.Deobfuscating ).translate( obf ); + assert( translatedName != null && translatedName.equals( deobfName ) ); + } + + public void write( OutputStream out ) + throws IOException + { + // TEMP: just use the object output for now. We can find a more efficient storage format later + GZIPOutputStream gzipout = new GZIPOutputStream( out ); + ObjectOutputStream oout = new ObjectOutputStream( gzipout ); + oout.writeObject( this ); + gzipout.finish(); + } + + public static TranslationMappings newFromStream( InputStream in ) + throws IOException + { + try + { + return (TranslationMappings)new ObjectInputStream( new GZIPInputStream( in ) ).readObject(); + } + catch( ClassNotFoundException ex ) + { + throw new Error( ex ); + } + } + + private ClassIndex createClassIndex( ClassEntry obf ) + { + ClassIndex classIndex = new ClassIndex( obf.getName(), obf.getName() ); + m_classesByObf.put( classIndex.getObfName(), classIndex ); + m_classesByDeobf.put( classIndex.getDeobfName(), classIndex ); + return classIndex; + } + + private void updateDeobfMethodSignatures( ) + { + Translator translator = getTranslator( TranslationDirection.Deobfuscating ); + for( ClassIndex classIndex : m_classesByObf.values() ) + { + classIndex.updateDeobfMethodSignatures( translator ); + } + } + + @Override + public String toString( ) + { + StringBuilder buf = new StringBuilder(); + for( ClassIndex classIndex : m_classesByObf.values() ) + { + buf.append( classIndex.toString() ); + buf.append( "\n" ); + } + return buf.toString(); + } +} -- cgit v1.2.3