From 03bc9cf00a99c835b14172df3c9443905ae6e829 Mon Sep 17 00:00:00 2001 From: Agaricus Date: Sun, 14 Apr 2013 15:02:26 -0700 Subject: [PATCH 1/2] Add type info to properly deobfuscate overloaded fields. Fixes #210. --- .../deobf/FMLDeobfuscatingRemapper.java | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/fml/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java b/fml/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java index 356a65f67..c5d7f30ab 100644 --- a/fml/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java +++ b/fml/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java @@ -49,6 +49,8 @@ import com.google.common.io.InputSupplier; import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.relauncher.FMLRelaunchLog; import cpw.mods.fml.relauncher.RelaunchClassLoader; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.FieldNode; public class FMLDeobfuscatingRemapper extends Remapper { public static final FMLDeobfuscatingRemapper INSTANCE = new FMLDeobfuscatingRemapper(); @@ -142,7 +144,34 @@ public class FMLDeobfuscatingRemapper extends Remapper { { rawFieldMaps.put(cl, Maps.newHashMap()); } - rawFieldMaps.get(cl).put(oldName, newName); + rawFieldMaps.get(cl).put(oldName + ":" + getFieldType(cl, oldName), newName); + rawFieldMaps.get(cl).put(oldName + ":null", newName); + } + + @SuppressWarnings("unchecked") + private String getFieldType(String owner, String name) + { + try + { + byte[] classBytes = classLoader.getClassBytes(owner); + if (classBytes == null) + { + return null; + } + ClassReader cr = new ClassReader(classBytes); + ClassNode classNode = new ClassNode(); + cr.accept(classNode, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); + for (FieldNode fieldNode : (List) classNode.fields) { + if (fieldNode.name.equals(name)) { + return fieldNode.desc; + } + } + } + catch (IOException e) + { + e.printStackTrace(); + } + return null; } private void parseClass(Builder builder, String[] parts) @@ -181,7 +210,7 @@ public class FMLDeobfuscatingRemapper extends Remapper { return name; } Map fieldMap = getFieldMap(owner); - return fieldMap!=null && fieldMap.containsKey(name) ? fieldMap.get(name) : name; + return fieldMap!=null && fieldMap.containsKey(name+":"+desc) ? fieldMap.get(name+":"+desc) : name; } @Override From 1a9cb9e3c95d9d95b34cf81a14010441f852e535 Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 15 Apr 2013 17:30:35 -0400 Subject: [PATCH 2/2] Add in some caching of the read field descriptions for efficiency --- .../deobf/FMLDeobfuscatingRemapper.java | 49 ++++++++++++------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/fml/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java b/fml/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java index c5d7f30ab..b42e303d1 100644 --- a/fml/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java +++ b/fml/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java @@ -39,6 +39,7 @@ import com.google.common.collect.ImmutableBiMap; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; +import com.google.common.collect.ListMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; @@ -148,30 +149,42 @@ public class FMLDeobfuscatingRemapper extends Remapper { rawFieldMaps.get(cl).put(oldName + ":null", newName); } - @SuppressWarnings("unchecked") - private String getFieldType(String owner, String name) + /* + * Cache the field descriptions for classes so we don't repeatedly reload the same data again and again + */ + private Map> fieldDescriptions = Maps.newHashMap(); + + private String getFieldType(String owner, String name) { - try + if (fieldDescriptions.containsKey(owner)) { - byte[] classBytes = classLoader.getClassBytes(owner); - if (classBytes == null) + return fieldDescriptions.get(owner).get(name); + } + synchronized (fieldDescriptions) + { + try { - return null; - } - ClassReader cr = new ClassReader(classBytes); - ClassNode classNode = new ClassNode(); - cr.accept(classNode, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); - for (FieldNode fieldNode : (List) classNode.fields) { - if (fieldNode.name.equals(name)) { - return fieldNode.desc; + byte[] classBytes = classLoader.getClassBytes(owner); + if (classBytes == null) + { + return null; } + ClassReader cr = new ClassReader(classBytes); + ClassNode classNode = new ClassNode(); + cr.accept(classNode, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); + Map resMap = Maps.newHashMap(); + for (FieldNode fieldNode : classNode.fields) { + resMap.put(fieldNode.name, fieldNode.desc); + } + fieldDescriptions.put(owner, resMap); + return resMap.get(name); } + catch (IOException e) + { + FMLLog.log(Level.SEVERE,e, "A critical exception occured reading a class file %s", owner); + } + return null; } - catch (IOException e) - { - e.printStackTrace(); - } - return null; } private void parseClass(Builder builder, String[] parts)