Rewrite unused fields
This commit is contained in:
@@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user