First draft runtime deobf
This commit is contained in:
parent
5c99e3488a
commit
b4c7fe1d0e
10 changed files with 141 additions and 22 deletions
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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",
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package cpw.mods.fml.relauncher;
|
||||
|
||||
public interface IClassNameTransformer {
|
||||
public String remapClassName(String name);
|
||||
|
||||
public String unmapClassName(String name);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ public class RelaunchClassLoader extends URLClassLoader
|
|||
private Set<String> classLoaderExceptions = new HashSet<String>();
|
||||
private Set<String> transformerExceptions = new HashSet<String>();
|
||||
private Map<Package,Manifest> packageManifests = new HashMap<Package,Manifest>();
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue