Rewrite unused fields

This commit is contained in:
Adam
2016-03-25 22:02:44 -04:00
parent e8c047aabe
commit c22a9e43da
2 changed files with 51 additions and 22 deletions

View File

@@ -1,6 +1,8 @@
package net.runelite.deob.deobfuscators; package net.runelite.deob.deobfuscators;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import net.runelite.asm.ClassFile; import net.runelite.asm.ClassFile;
import net.runelite.asm.ClassGroup; import net.runelite.asm.ClassGroup;
@@ -10,59 +12,46 @@ import net.runelite.asm.Method;
import net.runelite.asm.attributes.Code; import net.runelite.asm.attributes.Code;
import net.runelite.asm.attributes.code.Instruction; import net.runelite.asm.attributes.code.Instruction;
import net.runelite.asm.attributes.code.instruction.types.FieldInstruction; import net.runelite.asm.attributes.code.instruction.types.FieldInstruction;
import net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction;
import net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction;
public class UnusedFields implements Deobfuscator public class UnusedFields implements Deobfuscator
{ {
private static boolean isUnused(ClassGroup group, Field field) private final Set<Field> used = new HashSet<>();
private void checkForFieldUsage(ClassGroup group)
{ {
int get = 0, set = 0;
for (ClassFile cf : group.getClasses()) for (ClassFile cf : group.getClasses())
for (Method m : cf.getMethods().getMethods()) for (Method m : cf.getMethods().getMethods())
{ {
Code code = m.getCode(); Code code = m.getCode();
if (code == null) if (code == null)
continue; continue;
for (Instruction ins : code.getInstructions().getInstructions()) for (Instruction ins : code.getInstructions().getInstructions())
{ {
if (ins instanceof FieldInstruction) if (ins instanceof FieldInstruction)
{ {
FieldInstruction fi = (FieldInstruction) ins; FieldInstruction fi = (FieldInstruction) ins;
if (fi.getMyField() != field)
continue;
if (ins instanceof GetFieldInstruction) used.add(fi.getMyField());
++get;
if (ins instanceof SetFieldInstruction)
++set;
} }
} }
} }
// for only checking 'get' wed need a way to remove field initialization in constructors/class initializers
return get + set == 0;
// if (get == 0)
// return true;
//
// return false;
} }
@Override @Override
public void run(ClassGroup group) public void run(ClassGroup group)
{ {
checkForFieldUsage(group);
int count = 0; int count = 0;
for (ClassFile cf : group.getClasses()) for (ClassFile cf : group.getClasses())
for (Field f : new ArrayList<>(cf.getFields().getFields())) for (Field f : new ArrayList<>(cf.getFields().getFields()))
{ if (!used.contains(f))
if (isUnused(group, f))
{ {
cf.getFields().getFields().remove(f); cf.getFields().getFields().remove(f);
++count; ++count;
} }
}
System.out.println("Removed " + count + " unused fields"); System.out.println("Removed " + count + " unused fields");
} }
} }

View File

@@ -0,0 +1,40 @@
package net.runelite.deob.deobfuscators;
import java.io.File;
import java.io.IOException;
import net.runelite.asm.ClassGroup;
import net.runelite.deob.util.JarUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
public class UnusedFieldsTest
{
private static final File GAMEPACK = new File(RenameUniqueTest.class.getResource("/gamepack_v16.jar").getFile());
@Rule
public TemporaryFolder folder = new TemporaryFolder();
private ClassGroup group;
@Before
public void before() throws IOException
{
group = JarUtil.loadJar(GAMEPACK);
}
@After
public void after() throws IOException
{
JarUtil.saveJar(group, folder.newFile());
}
@Test
public void testRun()
{
UnusedFields uf = new UnusedFields();
uf.run(group);
}
}