From b5d5c95b3364075e111afe79395f23198426645c Mon Sep 17 00:00:00 2001 From: Christian Date: Sun, 27 Jan 2013 15:55:37 -0500 Subject: [PATCH 1/7] First draft runtime deobf --- .../mods/fml/common/asm/ASMTransformer.java | 4 +- .../asm/transformers/AccessTransformer.java | 5 +- .../DeobfuscationTransformer.java | 44 +++++++++++++++ .../FMLDeobfuscatingRemapper.java | 33 ++++++++++++ .../asm/transformers/MarkerTransformer.java | 4 +- .../asm/transformers/SideTransformer.java | 4 +- .../mods/fml/relauncher/FMLCorePlugin.java | 6 ++- .../fml/relauncher/IClassNameTransformer.java | 7 +++ .../fml/relauncher/IClassTransformer.java | 2 +- .../fml/relauncher/RelaunchClassLoader.java | 54 +++++++++++++++---- 10 files changed, 141 insertions(+), 22 deletions(-) create mode 100644 common/cpw/mods/fml/common/asm/transformers/DeobfuscationTransformer.java create mode 100644 common/cpw/mods/fml/common/asm/transformers/FMLDeobfuscatingRemapper.java create mode 100644 common/cpw/mods/fml/relauncher/IClassNameTransformer.java diff --git a/common/cpw/mods/fml/common/asm/ASMTransformer.java b/common/cpw/mods/fml/common/asm/ASMTransformer.java index a4b106e73b..8c7c512c26 100644 --- a/common/cpw/mods/fml/common/asm/ASMTransformer.java +++ b/common/cpw/mods/fml/common/asm/ASMTransformer.java @@ -12,7 +12,7 @@ import cpw.mods.fml.relauncher.IClassTransformer; public class ASMTransformer implements IClassTransformer { @Override - public byte[] transform(String name, byte[] bytes) + public byte[] transform(String name,String transformedName, byte[] bytes) { if ("net.minecraft.src.Block".equals(name)) { @@ -24,7 +24,7 @@ public class ASMTransformer implements IClassTransformer cn.accept(cw); return cw.toByteArray(); } - + return bytes; } diff --git a/common/cpw/mods/fml/common/asm/transformers/AccessTransformer.java b/common/cpw/mods/fml/common/asm/transformers/AccessTransformer.java index bc1a376eff..062d343812 100644 --- a/common/cpw/mods/fml/common/asm/transformers/AccessTransformer.java +++ b/common/cpw/mods/fml/common/asm/transformers/AccessTransformer.java @@ -143,8 +143,9 @@ public class AccessTransformer implements IClassTransformer @SuppressWarnings("unchecked") @Override - public byte[] transform(String name, byte[] bytes) + public byte[] transform(String name, String transformedName, byte[] bytes) { + System.out.printf("AT transforming %s : %s\n",name,transformedName); if (bytes == null) { return null; } if (!modifiers.containsKey(name)) { return bytes; } @@ -375,7 +376,7 @@ public class AccessTransformer implements IClassTransformer for (AccessTransformer trans : transformers) { - entryData = trans.transform(name, entryData); + entryData = trans.transform(name, name, entryData); } } diff --git a/common/cpw/mods/fml/common/asm/transformers/DeobfuscationTransformer.java b/common/cpw/mods/fml/common/asm/transformers/DeobfuscationTransformer.java new file mode 100644 index 0000000000..5d361c6e11 --- /dev/null +++ b/common/cpw/mods/fml/common/asm/transformers/DeobfuscationTransformer.java @@ -0,0 +1,44 @@ +package cpw.mods.fml.common.asm.transformers; + +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.commons.RemappingClassAdapter; +import org.objectweb.asm.tree.ClassNode; + +import cpw.mods.fml.relauncher.IClassNameTransformer; +import cpw.mods.fml.relauncher.IClassTransformer; + +public class DeobfuscationTransformer implements IClassTransformer, IClassNameTransformer { + + @Override + public byte[] transform(String name, String transformedName, byte[] bytes) + { + System.out.println("***" + name + ":"+transformedName); + ClassReader classReader = new ClassReader(bytes); + ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS); + RemappingClassAdapter remapAdapter = new RemappingClassAdapter(classWriter, FMLDeobfuscatingRemapper.INSTANCE); + classReader.accept(remapAdapter, ClassReader.EXPAND_FRAMES); + return classWriter.toByteArray(); + } + + @Override + public String remapClassName(String name) + { + return FMLDeobfuscatingRemapper.INSTANCE.map(name.replace('.','/')).replace('/', '.'); + } + + @Override + public String unmapClassName(String name) + { + if (name.startsWith("hello.world.")) + { + return name.replace("hello.world.","").replace("LexManos", ""); + } + else + { + return name; + } + } + +} diff --git a/common/cpw/mods/fml/common/asm/transformers/FMLDeobfuscatingRemapper.java b/common/cpw/mods/fml/common/asm/transformers/FMLDeobfuscatingRemapper.java new file mode 100644 index 0000000000..70bea79c44 --- /dev/null +++ b/common/cpw/mods/fml/common/asm/transformers/FMLDeobfuscatingRemapper.java @@ -0,0 +1,33 @@ +package cpw.mods.fml.common.asm.transformers; + +import org.objectweb.asm.commons.Remapper; + +public class FMLDeobfuscatingRemapper extends Remapper { + public static final FMLDeobfuscatingRemapper INSTANCE = new FMLDeobfuscatingRemapper(); + + @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 map(String typeName) + { + if (typeName.indexOf('/') < 0) + { + return "hello/world/"+typeName+"LexManos"; + } + else + { + return typeName; + } + } +} diff --git a/common/cpw/mods/fml/common/asm/transformers/MarkerTransformer.java b/common/cpw/mods/fml/common/asm/transformers/MarkerTransformer.java index f9a2985a71..1c9b037077 100644 --- a/common/cpw/mods/fml/common/asm/transformers/MarkerTransformer.java +++ b/common/cpw/mods/fml/common/asm/transformers/MarkerTransformer.java @@ -87,7 +87,7 @@ public class MarkerTransformer implements IClassTransformer @SuppressWarnings("unchecked") @Override - public byte[] transform(String name, byte[] bytes) + public byte[] transform(String name, String transformedName, byte[] bytes) { if (bytes == null) { return null; } if (!markers.containsKey(name)) { return bytes; } @@ -240,7 +240,7 @@ public class MarkerTransformer implements IClassTransformer for (MarkerTransformer trans : transformers) { - entryData = trans.transform(name, entryData); + entryData = trans.transform(name, name, entryData); } } diff --git a/common/cpw/mods/fml/common/asm/transformers/SideTransformer.java b/common/cpw/mods/fml/common/asm/transformers/SideTransformer.java index f4c63ffd0d..1b0d7afc58 100644 --- a/common/cpw/mods/fml/common/asm/transformers/SideTransformer.java +++ b/common/cpw/mods/fml/common/asm/transformers/SideTransformer.java @@ -21,7 +21,7 @@ public class SideTransformer implements IClassTransformer private static final boolean DEBUG = false; @SuppressWarnings("unchecked") @Override - public byte[] transform(String name, byte[] bytes) + public byte[] transform(String name, String transformedName, byte[] bytes) { if (bytes == null) { return null; } @@ -69,7 +69,7 @@ public class SideTransformer implements IClassTransformer classNode.accept(writer); return writer.toByteArray(); } - + private boolean remove(List anns, String side) { if (anns == null) diff --git a/common/cpw/mods/fml/relauncher/FMLCorePlugin.java b/common/cpw/mods/fml/relauncher/FMLCorePlugin.java index 093ca092f1..b188e993d3 100644 --- a/common/cpw/mods/fml/relauncher/FMLCorePlugin.java +++ b/common/cpw/mods/fml/relauncher/FMLCorePlugin.java @@ -13,9 +13,11 @@ public class FMLCorePlugin implements IFMLLoadingPlugin @Override public String[] getASMTransformerClass() { - return new String[] {"cpw.mods.fml.common.asm.transformers.AccessTransformer", + return new String[] { + "cpw.mods.fml.common.asm.transformers.AccessTransformer", "cpw.mods.fml.common.asm.transformers.MarkerTransformer", - "cpw.mods.fml.common.asm.transformers.SideTransformer" + "cpw.mods.fml.common.asm.transformers.SideTransformer", + "cpw.mods.fml.common.asm.transformers.DeobfuscationTransformer", }; } diff --git a/common/cpw/mods/fml/relauncher/IClassNameTransformer.java b/common/cpw/mods/fml/relauncher/IClassNameTransformer.java new file mode 100644 index 0000000000..3853e14a66 --- /dev/null +++ b/common/cpw/mods/fml/relauncher/IClassNameTransformer.java @@ -0,0 +1,7 @@ +package cpw.mods.fml.relauncher; + +public interface IClassNameTransformer { + public String remapClassName(String name); + + public String unmapClassName(String name); +} diff --git a/common/cpw/mods/fml/relauncher/IClassTransformer.java b/common/cpw/mods/fml/relauncher/IClassTransformer.java index dd9045b55a..d0a8e0fbca 100644 --- a/common/cpw/mods/fml/relauncher/IClassTransformer.java +++ b/common/cpw/mods/fml/relauncher/IClassTransformer.java @@ -2,5 +2,5 @@ package cpw.mods.fml.relauncher; public interface IClassTransformer { - public byte[] transform(String name, byte[] bytes); + public byte[] transform(String name, String transformedName, byte[] bytes); } diff --git a/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java b/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java index f2b48bd642..7b535e1e87 100644 --- a/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java +++ b/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java @@ -39,6 +39,7 @@ public class RelaunchClassLoader extends URLClassLoader private Set classLoaderExceptions = new HashSet(); private Set transformerExceptions = new HashSet(); private Map packageManifests = new HashMap(); + private IClassNameTransformer renameTransformer; private static Manifest EMPTY = new Manifest(); @@ -74,7 +75,12 @@ public class RelaunchClassLoader extends URLClassLoader { try { - transformers.add((IClassTransformer) loadClass(transformerClassName).newInstance()); + IClassTransformer transformer = (IClassTransformer) loadClass(transformerClassName).newInstance(); + transformers.add(transformer); + if (transformer instanceof IClassNameTransformer && renameTransformer == null) + { + renameTransformer = (IClassNameTransformer) transformer; + } } catch (Exception e) { @@ -122,9 +128,11 @@ public class RelaunchClassLoader extends URLClassLoader try { CodeSigner[] signers = null; - int lastDot = name.lastIndexOf('.'); - String pkgname = lastDot == -1 ? "" : name.substring(0, lastDot); - String fName = name.replace('.', '/').concat(".class"); + String transformedName = transformName(name); + String untransformedName = untransformName(name); + int lastDot = untransformedName.lastIndexOf('.'); + String pkgname = lastDot == -1 ? "" : untransformedName.substring(0, lastDot); + String fName = untransformedName.replace('.', '/').concat(".class"); String pkgPath = pkgname.replace('.', '/'); URLConnection urlConnection = findCodeSourceConnectionFor(fName); if (urlConnection instanceof JarURLConnection && lastDot > -1) @@ -136,7 +144,7 @@ public class RelaunchClassLoader extends URLClassLoader Manifest mf = jf.getManifest(); JarEntry ent = jf.getJarEntry(fName); Package pkg = getPackage(pkgname); - getClassBytes(name); + getClassBytes(untransformedName); signers = ent.getCodeSigners(); if (pkg == null) { @@ -169,10 +177,10 @@ public class RelaunchClassLoader extends URLClassLoader FMLLog.severe("The URL %s is defining elements for sealed path %s", urlConnection.getURL(), pkgname); } } - byte[] basicClass = getClassBytes(name); - byte[] transformedClass = runTransformers(name, basicClass); - Class cl = defineClass(name, transformedClass, 0, transformedClass.length, new CodeSource(urlConnection.getURL(), signers)); - cachedClasses.put(name, cl); + byte[] basicClass = getClassBytes(untransformedName); + byte[] transformedClass = runTransformers(untransformedName, transformedName, basicClass); + Class cl = defineClass(transformedName, transformedClass, 0, transformedClass.length, new CodeSource(urlConnection.getURL(), signers)); + cachedClasses.put(transformedName, cl); return cl; } catch (Throwable e) @@ -186,6 +194,30 @@ public class RelaunchClassLoader extends URLClassLoader } } + private String untransformName(String name) + { + if (renameTransformer != null) + { + return renameTransformer.unmapClassName(name); + } + else + { + return name; + } + } + + private String transformName(String name) + { + if (renameTransformer != null) + { + return renameTransformer.remapClassName(name); + } + else + { + return name; + } + } + private boolean isSealed(String path, Manifest man) { Attributes attr = man.getAttributes(path); @@ -221,11 +253,11 @@ public class RelaunchClassLoader extends URLClassLoader } } - private byte[] runTransformers(String name, byte[] basicClass) + private byte[] runTransformers(String name, String transformedName, byte[] basicClass) { for (IClassTransformer transformer : transformers) { - basicClass = transformer.transform(name, basicClass); + basicClass = transformer.transform(name, transformedName, basicClass); } return basicClass; } From 6b5a433f65fdca8127cb72ea10105f3215ece2a1 Mon Sep 17 00:00:00 2001 From: Christian Date: Sun, 27 Jan 2013 17:09:00 -0500 Subject: [PATCH 2/7] Working to read class names and remap them at runtime. --- .../mods/fml/common/asm/FMLSanityChecker.java | 3 + .../DeobfuscationTransformer.java | 14 ++- .../FMLDeobfuscatingRemapper.java | 33 ------- .../deobf/FMLDeobfuscatingRemapper.java | 95 +++++++++++++++++++ .../deobf/FMLRemappingAdapter.java | 18 ++++ .../transformers/deobf/ZipInputSupplier.java | 26 +++++ 6 files changed, 148 insertions(+), 41 deletions(-) delete mode 100644 common/cpw/mods/fml/common/asm/transformers/FMLDeobfuscatingRemapper.java create mode 100644 common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java create mode 100644 common/cpw/mods/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java create mode 100644 common/cpw/mods/fml/common/asm/transformers/deobf/ZipInputSupplier.java diff --git a/common/cpw/mods/fml/common/asm/FMLSanityChecker.java b/common/cpw/mods/fml/common/asm/FMLSanityChecker.java index 7206ee87e3..a3d628698f 100644 --- a/common/cpw/mods/fml/common/asm/FMLSanityChecker.java +++ b/common/cpw/mods/fml/common/asm/FMLSanityChecker.java @@ -1,6 +1,7 @@ package cpw.mods.fml.common.asm; import java.io.ByteArrayInputStream; +import java.io.File; import java.io.InputStreamReader; import java.io.ObjectInputStream.GetField; import java.io.StringReader; @@ -28,6 +29,7 @@ import org.objectweb.asm.Opcodes; import cpw.mods.fml.common.CertificateHelper; import cpw.mods.fml.common.FMLLog; +import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper; import cpw.mods.fml.relauncher.IFMLCallHook; import cpw.mods.fml.relauncher.RelaunchClassLoader; @@ -124,6 +126,7 @@ public class FMLSanityChecker implements IFMLCallHook public void injectData(Map data) { cl = (RelaunchClassLoader) data.get("classLoader"); + FMLDeobfuscatingRemapper.INSTANCE.setup((File)data.get("mcLocation")); } } diff --git a/common/cpw/mods/fml/common/asm/transformers/DeobfuscationTransformer.java b/common/cpw/mods/fml/common/asm/transformers/DeobfuscationTransformer.java index 5d361c6e11..2661b0532a 100644 --- a/common/cpw/mods/fml/common/asm/transformers/DeobfuscationTransformer.java +++ b/common/cpw/mods/fml/common/asm/transformers/DeobfuscationTransformer.java @@ -6,6 +6,7 @@ import org.objectweb.asm.Opcodes; 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.relauncher.IClassNameTransformer; import cpw.mods.fml.relauncher.IClassTransformer; @@ -15,6 +16,10 @@ public class DeobfuscationTransformer implements IClassTransformer, IClassNameTr public byte[] transform(String name, String transformedName, byte[] bytes) { System.out.println("***" + name + ":"+transformedName); + if (bytes == null) + { + return null; + } ClassReader classReader = new ClassReader(bytes); ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS); RemappingClassAdapter remapAdapter = new RemappingClassAdapter(classWriter, FMLDeobfuscatingRemapper.INSTANCE); @@ -31,14 +36,7 @@ public class DeobfuscationTransformer implements IClassTransformer, IClassNameTr @Override public String unmapClassName(String name) { - if (name.startsWith("hello.world.")) - { - return name.replace("hello.world.","").replace("LexManos", ""); - } - else - { - return name; - } + return FMLDeobfuscatingRemapper.INSTANCE.unmap(name.replace('.', '/')).replace('/','.'); } } diff --git a/common/cpw/mods/fml/common/asm/transformers/FMLDeobfuscatingRemapper.java b/common/cpw/mods/fml/common/asm/transformers/FMLDeobfuscatingRemapper.java deleted file mode 100644 index 70bea79c44..0000000000 --- a/common/cpw/mods/fml/common/asm/transformers/FMLDeobfuscatingRemapper.java +++ /dev/null @@ -1,33 +0,0 @@ -package cpw.mods.fml.common.asm.transformers; - -import org.objectweb.asm.commons.Remapper; - -public class FMLDeobfuscatingRemapper extends Remapper { - public static final FMLDeobfuscatingRemapper INSTANCE = new FMLDeobfuscatingRemapper(); - - @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 map(String typeName) - { - if (typeName.indexOf('/') < 0) - { - return "hello/world/"+typeName+"LexManos"; - } - else - { - return typeName; - } - } -} diff --git a/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java b/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java new file mode 100644 index 0000000000..c05a6a5e35 --- /dev/null +++ b/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java @@ -0,0 +1,95 @@ +package cpw.mods.fml.common.asm.transformers.deobf; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.Charset; +import java.util.List; +import java.util.logging.Level; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +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.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; + +public class FMLDeobfuscatingRemapper extends Remapper { + public static final FMLDeobfuscatingRemapper INSTANCE = new FMLDeobfuscatingRemapper(); + + private BiMap classNameBiMap; + + private boolean isLoaded = false; + + private FMLDeobfuscatingRemapper() + { + } + + public void setup(File mcDir) + { + try + { + File libDir = new File(mcDir, "lib"); + File mapData = new File(libDir, "deobfuscation_data.zip"); + ZipFile mapZip = new ZipFile(mapData); + ZipEntry classData = mapZip.getEntry("class_data.csv"); + ZipInputSupplier zis = new ZipInputSupplier(mapZip, classData); + InputSupplier classNameSupplier = CharStreams.newReaderSupplier(zis,Charsets.UTF_8); + List classList = CharStreams.readLines(classNameSupplier); + Builder builder = ImmutableBiMap.builder(); + for (String line : classList) + { + String[] parts = line.split(","); + builder.put(parts[0],parts[1]); + } + classNameBiMap = builder.build(); + } + catch (IOException ioe) + { + FMLRelaunchLog.log(Level.SEVERE, ioe, "An error occurred loading the class map data"); + } + } +// @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 map(String typeName) + { + if (classNameBiMap == null) + { + return typeName; + } + + String result = classNameBiMap.containsKey(typeName) ? classNameBiMap.get(typeName) : typeName; + System.out.printf("Remapping %s to %s\n", typeName, result); + return result; + } + + public String unmap(String typeName) + { + if (classNameBiMap == null) + { + return typeName; + } + return classNameBiMap.containsValue(typeName) ? classNameBiMap.inverse().get(typeName) : typeName; + } +} diff --git a/common/cpw/mods/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java b/common/cpw/mods/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java new file mode 100644 index 0000000000..37ff609df6 --- /dev/null +++ b/common/cpw/mods/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java @@ -0,0 +1,18 @@ +package cpw.mods.fml.common.asm.transformers.deobf; + +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.commons.Remapper; +import org.objectweb.asm.commons.RemappingClassAdapter; + +public class FMLRemappingAdapter extends RemappingClassAdapter { + public FMLRemappingAdapter(ClassVisitor cv) + { + super(cv, FMLDeobfuscatingRemapper.INSTANCE); + } + + @Override + public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) + { + super.visit(version, access, name, signature, superName, interfaces); + } +} diff --git a/common/cpw/mods/fml/common/asm/transformers/deobf/ZipInputSupplier.java b/common/cpw/mods/fml/common/asm/transformers/deobf/ZipInputSupplier.java new file mode 100644 index 0000000000..db04039dcc --- /dev/null +++ b/common/cpw/mods/fml/common/asm/transformers/deobf/ZipInputSupplier.java @@ -0,0 +1,26 @@ +package cpw.mods.fml.common.asm.transformers.deobf; + +import java.io.IOException; +import java.io.InputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import com.google.common.io.InputSupplier; + +public class ZipInputSupplier implements InputSupplier { + private ZipFile zipFile; + private ZipEntry zipEntry; + + public ZipInputSupplier(ZipFile zip, ZipEntry entry) + { + this.zipFile = zip; + this.zipEntry = entry; + } + + @Override + public InputStream getInput() throws IOException + { + return zipFile.getInputStream(zipEntry); + } + +} From 66a81e7dbe4c48c0ffdca043b6d22bb42034440c Mon Sep 17 00:00:00 2001 From: Christian Date: Sun, 27 Jan 2013 21:50:08 -0500 Subject: [PATCH 3/7] 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) From 5d4c2fed884d27ed848436d96725799b93df0003 Mon Sep 17 00:00:00 2001 From: Christian Date: Sun, 27 Jan 2013 22:42:36 -0500 Subject: [PATCH 4/7] Now actually works for mods, somewhat. It currently generates access violations for ModLoader mods that presume access to fields that are not actually accessible from a different package. --- .../mods/fml/common/asm/FMLSanityChecker.java | 10 ++--- .../deobf/FMLDeobfuscatingRemapper.java | 41 +++++++++++++++---- .../deobf/FMLRemappingAdapter.java | 6 ++- 3 files changed, 42 insertions(+), 15 deletions(-) diff --git a/common/cpw/mods/fml/common/asm/FMLSanityChecker.java b/common/cpw/mods/fml/common/asm/FMLSanityChecker.java index 8359e10a8e..e4a59b17b4 100644 --- a/common/cpw/mods/fml/common/asm/FMLSanityChecker.java +++ b/common/cpw/mods/fml/common/asm/FMLSanityChecker.java @@ -28,8 +28,8 @@ import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.Opcodes; import cpw.mods.fml.common.CertificateHelper; -import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper; +import cpw.mods.fml.relauncher.FMLRelaunchLog; import cpw.mods.fml.relauncher.IFMLCallHook; import cpw.mods.fml.relauncher.RelaunchClassLoader; @@ -74,17 +74,17 @@ public class FMLSanityChecker implements IFMLCallHook String fingerprint = CertificateHelper.getFingerprint(cert); if (fingerprint.equals(FMLFINGERPRINT)) { - FMLLog.info("Found valid fingerprint for FML. Certificate fingerprint %s", fingerprint); + FMLRelaunchLog.info("Found valid fingerprint for FML. Certificate fingerprint %s", fingerprint); goodFML = true; } else if (fingerprint.equals(FORGEFINGERPRINT)) { - FMLLog.info("Found valid fingerprint for Minecraft Forge. Certificate fingerprint %s", fingerprint); + FMLRelaunchLog.info("Found valid fingerprint for Minecraft Forge. Certificate fingerprint %s", fingerprint); goodFML = true; } else { - FMLLog.severe("Found invalid fingerprint for FML: %s", fingerprint); + FMLRelaunchLog.severe("Found invalid fingerprint for FML: %s", fingerprint); } } } @@ -95,7 +95,7 @@ public class FMLSanityChecker implements IFMLCallHook } if (!goodFML) { - FMLLog.severe("FML appears to be missing any signature data. This is not a good thing"); + FMLRelaunchLog.severe("FML appears to be missing any signature data. This is not a good thing"); } byte[] mlClass = cl.getClassBytes("ModLoader"); // Only care in obfuscated env 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 b814bc7f3a..0c8333ce08 100644 --- a/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java +++ b/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java @@ -5,6 +5,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.Charset; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -20,7 +21,9 @@ 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.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.common.collect.ImmutableBiMap.Builder; @@ -127,13 +130,13 @@ public class FMLDeobfuscatingRemapper extends Remapper { @Override public String mapMethodName(String owner, String name, String desc) { - if (classNameBiMap==null || !classNameBiMap.containsKey(owner)) + if (classNameBiMap==null) { return name; } Map methodMap = getMethodMap(owner); String methodDescriptor = name+desc; - return methodMap.containsKey(methodDescriptor) ? methodMap.get(methodDescriptor) : name; + return methodMap!=null && methodMap.containsKey(methodDescriptor) ? methodMap.get(methodDescriptor) : name; } private Map getMethodMap(String className) @@ -150,27 +153,47 @@ public class FMLDeobfuscatingRemapper extends Remapper { try { byte[] classBytes = classLoader.getClassBytes(name); + if (classBytes == null) + { + return; + } ClassReader cr = new ClassReader(classBytes); String superName = cr.getSuperName(); - mergeSuperMaps(name, superName); + String[] interfaces = cr.getInterfaces(); + if (interfaces == null) + { + interfaces = new String[0]; + } + mergeSuperMaps(name, superName, interfaces); } catch (IOException e) { e.printStackTrace(); } } - public void mergeSuperMaps(String name, String superName) + public void mergeSuperMaps(String name, String superName, String[] interfaces) { - if (classNameBiMap == null || !classNameBiMap.containsKey(name)) + if (classNameBiMap == null) { return; } - if (superName != null && classNameBiMap.containsKey(superName) && !methodNameMaps.containsKey(superName)) + List allParents = ImmutableList.builder().add(superName).addAll(Arrays.asList(interfaces)).build(); + for (String parentThing : allParents) { - findAndMergeSuperMaps(superName); + if (superName != null && classNameBiMap.containsKey(superName) && !methodNameMaps.containsKey(superName)) + { + findAndMergeSuperMaps(superName); + } + } + System.out.printf("Merging maps for %s (%s , %s)\n", name, superName, Arrays.asList(interfaces)); + Map methodMap = Maps.newHashMap(); + for (String parentThing : allParents) + { + if (methodNameMaps.containsKey(parentThing)) + { + methodMap.putAll(methodNameMaps.get(parentThing)); + } } - 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)); 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 c52b353b6a..39f589246d 100644 --- a/common/cpw/mods/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java +++ b/common/cpw/mods/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java @@ -13,7 +13,11 @@ 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); + if (interfaces == null) + { + interfaces = new String[0]; + } + FMLDeobfuscatingRemapper.INSTANCE.mergeSuperMaps(name, superName, interfaces); super.visit(version, access, name, signature, superName, interfaces); } } From f00650481b2b0972b86fe0de69fd1ef902d94876 Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 28 Jan 2013 17:39:22 -0500 Subject: [PATCH 5/7] Read the joined.srg file directly from lib/deobfuscation_data.zip now. Still debating distribution method. --- .../deobf/FMLDeobfuscatingRemapper.java | 80 ++++++++++++------- .../fml/relauncher/RelaunchClassLoader.java | 1 + 2 files changed, 53 insertions(+), 28 deletions(-) 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 0c8333ce08..f2638fc3c2 100644 --- a/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java +++ b/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java @@ -17,12 +17,15 @@ import java.util.zip.ZipFile; import org.objectweb.asm.ClassReader; import org.objectweb.asm.commons.Remapper; +import com.google.common.base.CharMatcher; import com.google.common.base.Charsets; +import com.google.common.base.Splitter; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; 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.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; @@ -58,40 +61,34 @@ public class FMLDeobfuscatingRemapper extends Remapper { File libDir = new File(mcDir, "lib"); File mapData = new File(libDir, "deobfuscation_data.zip"); ZipFile mapZip = new ZipFile(mapData); - ZipEntry classData = mapZip.getEntry("class_data.csv"); + ZipEntry classData = mapZip.getEntry("joined.srg"); ZipInputSupplier zis = new ZipInputSupplier(mapZip, classData); - InputSupplier classNameSupplier = CharStreams.newReaderSupplier(zis,Charsets.UTF_8); - List classList = CharStreams.readLines(classNameSupplier); + InputSupplier srgSupplier = CharStreams.newReaderSupplier(zis,Charsets.UTF_8); + List srgList = CharStreams.readLines(srgSupplier); + rawMethodMaps = Maps.newHashMap(); + rawFieldMaps = Maps.newHashMap(); Builder builder = ImmutableBiMap.builder(); - for (String line : classList) + Splitter splitter = Splitter.on(CharMatcher.anyOf(": ")).omitEmptyStrings().trimResults(); + for (String line : srgList) { - String[] parts = line.split(","); - builder.put(parts[0],parts[1]); + String[] parts = Iterables.toArray(splitter.split(line),String.class); + String typ = parts[0]; + System.out.printf("PARTS: %s\n", Arrays.asList(parts)); + if ("CL".equals(typ)) + { + parseClass(builder, parts); + } + else if ("MD".equals(typ)) + { + parseMethod(parts); + } + else if ("FD".equals(typ)) + { + parseField(parts); + } } 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) { @@ -99,6 +96,33 @@ public class FMLDeobfuscatingRemapper extends Remapper { } methodNameMaps = Maps.newHashMapWithExpectedSize(rawMethodMaps.size()); } + private void parseField(String[] parts) + { + // + } + + private void parseClass(Builder builder, String[] parts) + { + builder.put(parts[1],parts[2]); + } + + private void parseMethod(String[] parts) + { + String oldSrg = parts[1]; + int lastOld = oldSrg.lastIndexOf('/'); + String cl = oldSrg.substring(0,lastOld); + String oldName = oldSrg.substring(lastOld+1); + String sig = parts[2]; + String newSrg = parts[3]; + 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); + } + @Override public String mapFieldName(String owner, String name, String desc) { diff --git a/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java b/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java index 865c051f8c..9e5dbc155d 100644 --- a/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java +++ b/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java @@ -67,6 +67,7 @@ public class RelaunchClassLoader extends URLClassLoader // standard transformer exclusions addTransformerExclusion("javax."); + addTransformerExclusion("argo."); addTransformerExclusion("org.objectweb.asm."); addTransformerExclusion("com.google.common."); addTransformerExclusion("org.bouncycastle."); From b9ccadb2f1e7087e6726eca49f586d0bc0bc371a Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 28 Jan 2013 17:48:44 -0500 Subject: [PATCH 6/7] Final part of the deobfuscation data setup- fields are now deobfuscated as well. All that remains, is to figure out what and how to distribute the deobfuscation data itself. --- .../asm/transformers/AccessTransformer.java | 1 - .../DeobfuscationTransformer.java | 1 - .../deobf/FMLDeobfuscatingRemapper.java | 42 +++++++++++++++++-- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/common/cpw/mods/fml/common/asm/transformers/AccessTransformer.java b/common/cpw/mods/fml/common/asm/transformers/AccessTransformer.java index 062d343812..2d4944313f 100644 --- a/common/cpw/mods/fml/common/asm/transformers/AccessTransformer.java +++ b/common/cpw/mods/fml/common/asm/transformers/AccessTransformer.java @@ -145,7 +145,6 @@ public class AccessTransformer implements IClassTransformer @Override public byte[] transform(String name, String transformedName, byte[] bytes) { - System.out.printf("AT transforming %s : %s\n",name,transformedName); if (bytes == null) { return null; } if (!modifiers.containsKey(name)) { return bytes; } diff --git a/common/cpw/mods/fml/common/asm/transformers/DeobfuscationTransformer.java b/common/cpw/mods/fml/common/asm/transformers/DeobfuscationTransformer.java index 6e0c0a426f..f0ddefe212 100644 --- a/common/cpw/mods/fml/common/asm/transformers/DeobfuscationTransformer.java +++ b/common/cpw/mods/fml/common/asm/transformers/DeobfuscationTransformer.java @@ -16,7 +16,6 @@ public class DeobfuscationTransformer implements IClassTransformer, IClassNameTr @Override public byte[] transform(String name, String transformedName, byte[] bytes) { - System.out.println("***" + name + ":"+transformedName); if (bytes == null) { return null; 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 f2638fc3c2..8eb2c23cb8 100644 --- a/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java +++ b/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java @@ -73,7 +73,6 @@ public class FMLDeobfuscatingRemapper extends Remapper { { String[] parts = Iterables.toArray(splitter.split(line),String.class); String typ = parts[0]; - System.out.printf("PARTS: %s\n", Arrays.asList(parts)); if ("CL".equals(typ)) { parseClass(builder, parts); @@ -95,10 +94,22 @@ public class FMLDeobfuscatingRemapper extends Remapper { FMLRelaunchLog.log(Level.SEVERE, ioe, "An error occurred loading the deobfuscation map data"); } methodNameMaps = Maps.newHashMapWithExpectedSize(rawMethodMaps.size()); + fieldNameMaps = Maps.newHashMapWithExpectedSize(rawFieldMaps.size()); } private void parseField(String[] parts) { - // + String oldSrg = parts[1]; + int lastOld = oldSrg.lastIndexOf('/'); + String cl = oldSrg.substring(0,lastOld); + String oldName = oldSrg.substring(lastOld+1); + String newSrg = parts[2]; + int lastNew = newSrg.lastIndexOf('/'); + String newName = newSrg.substring(lastNew+1); + if (!rawFieldMaps.containsKey(cl)) + { + rawFieldMaps.put(cl, Maps.newHashMap()); + } + rawFieldMaps.get(cl).put(oldName, newName); } private void parseClass(Builder builder, String[] parts) @@ -126,7 +137,12 @@ public class FMLDeobfuscatingRemapper extends Remapper { @Override public String mapFieldName(String owner, String name, String desc) { - return name; + if (classNameBiMap == null) + { + return name; + } + Map fieldMap = getFieldMap(owner); + return fieldMap!=null && fieldMap.containsKey(name) ? fieldMap.get(name) : name; } @Override @@ -163,6 +179,15 @@ public class FMLDeobfuscatingRemapper extends Remapper { return methodMap!=null && methodMap.containsKey(methodDescriptor) ? methodMap.get(methodDescriptor) : name; } + private Map getFieldMap(String className) + { + if (!fieldNameMaps.containsKey(className)) + { + findAndMergeSuperMaps(className); + } + return fieldNameMaps.get(className); + } + private Map getMethodMap(String className) { if (!methodNameMaps.containsKey(className)) @@ -209,19 +234,28 @@ public class FMLDeobfuscatingRemapper extends Remapper { findAndMergeSuperMaps(superName); } } - System.out.printf("Merging maps for %s (%s , %s)\n", name, superName, Arrays.asList(interfaces)); Map methodMap = Maps.newHashMap(); + Map fieldMap = Maps.newHashMap(); for (String parentThing : allParents) { if (methodNameMaps.containsKey(parentThing)) { methodMap.putAll(methodNameMaps.get(parentThing)); } + if (fieldNameMaps.containsKey(parentThing)) + { + fieldMap.putAll(fieldNameMaps.get(parentThing)); + } } if (rawMethodMaps.containsKey(name)) { methodMap.putAll(rawMethodMaps.get(name)); } + if (rawFieldMaps.containsKey(name)) + { + fieldMap.putAll(rawFieldMaps.get(name)); + } methodNameMaps.put(name, ImmutableMap.copyOf(methodMap)); + fieldNameMaps.put(name, ImmutableMap.copyOf(fieldMap)); } } From 29e59438c5f822538bc765b5b384a4302aee3d6e Mon Sep 17 00:00:00 2001 From: Christian Date: Sun, 17 Feb 2013 16:22:58 -0500 Subject: [PATCH 7/7] Fix Language Registry, closes #163 --- .../fml/common/registry/LanguageRegistry.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/common/cpw/mods/fml/common/registry/LanguageRegistry.java b/common/cpw/mods/fml/common/registry/LanguageRegistry.java index 1de27d199f..65a7d2bd2d 100644 --- a/common/cpw/mods/fml/common/registry/LanguageRegistry.java +++ b/common/cpw/mods/fml/common/registry/LanguageRegistry.java @@ -12,6 +12,8 @@ import java.util.logging.Level; import com.google.common.base.Charsets; import cpw.mods.fml.common.FMLLog; +import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.ModContainer; import net.minecraft.block.Block; import net.minecraft.item.Item; @@ -122,7 +124,23 @@ public class LanguageRegistry public void loadLocalization(String localizationFile, String lang, boolean isXML) { - loadLocalization(this.getClass().getResource(localizationFile), lang, isXML); + URL urlResource = this.getClass().getResource(localizationFile); + if (urlResource != null) + { + loadLocalization(urlResource, lang, isXML); + } + else + { + ModContainer activeModContainer = Loader.instance().activeModContainer(); + if (activeModContainer!=null) + { + FMLLog.log(activeModContainer.getModId(), Level.SEVERE, "The language resource %s cannot be located on the classpath. This is a programming error.", localizationFile); + } + else + { + FMLLog.log(Level.SEVERE, "The language resource %s cannot be located on the classpath. This is a programming error.", localizationFile); + } + } } public void loadLocalization(URL localizationFile, String lang, boolean isXML)