Rebuild pool when writing instrutions to fix previous corruption with the newarray stuff. Run classes through ow2 asm to generate stack maps (and maxs for fun) since I don't want to generate my own stackmaps.

This commit is contained in:
Adam
2016-03-19 12:45:56 -04:00
parent 3d1ae24d73
commit 3cc6255596
7 changed files with 113 additions and 9 deletions

View File

@@ -0,0 +1,22 @@
package net.runelite.deob.asm;
import java.io.IOException;
import java.io.InputStream;
import net.runelite.deob.ClassGroup;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
public class AsmUtils
{
public static byte[] rebuildWithStackmaps(ClassGroup group, InputStream is) throws IOException
{
// I don't want to write my own stack map builder.
ClassReader r = new ClassReader(is);
ClassWriter writer = new NonloadingClassWriter(group, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
r.accept(writer, ClassReader.SKIP_FRAMES);
return writer.toByteArray();
}
}

View File

@@ -0,0 +1,67 @@
package net.runelite.deob.asm;
import net.runelite.deob.ClassFile;
import net.runelite.deob.ClassGroup;
import org.objectweb.asm.ClassWriter;
class NonloadingClassWriter extends ClassWriter
{
private final ClassGroup group;
public NonloadingClassWriter(ClassGroup group, int flags)
{
super(flags);
this.group = group;
}
@Override
protected String getCommonSuperClass(String type1, String type2)
{
ClassFile cf1 = group.findClass(type1),
cf2 = group.findClass(type2);
if (cf1 == null && cf2 == null)
{
// not mine
return super.getCommonSuperClass(type1, type2);
}
if (cf1 != null && cf2 != null)
{
for (ClassFile c = cf1; c != null; c = c.getParent())
for (ClassFile c2 = cf2; c2 != null; c2 = c2.getParent())
if (c == c2)
return c.getName();
throw new RuntimeException("No common base");
}
ClassFile found;
String other;
if (cf1 == null)
{
found = cf2;
other = type1;
}
else
{
assert cf2 == null;
found = cf1;
other = type2;
}
ClassFile prev = null;
for (ClassFile c = found; c != null; c = c.getParent())
{
prev = c;
if (c.getName().equals(other))
return other;
}
return super.getCommonSuperClass(prev.getSuperName(), other);
}
}

View File

@@ -82,7 +82,9 @@ public class Instructions
public void write(DataOutputStream out) throws IOException
{
// trnaslate instructions to specific
this.regeneratePool();
// translate instructions to specific
this.buildJumpGraph();
for (Instruction i : new ArrayList<>(instructions))

View File

@@ -82,7 +82,10 @@ public class ANewArray extends Instruction
StringBuffer sb = new StringBuffer();
for (int i = 0; i < this.dimensions; ++i)
sb.append('[');
sb.append("L" + myClass.getName() + ";");
if (this.dimensions > 0)
sb.append("L" + myClass.getName() + ";");
else
sb.append(myClass.getName());
clazz = new Class(sb.toString());
}
}

View File

@@ -87,7 +87,10 @@ public class MultiANewArray extends Instruction
StringBuffer sb = new StringBuffer();
for (int i = 0; i < this.dimensions; ++i)
sb.append('[');
sb.append("L" + myClass.getName() + ";");
if (this.dimensions > 0)
sb.append("L" + myClass.getName() + ";");
else
sb.append(myClass.getName());
clazz = new Class(sb.toString());
}
}

View File

@@ -1,5 +1,6 @@
package net.runelite.deob.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@@ -14,6 +15,8 @@ import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import net.runelite.deob.ClassFile;
import net.runelite.deob.ClassGroup;
import net.runelite.deob.asm.AsmUtils;
import org.objectweb.asm.ClassReader;
public class JarUtil
{
@@ -51,7 +54,11 @@ public class JarUtil
ByteArrayOutputStream bout = new ByteArrayOutputStream();
cf.write(new DataOutputStream(bout));
jout.write(bout.toByteArray());
// run through asm to generate stackmaps
byte[] b = AsmUtils.rebuildWithStackmaps(group, new ByteArrayInputStream(bout.toByteArray()));
jout.write(b);
jout.closeEntry();
}