From 66a81e7dbe4c48c0ffdca043b6d22bb42034440c Mon Sep 17 00:00:00 2001 From: Christian Date: Sun, 27 Jan 2013 21:50:08 -0500 Subject: [PATCH] Method deobfuscation now works --- .../mods/fml/common/asm/FMLSanityChecker.java | 2 +- .../DeobfuscationTransformer.java | 3 +- .../deobf/FMLDeobfuscatingRemapper.java | 119 +++++++++++++++--- .../deobf/FMLRemappingAdapter.java | 1 + .../fml/relauncher/RelaunchClassLoader.java | 2 + 5 files changed, 108 insertions(+), 19 deletions(-) diff --git a/common/cpw/mods/fml/common/asm/FMLSanityChecker.java b/common/cpw/mods/fml/common/asm/FMLSanityChecker.java index a3d628698f..8359e10a8e 100644 --- a/common/cpw/mods/fml/common/asm/FMLSanityChecker.java +++ b/common/cpw/mods/fml/common/asm/FMLSanityChecker.java @@ -126,7 +126,7 @@ public class FMLSanityChecker implements IFMLCallHook public void injectData(Map data) { cl = (RelaunchClassLoader) data.get("classLoader"); - FMLDeobfuscatingRemapper.INSTANCE.setup((File)data.get("mcLocation")); + FMLDeobfuscatingRemapper.INSTANCE.setup((File)data.get("mcLocation"), cl); } } diff --git a/common/cpw/mods/fml/common/asm/transformers/DeobfuscationTransformer.java b/common/cpw/mods/fml/common/asm/transformers/DeobfuscationTransformer.java index 2661b0532a..6e0c0a426f 100644 --- a/common/cpw/mods/fml/common/asm/transformers/DeobfuscationTransformer.java +++ b/common/cpw/mods/fml/common/asm/transformers/DeobfuscationTransformer.java @@ -7,6 +7,7 @@ import org.objectweb.asm.commons.RemappingClassAdapter; import org.objectweb.asm.tree.ClassNode; import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper; +import cpw.mods.fml.common.asm.transformers.deobf.FMLRemappingAdapter; import cpw.mods.fml.relauncher.IClassNameTransformer; import cpw.mods.fml.relauncher.IClassTransformer; @@ -22,7 +23,7 @@ public class DeobfuscationTransformer implements IClassTransformer, IClassNameTr } ClassReader classReader = new ClassReader(bytes); ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS); - RemappingClassAdapter remapAdapter = new RemappingClassAdapter(classWriter, FMLDeobfuscatingRemapper.INSTANCE); + RemappingClassAdapter remapAdapter = new FMLRemappingAdapter(classWriter); classReader.accept(remapAdapter, ClassReader.EXPAND_FRAMES); return classWriter.toByteArray(); } diff --git a/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java b/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java index c05a6a5e35..b814bc7f3a 100644 --- a/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java +++ b/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java @@ -5,37 +5,51 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.Charset; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.logging.Level; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; +import org.objectweb.asm.ClassReader; import org.objectweb.asm.commons.Remapper; import com.google.common.base.Charsets; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import com.google.common.collect.ImmutableBiMap; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import com.google.common.collect.ImmutableBiMap.Builder; import com.google.common.io.CharStreams; import com.google.common.io.InputSupplier; import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.relauncher.FMLRelaunchLog; +import cpw.mods.fml.relauncher.RelaunchClassLoader; public class FMLDeobfuscatingRemapper extends Remapper { public static final FMLDeobfuscatingRemapper INSTANCE = new FMLDeobfuscatingRemapper(); private BiMap classNameBiMap; + private Map> rawFieldMaps; + private Map> rawMethodMaps; - private boolean isLoaded = false; + private Map> fieldNameMaps; + private Map> methodNameMaps; + + private RelaunchClassLoader classLoader; private FMLDeobfuscatingRemapper() { } - public void setup(File mcDir) + public void setup(File mcDir, RelaunchClassLoader classLoader) { + this.classLoader = classLoader; try { File libDir = new File(mcDir, "lib"); @@ -52,25 +66,42 @@ public class FMLDeobfuscatingRemapper extends Remapper { builder.put(parts[0],parts[1]); } classNameBiMap = builder.build(); + + ZipEntry methodData = mapZip.getEntry("method_data.csv"); + zis = new ZipInputSupplier(mapZip, methodData); + InputSupplier methodNameSupplier = CharStreams.newReaderSupplier(zis,Charsets.UTF_8); + List methodList = CharStreams.readLines(methodNameSupplier); + rawMethodMaps = Maps.newHashMap(); + for (String line : methodList) + { + String[] parts = line.split(","); + String oldSrg = parts[0]; + int lastOld = oldSrg.lastIndexOf('/'); + String cl = oldSrg.substring(0,lastOld); + String oldName = oldSrg.substring(lastOld+1); + String sig = parts[1]; + String newSrg = parts[2]; + int lastNew = newSrg.lastIndexOf('/'); + String newName = newSrg.substring(lastNew+1); + if (!rawMethodMaps.containsKey(cl)) + { + rawMethodMaps.put(cl, Maps.newHashMap()); + } + rawMethodMaps.get(cl).put(oldName+sig, newName); + } } catch (IOException ioe) { - FMLRelaunchLog.log(Level.SEVERE, ioe, "An error occurred loading the class map data"); + FMLRelaunchLog.log(Level.SEVERE, ioe, "An error occurred loading the deobfuscation map data"); } + methodNameMaps = Maps.newHashMapWithExpectedSize(rawMethodMaps.size()); } -// @Override -// public String mapFieldName(String owner, String name, String desc) -// { -// System.out.println("+++" + owner + "."+name+"."+desc); -// if (owner.indexOf('/')<0) -// { -// return "lexManosWasHere"+name; -// } -// else -// { -// return name; -// } -// } + @Override + public String mapFieldName(String owner, String name, String desc) + { + return name; + } + @Override public String map(String typeName) { @@ -80,7 +111,6 @@ public class FMLDeobfuscatingRemapper extends Remapper { } String result = classNameBiMap.containsKey(typeName) ? classNameBiMap.get(typeName) : typeName; - System.out.printf("Remapping %s to %s\n", typeName, result); return result; } @@ -92,4 +122,59 @@ public class FMLDeobfuscatingRemapper extends Remapper { } return classNameBiMap.containsValue(typeName) ? classNameBiMap.inverse().get(typeName) : typeName; } + + + @Override + public String mapMethodName(String owner, String name, String desc) + { + if (classNameBiMap==null || !classNameBiMap.containsKey(owner)) + { + return name; + } + Map methodMap = getMethodMap(owner); + String methodDescriptor = name+desc; + return methodMap.containsKey(methodDescriptor) ? methodMap.get(methodDescriptor) : name; + } + + private Map getMethodMap(String className) + { + if (!methodNameMaps.containsKey(className)) + { + findAndMergeSuperMaps(className); + } + return methodNameMaps.get(className); + } + + private void findAndMergeSuperMaps(String name) + { + try + { + byte[] classBytes = classLoader.getClassBytes(name); + ClassReader cr = new ClassReader(classBytes); + String superName = cr.getSuperName(); + mergeSuperMaps(name, superName); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + public void mergeSuperMaps(String name, String superName) + { + if (classNameBiMap == null || !classNameBiMap.containsKey(name)) + { + return; + } + if (superName != null && classNameBiMap.containsKey(superName) && !methodNameMaps.containsKey(superName)) + { + findAndMergeSuperMaps(superName); + } + FMLLog.info("Merging maps for %s (%s)", name, superName); + Map methodMap = methodNameMaps.containsKey(superName) ? Maps.newHashMap(methodNameMaps.get(superName)) : Maps.newHashMap(); + if (rawMethodMaps.containsKey(name)) + { + methodMap.putAll(rawMethodMaps.get(name)); + } + methodNameMaps.put(name, ImmutableMap.copyOf(methodMap)); + } } diff --git a/common/cpw/mods/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java b/common/cpw/mods/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java index 37ff609df6..c52b353b6a 100644 --- a/common/cpw/mods/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java +++ b/common/cpw/mods/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java @@ -13,6 +13,7 @@ public class FMLRemappingAdapter extends RemappingClassAdapter { @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { + FMLDeobfuscatingRemapper.INSTANCE.mergeSuperMaps(name, superName); super.visit(version, access, name, signature, superName, interfaces); } } diff --git a/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java b/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java index 7b535e1e87..865c051f8c 100644 --- a/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java +++ b/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java @@ -69,6 +69,8 @@ public class RelaunchClassLoader extends URLClassLoader addTransformerExclusion("javax."); addTransformerExclusion("org.objectweb.asm."); addTransformerExclusion("com.google.common."); + addTransformerExclusion("org.bouncycastle."); + addTransformerExclusion("cpw.mods.fml.common.asm.transformers.deobf."); } public void registerTransformer(String transformerClassName)