diff --git a/fml/common/cpw/mods/fml/common/asm/ASMTransformer.java b/fml/common/cpw/mods/fml/common/asm/ASMTransformer.java index a4b106e73..8c7c512c2 100644 --- a/fml/common/cpw/mods/fml/common/asm/ASMTransformer.java +++ b/fml/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/fml/common/cpw/mods/fml/common/asm/FMLSanityChecker.java b/fml/common/cpw/mods/fml/common/asm/FMLSanityChecker.java index 7206ee87e..e4a59b17b 100644 --- a/fml/common/cpw/mods/fml/common/asm/FMLSanityChecker.java +++ b/fml/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; @@ -27,7 +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; @@ -72,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); } } } @@ -93,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 @@ -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"), cl); } } diff --git a/fml/common/cpw/mods/fml/common/asm/transformers/AccessTransformer.java b/fml/common/cpw/mods/fml/common/asm/transformers/AccessTransformer.java index bc1a376ef..2d4944313 100644 --- a/fml/common/cpw/mods/fml/common/asm/transformers/AccessTransformer.java +++ b/fml/common/cpw/mods/fml/common/asm/transformers/AccessTransformer.java @@ -143,7 +143,7 @@ public class AccessTransformer 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 (!modifiers.containsKey(name)) { return bytes; } @@ -375,7 +375,7 @@ public class AccessTransformer implements IClassTransformer for (AccessTransformer trans : transformers) { - entryData = trans.transform(name, entryData); + entryData = trans.transform(name, name, entryData); } } diff --git a/fml/common/cpw/mods/fml/common/asm/transformers/DeobfuscationTransformer.java b/fml/common/cpw/mods/fml/common/asm/transformers/DeobfuscationTransformer.java new file mode 100644 index 000000000..f0ddefe21 --- /dev/null +++ b/fml/common/cpw/mods/fml/common/asm/transformers/DeobfuscationTransformer.java @@ -0,0 +1,42 @@ +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.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; + +public class DeobfuscationTransformer implements IClassTransformer, IClassNameTransformer { + + @Override + public byte[] transform(String name, String transformedName, byte[] bytes) + { + if (bytes == null) + { + return null; + } + ClassReader classReader = new ClassReader(bytes); + ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS); + RemappingClassAdapter remapAdapter = new FMLRemappingAdapter(classWriter); + 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) + { + return FMLDeobfuscatingRemapper.INSTANCE.unmap(name.replace('.', '/')).replace('/','.'); + } + +} diff --git a/fml/common/cpw/mods/fml/common/asm/transformers/MarkerTransformer.java b/fml/common/cpw/mods/fml/common/asm/transformers/MarkerTransformer.java index f9a2985a7..1c9b03707 100644 --- a/fml/common/cpw/mods/fml/common/asm/transformers/MarkerTransformer.java +++ b/fml/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/fml/common/cpw/mods/fml/common/asm/transformers/SideTransformer.java b/fml/common/cpw/mods/fml/common/asm/transformers/SideTransformer.java index f4c63ffd0..1b0d7afc5 100644 --- a/fml/common/cpw/mods/fml/common/asm/transformers/SideTransformer.java +++ b/fml/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/fml/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java b/fml/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java new file mode 100644 index 000000000..8eb2c23cb --- /dev/null +++ b/fml/common/cpw/mods/fml/common/asm/transformers/deobf/FMLDeobfuscatingRemapper.java @@ -0,0 +1,261 @@ +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.Arrays; +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.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; +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 Map> fieldNameMaps; + private Map> methodNameMaps; + + private RelaunchClassLoader classLoader; + + private FMLDeobfuscatingRemapper() + { + } + + public void setup(File mcDir, RelaunchClassLoader classLoader) + { + this.classLoader = classLoader; + try + { + File libDir = new File(mcDir, "lib"); + File mapData = new File(libDir, "deobfuscation_data.zip"); + ZipFile mapZip = new ZipFile(mapData); + ZipEntry classData = mapZip.getEntry("joined.srg"); + ZipInputSupplier zis = new ZipInputSupplier(mapZip, classData); + InputSupplier srgSupplier = CharStreams.newReaderSupplier(zis,Charsets.UTF_8); + List srgList = CharStreams.readLines(srgSupplier); + rawMethodMaps = Maps.newHashMap(); + rawFieldMaps = Maps.newHashMap(); + Builder builder = ImmutableBiMap.builder(); + Splitter splitter = Splitter.on(CharMatcher.anyOf(": ")).omitEmptyStrings().trimResults(); + for (String line : srgList) + { + String[] parts = Iterables.toArray(splitter.split(line),String.class); + String typ = parts[0]; + if ("CL".equals(typ)) + { + parseClass(builder, parts); + } + else if ("MD".equals(typ)) + { + parseMethod(parts); + } + else if ("FD".equals(typ)) + { + parseField(parts); + } + } + classNameBiMap = builder.build(); + + } + catch (IOException ioe) + { + 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) + { + 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) + { + if (classNameBiMap == null) + { + return name; + } + Map fieldMap = getFieldMap(owner); + return fieldMap!=null && fieldMap.containsKey(name) ? fieldMap.get(name) : name; + } + + @Override + public String map(String typeName) + { + if (classNameBiMap == null) + { + return typeName; + } + + String result = classNameBiMap.containsKey(typeName) ? classNameBiMap.get(typeName) : typeName; + return result; + } + + public String unmap(String typeName) + { + if (classNameBiMap == null) + { + return typeName; + } + return classNameBiMap.containsValue(typeName) ? classNameBiMap.inverse().get(typeName) : typeName; + } + + + @Override + public String mapMethodName(String owner, String name, String desc) + { + if (classNameBiMap==null) + { + return name; + } + Map methodMap = getMethodMap(owner); + String methodDescriptor = name+desc; + 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)) + { + findAndMergeSuperMaps(className); + } + return methodNameMaps.get(className); + } + + private void findAndMergeSuperMaps(String name) + { + try + { + byte[] classBytes = classLoader.getClassBytes(name); + if (classBytes == null) + { + return; + } + ClassReader cr = new ClassReader(classBytes); + String superName = cr.getSuperName(); + 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, String[] interfaces) + { + if (classNameBiMap == null) + { + return; + } + List allParents = ImmutableList.builder().add(superName).addAll(Arrays.asList(interfaces)).build(); + for (String parentThing : allParents) + { + if (superName != null && classNameBiMap.containsKey(superName) && !methodNameMaps.containsKey(superName)) + { + findAndMergeSuperMaps(superName); + } + } + 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)); + } +} diff --git a/fml/common/cpw/mods/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java b/fml/common/cpw/mods/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java new file mode 100644 index 000000000..39f589246 --- /dev/null +++ b/fml/common/cpw/mods/fml/common/asm/transformers/deobf/FMLRemappingAdapter.java @@ -0,0 +1,23 @@ +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) + { + if (interfaces == null) + { + interfaces = new String[0]; + } + FMLDeobfuscatingRemapper.INSTANCE.mergeSuperMaps(name, superName, interfaces); + super.visit(version, access, name, signature, superName, interfaces); + } +} diff --git a/fml/common/cpw/mods/fml/common/asm/transformers/deobf/ZipInputSupplier.java b/fml/common/cpw/mods/fml/common/asm/transformers/deobf/ZipInputSupplier.java new file mode 100644 index 000000000..db04039dc --- /dev/null +++ b/fml/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); + } + +} diff --git a/fml/common/cpw/mods/fml/relauncher/FMLCorePlugin.java b/fml/common/cpw/mods/fml/relauncher/FMLCorePlugin.java index 093ca092f..b188e993d 100644 --- a/fml/common/cpw/mods/fml/relauncher/FMLCorePlugin.java +++ b/fml/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/fml/common/cpw/mods/fml/relauncher/IClassNameTransformer.java b/fml/common/cpw/mods/fml/relauncher/IClassNameTransformer.java new file mode 100644 index 000000000..3853e14a6 --- /dev/null +++ b/fml/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/fml/common/cpw/mods/fml/relauncher/IClassTransformer.java b/fml/common/cpw/mods/fml/relauncher/IClassTransformer.java index dd9045b55..d0a8e0fbc 100644 --- a/fml/common/cpw/mods/fml/relauncher/IClassTransformer.java +++ b/fml/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/fml/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java b/fml/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java index fe0d481db..3ddde7c27 100644 --- a/fml/common/cpw/mods/fml/relauncher/RelaunchClassLoader.java +++ b/fml/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(); @@ -68,15 +69,23 @@ public class RelaunchClassLoader extends URLClassLoader // standard transformer exclusions addTransformerExclusion("javax."); + addTransformerExclusion("argo."); addTransformerExclusion("org.objectweb.asm."); addTransformerExclusion("com.google.common."); + addTransformerExclusion("org.bouncycastle."); + addTransformerExclusion("cpw.mods.fml.common.asm.transformers.deobf."); } public void registerTransformer(String transformerClassName) { 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) { @@ -124,9 +133,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) @@ -138,7 +149,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) { @@ -171,10 +182,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) @@ -188,6 +199,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); @@ -223,11 +258,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; }