Deob: Make mapping dumper dump (theoretically) all you need for updating (#1191)
* Deob: Make mapping dumper dump (theoretically) all you need for updating * Update ClassFile.java
This commit is contained in:
@@ -6,9 +6,9 @@ plugins {
|
|||||||
|
|
||||||
description = 'Deobfuscator'
|
description = 'Deobfuscator'
|
||||||
|
|
||||||
def rootPath = project.rootDir.toString().replace('\\', '/')
|
configurations {
|
||||||
def deobfuscatedJar = "${rootPath}/runescape-client/build/libs/rs-client-${project.version}.jar"
|
deobjars
|
||||||
def vanillaJar = "${rootPath}/injector-plugin/vanilla-${rsversion}.jar"
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation project(':runelite-api')
|
implementation project(':runelite-api')
|
||||||
@@ -19,18 +19,28 @@ dependencies {
|
|||||||
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
|
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
|
||||||
implementation group: 'org.ow2.asm', name: 'asm-debug-all', version: '5.2'
|
implementation group: 'org.ow2.asm', name: 'asm-debug-all', version: '5.2'
|
||||||
runtime group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.26'
|
runtime group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.26'
|
||||||
testImplementation project(':rs-client')
|
deobjars project(':rs-client')
|
||||||
testImplementation group: 'net.runelite.rs', name: 'vanilla', version: '181'
|
deobjars group: 'net.runelite.rs', name: 'vanilla', version: '181'
|
||||||
|
testImplementation configurations.deobjars.dependencies
|
||||||
testImplementation group: 'junit', name: 'junit', version: '4.12'
|
testImplementation group: 'junit', name: 'junit', version: '4.12'
|
||||||
testImplementation group: 'org.mockito', name: 'mockito-core', version: '3.0.0'
|
testImplementation group: 'org.mockito', name: 'mockito-core', version: '3.0.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
processResources {
|
||||||
|
from file("src/main/resources/deob.properties"), {
|
||||||
|
filter(ReplaceTokens, tokens: [
|
||||||
|
"rs.version": rsversion.toString(),
|
||||||
|
"vanilla.jar": configurations.deobjars.find {it.name.startsWith("vanilla")}.toString().replace('\\', "/"),
|
||||||
|
"rs.client": configurations.deobjars.find {it.name.startsWith("rs-client")}.toString().replace('\\', "/")
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
processTestResources {
|
processTestResources {
|
||||||
from file("src/test/resources/deob-test.properties"), {
|
from file("src/test/resources/deob-test.properties"), {
|
||||||
filter(ReplaceTokens, tokens: [
|
filter(ReplaceTokens, tokens: [
|
||||||
"rs.client": deobfuscatedJar.toString(),
|
"rs.client": configurations.deobjars.find {it.name.startsWith("rs-client")}.toString().replace('\\', "/"),
|
||||||
"rs.version": rsversion.toString(),
|
"rs.version": rsversion.toString(),
|
||||||
"vanilla.jar": vanillaJar.toString()
|
"vanilla.jar": configurations.deobjars.find {it.name.startsWith("vanilla")}.toString().replace('\\', "/")
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,6 +30,7 @@ import net.runelite.asm.attributes.Annotations;
|
|||||||
import net.runelite.asm.attributes.annotation.Annotation;
|
import net.runelite.asm.attributes.annotation.Annotation;
|
||||||
import net.runelite.asm.pool.Class;
|
import net.runelite.asm.pool.Class;
|
||||||
import net.runelite.asm.signature.Signature;
|
import net.runelite.asm.signature.Signature;
|
||||||
|
import static net.runelite.deob.DeobAnnotations.*;
|
||||||
import org.objectweb.asm.AnnotationVisitor;
|
import org.objectweb.asm.AnnotationVisitor;
|
||||||
import org.objectweb.asm.ClassVisitor;
|
import org.objectweb.asm.ClassVisitor;
|
||||||
import org.objectweb.asm.FieldVisitor;
|
import org.objectweb.asm.FieldVisitor;
|
||||||
@@ -308,6 +309,20 @@ public class ClassFile
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Method findObfStaticMethod(String name, Signature type)
|
||||||
|
{
|
||||||
|
for (Method m : methods)
|
||||||
|
{
|
||||||
|
if (m.isStatic() &&
|
||||||
|
name.equals(getObfuscatedName(m.getAnnotations())) &&
|
||||||
|
type.equals(getObfuscatedSignature(m)))
|
||||||
|
{
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return findMethodDeepStatic(name, type);
|
||||||
|
}
|
||||||
|
|
||||||
public Method findMethod(String name)
|
public Method findMethod(String name)
|
||||||
{
|
{
|
||||||
for (Method m : methods)
|
for (Method m : methods)
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import net.runelite.asm.attributes.Code;
|
import net.runelite.asm.attributes.Code;
|
||||||
import net.runelite.asm.signature.Signature;
|
import net.runelite.asm.signature.Signature;
|
||||||
|
import static net.runelite.deob.DeobAnnotations.*;
|
||||||
|
|
||||||
public class ClassGroup
|
public class ClassGroup
|
||||||
{
|
{
|
||||||
@@ -142,4 +143,17 @@ public class ClassGroup
|
|||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ClassFile findObfuscatedName(String name)
|
||||||
|
{
|
||||||
|
for (ClassFile cf : classes)
|
||||||
|
{
|
||||||
|
if (name.equals(getObfuscatedName(cf.getAnnotations())))
|
||||||
|
{
|
||||||
|
return cf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return findClass(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ package net.runelite.asm;
|
|||||||
|
|
||||||
import net.runelite.asm.attributes.Annotations;
|
import net.runelite.asm.attributes.Annotations;
|
||||||
import net.runelite.asm.attributes.annotation.Annotation;
|
import net.runelite.asm.attributes.annotation.Annotation;
|
||||||
|
import net.runelite.deob.DeobAnnotations;
|
||||||
import org.objectweb.asm.AnnotationVisitor;
|
import org.objectweb.asm.AnnotationVisitor;
|
||||||
import org.objectweb.asm.FieldVisitor;
|
import org.objectweb.asm.FieldVisitor;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
@@ -131,6 +132,17 @@ public class Field
|
|||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Type getObfuscatedType()
|
||||||
|
{
|
||||||
|
Type type = DeobAnnotations.getObfuscatedType(this);
|
||||||
|
if (type == null)
|
||||||
|
{
|
||||||
|
type = getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
public Object getValue()
|
public Object getValue()
|
||||||
{
|
{
|
||||||
return value;
|
return value;
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import net.runelite.asm.attributes.code.LocalVariable;
|
|||||||
import net.runelite.asm.attributes.code.Parameter;
|
import net.runelite.asm.attributes.code.Parameter;
|
||||||
import net.runelite.asm.attributes.code.instruction.types.LVTInstruction;
|
import net.runelite.asm.attributes.code.instruction.types.LVTInstruction;
|
||||||
import net.runelite.asm.signature.Signature;
|
import net.runelite.asm.signature.Signature;
|
||||||
|
import net.runelite.deob.DeobAnnotations;
|
||||||
import org.objectweb.asm.AnnotationVisitor;
|
import org.objectweb.asm.AnnotationVisitor;
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
@@ -193,6 +194,17 @@ public class Method
|
|||||||
this.arguments = signature;
|
this.arguments = signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Signature getObfuscatedSignature()
|
||||||
|
{
|
||||||
|
Signature sig = DeobAnnotations.getObfuscatedSignature(this);
|
||||||
|
if (sig == null)
|
||||||
|
{
|
||||||
|
sig = arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sig;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isNative()
|
public boolean isNative()
|
||||||
{
|
{
|
||||||
return (accessFlags & ACC_NATIVE) != 0;
|
return (accessFlags & ACC_NATIVE) != 0;
|
||||||
|
|||||||
@@ -25,10 +25,13 @@
|
|||||||
|
|
||||||
package net.runelite.asm.attributes;
|
package net.runelite.asm.attributes;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import net.runelite.asm.Method;
|
import net.runelite.asm.Method;
|
||||||
import net.runelite.asm.attributes.code.Exceptions;
|
import net.runelite.asm.attributes.code.Exceptions;
|
||||||
import net.runelite.asm.attributes.code.Instruction;
|
import net.runelite.asm.attributes.code.Instruction;
|
||||||
import net.runelite.asm.attributes.code.Instructions;
|
import net.runelite.asm.attributes.code.Instructions;
|
||||||
|
import net.runelite.asm.attributes.code.Label;
|
||||||
import net.runelite.asm.attributes.code.instruction.types.LVTInstruction;
|
import net.runelite.asm.attributes.code.instruction.types.LVTInstruction;
|
||||||
import net.runelite.asm.signature.Signature;
|
import net.runelite.asm.signature.Signature;
|
||||||
|
|
||||||
@@ -110,4 +113,28 @@ public class Code
|
|||||||
{
|
{
|
||||||
return instructions;
|
return instructions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Integer> getLineNumbers()
|
||||||
|
{
|
||||||
|
final List<Integer> lineNumbers = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Instruction i : instructions.getInstructions())
|
||||||
|
{
|
||||||
|
if (!(i instanceof Label))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer lineNumber = ((Label) i).getLineNumber();
|
||||||
|
if (lineNumber == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
lineNumbers.add(lineNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
lineNumbers.sort(Integer::compareTo);
|
||||||
|
return lineNumbers;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,6 +109,11 @@ public class Label extends NOP
|
|||||||
this.lineNumber = lineNumber;
|
this.lineNumber = lineNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getLineNumber()
|
||||||
|
{
|
||||||
|
return this.lineNumber;
|
||||||
|
}
|
||||||
|
|
||||||
public Instruction next()
|
public Instruction next()
|
||||||
{
|
{
|
||||||
Instructions ins = this.getInstructions();
|
Instructions ins = this.getInstructions();
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public class Field
|
|||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "Field{" + "clazz=" + clazz + ", name=" + name + ", type=" + type + '}';
|
return clazz.getName() + '.' + name + " " + type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class Method
|
|||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return clazz + "." + name + type;
|
return clazz.getName() + "." + name + type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public class Deob
|
|||||||
System.exit(-1);
|
System.exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//logger.info("Deobfuscator revision {}", DeobProperties.getRevision());
|
logger.info("Deobfuscator revision {}", DeobProperties.getRevision());
|
||||||
|
|
||||||
Stopwatch stopwatch = Stopwatch.createStarted();
|
Stopwatch stopwatch = Stopwatch.createStarted();
|
||||||
|
|
||||||
|
|||||||
@@ -24,18 +24,39 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.deob;
|
package net.runelite.deob;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
public class DeobProperties
|
public class DeobProperties
|
||||||
{
|
{
|
||||||
public static String getRevision() throws IOException
|
private static final Properties properties;
|
||||||
|
static
|
||||||
{
|
{
|
||||||
Properties properties = new Properties();
|
properties = new Properties();
|
||||||
InputStream resourceAsStream = DeobProperties.class.getResourceAsStream("/deob.properties");
|
try (InputStream resourceAsStream = DeobProperties.class.getResourceAsStream("/deob.properties"))
|
||||||
properties.load(resourceAsStream);
|
{
|
||||||
|
properties.load(resourceAsStream);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
//yes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return "420";
|
public static String getRevision()
|
||||||
|
{
|
||||||
|
return properties.getProperty("rs.version");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File getVanilla()
|
||||||
|
{
|
||||||
|
return new File(properties.getProperty("vanilla.jar"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File getRsClient()
|
||||||
|
{
|
||||||
|
return new File(properties.getProperty("rs.client"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
package net.runelite.deob.updater;
|
||||||
|
|
||||||
|
import com.google.common.base.Stopwatch;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import net.runelite.asm.ClassFile;
|
||||||
|
import net.runelite.asm.ClassGroup;
|
||||||
|
import net.runelite.asm.pool.Field;
|
||||||
|
import net.runelite.asm.pool.Method;
|
||||||
|
import net.runelite.deob.DeobProperties;
|
||||||
|
import net.runelite.deob.updater.mappingdumper.MappedClass;
|
||||||
|
import net.runelite.deob.updater.mappingdumper.MappedField;
|
||||||
|
import net.runelite.deob.updater.mappingdumper.MappedMethod;
|
||||||
|
import net.runelite.deob.updater.mappingdumper.MappingDump;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class MappingDumper
|
||||||
|
{
|
||||||
|
private static ClassGroup group;
|
||||||
|
private final Logger log = LoggerFactory.getLogger(MappingDumper.class);
|
||||||
|
private static final Map<ClassFile, MappedClass> classMap = new HashMap<>();
|
||||||
|
private static final Map<Field, MappedField> fieldMap = new HashMap<>();
|
||||||
|
private static final Map<Method, MappedMethod> methodMap = new HashMap<>();
|
||||||
|
|
||||||
|
public MappingDumper(ClassGroup group)
|
||||||
|
{
|
||||||
|
MappingDumper.group = group;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dump(final File outputFile)
|
||||||
|
{
|
||||||
|
Stopwatch st = Stopwatch.createStarted();
|
||||||
|
group.buildClassGraph();
|
||||||
|
|
||||||
|
// MappingDump.of(ClassGroup) dumps everything completely
|
||||||
|
final MappingDump dump = new MappingDump().visitGroup(group);
|
||||||
|
dump.revision = Integer.parseInt(DeobProperties.getRevision());
|
||||||
|
|
||||||
|
log.info("RS version {}. Dump took {}", dump.revision, st.toString());
|
||||||
|
log.info("Total classes: {}. Total mapped classes: {}. ({}%)", dump.totalClasses, dump.totalNamedClasses, dump.totalNamedClasses * 100 / dump.totalClasses);
|
||||||
|
log.info("Total non static methods: {}. Total mapped non static methods: {}. ({}%)", dump.totalNonStaticMethods, dump.totalNamedNonStaticMethods, dump.totalNamedNonStaticMethods * 100 / dump.totalNamedMethods);
|
||||||
|
log.info("Total methods: {}. Total mapped methods: {}. ({}%)", dump.totalMethods, dump.totalNamedMethods, dump.totalNamedMethods * 100 / dump.totalMethods);
|
||||||
|
log.info("Total fields: {}. Total mapped fields: {}. ({}%)", dump.totalFields, dump.totalNamedFields, dump.totalNamedFields * 100 / dump.totalFields);
|
||||||
|
log.info("Total non static fields: {}. Total mapped non static fields: {}. ({}%)", dump.totalNonStaticFields, dump.totalNamedNonStaticFields, dump.totalNamedNonStaticFields * 100 / dump.totalNamedFields);
|
||||||
|
writeJson(dump, outputFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Without this stack'll overflow :P
|
||||||
|
private void writeJson(MappingDump dump, File outputFile)
|
||||||
|
{
|
||||||
|
final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
try (JsonWriter writer = new JsonWriter(new OutputStreamWriter(new FileOutputStream(outputFile), StandardCharsets.UTF_8)))
|
||||||
|
{
|
||||||
|
writer.setIndent(" ");
|
||||||
|
writer.beginObject();
|
||||||
|
writer.name("revision").value(dump.revision);
|
||||||
|
writer.name("totalClasses").value(dump.totalClasses);
|
||||||
|
writer.name("totalNamedClasses").value(dump.totalNamedClasses);
|
||||||
|
writer.name("totalFields").value(dump.totalFields);
|
||||||
|
writer.name("totalNamedFields").value(dump.totalNamedFields);
|
||||||
|
writer.name("totalNonStaticFields").value(dump.totalNonStaticFields);
|
||||||
|
writer.name("totalNamedNonStaticFields").value(dump.totalNamedNonStaticFields);
|
||||||
|
writer.name("totalStaticFields").value(dump.totalStaticFields);
|
||||||
|
writer.name("totalNamedStaticFields").value(dump.totalNamedStaticFields);
|
||||||
|
writer.name("totalMethods").value(dump.totalMethods);
|
||||||
|
writer.name("totalNamedMethods").value(dump.totalNamedMethods);
|
||||||
|
writer.name("totalNonStaticMethods").value(dump.totalNonStaticMethods);
|
||||||
|
writer.name("totalNamedNonStaticMethods").value(dump.totalNamedNonStaticMethods);
|
||||||
|
writer.name("totalStaticMethods").value(dump.totalStaticMethods);
|
||||||
|
writer.name("totalNamedStaticMethods").value(dump.totalNamedStaticMethods);
|
||||||
|
writer.name("mappedClasses");
|
||||||
|
writer.beginArray();
|
||||||
|
for (MappedClass mc : dump.classes)
|
||||||
|
{
|
||||||
|
gson.toJson(mc, MappedClass.class, writer);
|
||||||
|
}
|
||||||
|
writer.endArray();
|
||||||
|
writer.endObject();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
log.error("Error saving json: ", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClassGroup getGroup()
|
||||||
|
{
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void putMap(ClassFile clazz, MappedClass mc)
|
||||||
|
{
|
||||||
|
classMap.put(clazz, mc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MappedClass getMap(ClassFile clazz)
|
||||||
|
{
|
||||||
|
return classMap.get(clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void putMap(Field field, MappedField mf)
|
||||||
|
{
|
||||||
|
fieldMap.put(field, mf);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MappedField getMap(Field field)
|
||||||
|
{
|
||||||
|
return fieldMap.get(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void putMap(Method method, MappedMethod mm)
|
||||||
|
{
|
||||||
|
methodMap.put(method, mm);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MappedMethod getMap(Method method)
|
||||||
|
{
|
||||||
|
return methodMap.get(method);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package net.runelite.deob.updater.mappingdumper;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import net.runelite.asm.ClassFile;
|
||||||
|
import net.runelite.deob.DeobAnnotations;
|
||||||
|
import net.runelite.deob.updater.MappingDumper;
|
||||||
|
|
||||||
|
public class MappedClass
|
||||||
|
{
|
||||||
|
@SerializedName("class")
|
||||||
|
public String implementingName;
|
||||||
|
@SerializedName("name")
|
||||||
|
public String obfuscatedName;
|
||||||
|
@SerializedName("super")
|
||||||
|
public String superClass;
|
||||||
|
public int access;
|
||||||
|
public List<String> interfaces;
|
||||||
|
public List<MappedField> fields;
|
||||||
|
public List<MappedMethod> methods;
|
||||||
|
public List<MappedMethod> constructors;
|
||||||
|
|
||||||
|
public MappedClass visitClass(final ClassFile c, final MappingDump dump)
|
||||||
|
{
|
||||||
|
MappingDumper.putMap(c, this);
|
||||||
|
|
||||||
|
implementingName = DeobAnnotations.getImplements(c);
|
||||||
|
|
||||||
|
obfuscatedName = DeobAnnotations.getObfuscatedName(c.getAnnotations());
|
||||||
|
if (obfuscatedName == null)
|
||||||
|
{
|
||||||
|
obfuscatedName = c.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
ClassFile parent = c.getParent();
|
||||||
|
if (parent != null)
|
||||||
|
{
|
||||||
|
superClass = DeobAnnotations.getObfuscatedName(parent.getAnnotations());
|
||||||
|
}
|
||||||
|
|
||||||
|
access = c.getAccess();
|
||||||
|
|
||||||
|
interfaces = c.getInterfaces()
|
||||||
|
.getMyInterfaces()
|
||||||
|
.stream()
|
||||||
|
.map(ClassFile::getAnnotations)
|
||||||
|
.map(DeobAnnotations::getObfuscatedName)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
fields = c.getFields()
|
||||||
|
.stream()
|
||||||
|
.map(f -> new MappedField().visitField(f, dump))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
methods = c.getMethods()
|
||||||
|
.stream()
|
||||||
|
.map(m -> new MappedMethod().visitMethod(m, dump))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
constructors = methods
|
||||||
|
.stream()
|
||||||
|
.filter(m -> m.obfuscatedName.endsWith("init>"))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package net.runelite.deob.updater.mappingdumper;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import net.runelite.asm.Field;
|
||||||
|
import net.runelite.asm.pool.Method;
|
||||||
|
import net.runelite.deob.DeobAnnotations;
|
||||||
|
import net.runelite.deob.updater.MappingDumper;
|
||||||
|
|
||||||
|
public class MappedField
|
||||||
|
{
|
||||||
|
@SerializedName("field")
|
||||||
|
public String exportedName;
|
||||||
|
public String owner;
|
||||||
|
@SerializedName("name")
|
||||||
|
public String obfuscatedName;
|
||||||
|
public int access;
|
||||||
|
public String descriptor;
|
||||||
|
public Number decoder;
|
||||||
|
// method name, amt of times
|
||||||
|
public Map<Method, Integer> puts = new HashMap<>();
|
||||||
|
public Map<Method, Integer> gets = new HashMap<>();
|
||||||
|
|
||||||
|
public MappedField visitField(final Field f, final MappingDump dump)
|
||||||
|
{
|
||||||
|
MappingDumper.putMap(f.getPoolField(), this);
|
||||||
|
|
||||||
|
exportedName = DeobAnnotations.getExportedName(f.getAnnotations());
|
||||||
|
|
||||||
|
owner = MappingDumper.getMap(f.getClassFile()).obfuscatedName;
|
||||||
|
|
||||||
|
obfuscatedName = DeobAnnotations.getObfuscatedName(f.getAnnotations());
|
||||||
|
if (obfuscatedName == null)
|
||||||
|
{
|
||||||
|
obfuscatedName = f.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
access = f.getAccessFlags();
|
||||||
|
|
||||||
|
descriptor = f.getObfuscatedType().toString();
|
||||||
|
|
||||||
|
decoder = DeobAnnotations.getObfuscatedGetter(f);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
package net.runelite.deob.updater.mappingdumper;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import net.runelite.asm.Method;
|
||||||
|
import net.runelite.asm.attributes.Code;
|
||||||
|
import net.runelite.asm.attributes.code.Instruction;
|
||||||
|
import net.runelite.asm.attributes.code.Instructions;
|
||||||
|
import net.runelite.asm.attributes.code.Parameter;
|
||||||
|
import net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction;
|
||||||
|
import net.runelite.asm.attributes.code.instruction.types.InvokeInstruction;
|
||||||
|
import net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction;
|
||||||
|
import net.runelite.asm.pool.Class;
|
||||||
|
import net.runelite.asm.pool.Field;
|
||||||
|
import net.runelite.deob.DeobAnnotations;
|
||||||
|
import net.runelite.deob.updater.MappingDumper;
|
||||||
|
|
||||||
|
public class MappedMethod
|
||||||
|
{
|
||||||
|
@SerializedName("method")
|
||||||
|
public String exportedName;
|
||||||
|
public String owner;
|
||||||
|
@SerializedName("name")
|
||||||
|
public String obfuscatedName;
|
||||||
|
public int access;
|
||||||
|
public List<String> parameters;
|
||||||
|
public String descriptor;
|
||||||
|
public String garbageValue;
|
||||||
|
public List<Integer> lineNumbers;
|
||||||
|
public Map<Field, Integer> fieldGets = new HashMap<>();
|
||||||
|
public Map<Field, Integer> fieldPuts = new HashMap<>();
|
||||||
|
public Map<net.runelite.asm.pool.Method, Integer> dependencies = new HashMap<>();
|
||||||
|
|
||||||
|
public MappedMethod visitMethod(final Method m, final MappingDump dump)
|
||||||
|
{
|
||||||
|
MappingDumper.putMap(m.getPoolMethod(), this);
|
||||||
|
exportedName = DeobAnnotations.getExportedName(m.getAnnotations());
|
||||||
|
|
||||||
|
owner = MappingDumper.getMap(m.getClassFile()).obfuscatedName;
|
||||||
|
|
||||||
|
obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations());
|
||||||
|
if (obfuscatedName == null)
|
||||||
|
{
|
||||||
|
obfuscatedName = m.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
access = m.getAccessFlags();
|
||||||
|
|
||||||
|
parameters = m.getParameters()
|
||||||
|
.stream()
|
||||||
|
.map(Parameter::getName)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
descriptor = m.getObfuscatedSignature().toString();
|
||||||
|
|
||||||
|
garbageValue = DeobAnnotations.getDecoder(m);
|
||||||
|
|
||||||
|
Code c = m.getCode();
|
||||||
|
if (c != null)
|
||||||
|
{
|
||||||
|
visitCode(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void visitCode(Code c)
|
||||||
|
{
|
||||||
|
lineNumbers = c.getLineNumbers();
|
||||||
|
|
||||||
|
Instructions ins = c.getInstructions();
|
||||||
|
for (Instruction i : ins.getInstructions())
|
||||||
|
{
|
||||||
|
if (i instanceof GetFieldInstruction)
|
||||||
|
{
|
||||||
|
Field k = ((GetFieldInstruction) i).getField();
|
||||||
|
int v = fieldGets.getOrDefault(k, 0) + 1;
|
||||||
|
fieldGets.put(k, v);
|
||||||
|
}
|
||||||
|
else if (i instanceof SetFieldInstruction)
|
||||||
|
{
|
||||||
|
Field k = ((SetFieldInstruction) i).getField();
|
||||||
|
int v = fieldPuts.getOrDefault(k, 0) + 1;
|
||||||
|
fieldPuts.put(k, v);
|
||||||
|
}
|
||||||
|
else if (i instanceof InvokeInstruction)
|
||||||
|
{
|
||||||
|
List<Method> met = ((InvokeInstruction) i).getMethods();
|
||||||
|
net.runelite.asm.pool.Method k;
|
||||||
|
if (met.size() > 0)
|
||||||
|
{
|
||||||
|
Method mme = met.get(0);
|
||||||
|
k = new net.runelite.asm.pool.Method(
|
||||||
|
new Class(DeobAnnotations.getObfuscatedName(mme.getClassFile().getAnnotations())),
|
||||||
|
DeobAnnotations.getObfuscatedName(mme.getAnnotations()),
|
||||||
|
mme.getObfuscatedSignature() != null ? mme.getObfuscatedSignature() : mme.getDescriptor()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
k = ((InvokeInstruction) i).getMethod();
|
||||||
|
}
|
||||||
|
|
||||||
|
int v = dependencies.getOrDefault(k, 0) + 1;
|
||||||
|
dependencies.put(k, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
package net.runelite.deob.updater.mappingdumper;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import net.runelite.asm.ClassFile;
|
||||||
|
import net.runelite.asm.ClassGroup;
|
||||||
|
import net.runelite.asm.pool.Class;
|
||||||
|
import net.runelite.asm.pool.Field;
|
||||||
|
import net.runelite.asm.pool.Method;
|
||||||
|
import net.runelite.asm.signature.Signature;
|
||||||
|
import net.runelite.deob.updater.MappingDumper;
|
||||||
|
import static org.objectweb.asm.Opcodes.ACC_STATIC;
|
||||||
|
|
||||||
|
public class MappingDump
|
||||||
|
{
|
||||||
|
public int revision;
|
||||||
|
|
||||||
|
public int totalClasses = 0;
|
||||||
|
public int totalNamedClasses = 0;
|
||||||
|
|
||||||
|
public int totalFields = 0;
|
||||||
|
public int totalNamedFields = 0;
|
||||||
|
|
||||||
|
public int totalNonStaticFields = 0;
|
||||||
|
public int totalNamedNonStaticFields = 0;
|
||||||
|
|
||||||
|
public int totalStaticFields = 0;
|
||||||
|
public int totalNamedStaticFields = 0;
|
||||||
|
|
||||||
|
public int totalMethods = 0;
|
||||||
|
public int totalNamedMethods = 0;
|
||||||
|
|
||||||
|
public int totalNonStaticMethods = 0;
|
||||||
|
public int totalNamedNonStaticMethods = 0;
|
||||||
|
|
||||||
|
public int totalStaticMethods = 0;
|
||||||
|
public int totalNamedStaticMethods = 0;
|
||||||
|
|
||||||
|
public List<MappedClass> classes;
|
||||||
|
|
||||||
|
private ClassGroup group;
|
||||||
|
|
||||||
|
public MappingDump visitGroup(ClassGroup group)
|
||||||
|
{
|
||||||
|
this.group = group;
|
||||||
|
classes = new ArrayList<>();
|
||||||
|
|
||||||
|
for (ClassFile c : group.getClasses())
|
||||||
|
{
|
||||||
|
if (c.getName().contains("runelite"))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final MappedClass mc = new MappedClass();
|
||||||
|
classes.add(mc.visitClass(c, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
totalClasses = classes.size();
|
||||||
|
|
||||||
|
for (MappedClass c : classes)
|
||||||
|
{
|
||||||
|
if (c.implementingName != null)
|
||||||
|
{
|
||||||
|
totalNamedClasses++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (MappedMethod mm : c.methods)
|
||||||
|
{
|
||||||
|
for (Map.Entry<Field, Integer> entry : mm.fieldGets.entrySet())
|
||||||
|
{
|
||||||
|
MappedField mf = MappingDumper.getMap(entry.getKey());
|
||||||
|
if (mf == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
mf.gets.put(
|
||||||
|
new Method(
|
||||||
|
new Class(mm.owner),
|
||||||
|
mm.obfuscatedName,
|
||||||
|
new Signature(mm.descriptor)),
|
||||||
|
entry.getValue());
|
||||||
|
}
|
||||||
|
for (Map.Entry<Field, Integer> entry : mm.fieldPuts.entrySet())
|
||||||
|
{
|
||||||
|
MappedField mf = MappingDumper.getMap(entry.getKey());
|
||||||
|
if (mf == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
mf.puts.put(
|
||||||
|
new Method(
|
||||||
|
new Class(mm.owner),
|
||||||
|
mm.obfuscatedName,
|
||||||
|
new Signature(mm.descriptor)),
|
||||||
|
entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grabAmountInfo(c);
|
||||||
|
}
|
||||||
|
totalNonStaticFields = totalFields - totalStaticFields;
|
||||||
|
totalNamedNonStaticFields = totalNamedFields - totalNamedStaticFields;
|
||||||
|
totalNonStaticMethods = totalMethods - totalStaticMethods;
|
||||||
|
totalNamedNonStaticMethods = totalNamedMethods - totalNamedStaticMethods;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void grabAmountInfo(MappedClass c)
|
||||||
|
{
|
||||||
|
totalFields += c.fields.size();
|
||||||
|
totalNamedFields += c.fields
|
||||||
|
.stream()
|
||||||
|
.filter(f -> f.exportedName != null)
|
||||||
|
.count();
|
||||||
|
totalStaticFields += c.fields
|
||||||
|
.stream()
|
||||||
|
.filter(f -> (f.access & ACC_STATIC) != 0)
|
||||||
|
.count();
|
||||||
|
totalNamedStaticFields += c.fields
|
||||||
|
.stream()
|
||||||
|
.filter(f -> f.exportedName != null
|
||||||
|
&& (f.access & ACC_STATIC) != 0)
|
||||||
|
.count();
|
||||||
|
|
||||||
|
totalMethods += c.methods.size();
|
||||||
|
totalNamedMethods += c.methods
|
||||||
|
.stream()
|
||||||
|
.filter(f -> f.exportedName != null)
|
||||||
|
.count();
|
||||||
|
totalStaticMethods += c.methods
|
||||||
|
.stream()
|
||||||
|
.filter(f -> (f.access & ACC_STATIC) != 0)
|
||||||
|
.count();
|
||||||
|
totalNamedStaticMethods += c.methods
|
||||||
|
.stream()
|
||||||
|
.filter(f -> f.exportedName != null
|
||||||
|
&& (f.access & ACC_STATIC) != 0)
|
||||||
|
.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
ClassGroup getGroup()
|
||||||
|
{
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
}
|
||||||
3
deobfuscator/src/main/resources/deob.properties
Normal file
3
deobfuscator/src/main/resources/deob.properties
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
rs.version=@rs.version@
|
||||||
|
vanilla.jar=@vanilla.jar@
|
||||||
|
rs.client=@rs.client@
|
||||||
@@ -24,266 +24,47 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.deob.deobfuscators.mapping;
|
package net.runelite.deob.deobfuscators.mapping;
|
||||||
|
|
||||||
import com.google.common.io.Files;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import net.runelite.asm.ClassFile;
|
import net.runelite.asm.ClassFile;
|
||||||
import net.runelite.asm.ClassGroup;
|
import net.runelite.asm.ClassGroup;
|
||||||
import net.runelite.asm.Field;
|
import net.runelite.asm.Field;
|
||||||
import net.runelite.asm.Method;
|
import net.runelite.asm.Method;
|
||||||
import net.runelite.asm.Type;
|
import net.runelite.asm.Type;
|
||||||
import net.runelite.asm.attributes.code.Parameter;
|
|
||||||
import net.runelite.asm.signature.Signature;
|
import net.runelite.asm.signature.Signature;
|
||||||
import net.runelite.deob.Deob;
|
|
||||||
import net.runelite.deob.DeobAnnotations;
|
import net.runelite.deob.DeobAnnotations;
|
||||||
import net.runelite.deob.DeobTestProperties;
|
import net.runelite.deob.DeobTestProperties;
|
||||||
import net.runelite.deob.deobfuscators.mapping.mappingdumper.MappedClass;
|
|
||||||
import net.runelite.deob.deobfuscators.mapping.mappingdumper.MappedField;
|
|
||||||
import net.runelite.deob.deobfuscators.mapping.mappingdumper.MappedMethod;
|
|
||||||
import net.runelite.deob.deobfuscators.mapping.mappingdumper.MappingDump;
|
|
||||||
import net.runelite.deob.util.JarUtil;
|
import net.runelite.deob.util.JarUtil;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
public class MappingDumper
|
public class MappingDumper
|
||||||
{
|
{
|
||||||
@Rule
|
@Rule
|
||||||
public DeobTestProperties properties = new DeobTestProperties();
|
public DeobTestProperties properties = new DeobTestProperties();
|
||||||
|
|
||||||
private final Logger log = LoggerFactory.getLogger(MappingDumper.class);
|
private ClassGroup group;
|
||||||
|
|
||||||
private MappingDump dump;
|
|
||||||
private Map<String, MappedClass> classMap;
|
|
||||||
private static final String OUTDIR = "";
|
private static final String OUTDIR = "";
|
||||||
private final File OUTFILE = new File(OUTDIR, "rlplushooks.json");
|
private final File OUTFILE = new File(OUTDIR, "rlplushooks.json");
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void before()
|
public void before() throws IOException
|
||||||
{
|
{
|
||||||
dump = new MappingDump();
|
group = JarUtil.loadJar(new File(properties.getRsClient()));
|
||||||
dump.revision = properties.getRsVersion();
|
|
||||||
dump.classes = new ArrayList<>();
|
|
||||||
dump.staticFields = new ArrayList<>();
|
|
||||||
dump.staticMethods = new ArrayList<>();
|
|
||||||
classMap = new HashMap<>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
@Ignore
|
||||||
public void newDump() throws IOException
|
public void newDump()
|
||||||
{
|
{
|
||||||
final ClassGroup group = JarUtil.loadJar(new File(properties.getRsClient()));
|
new net.runelite.deob.updater.MappingDumper(group).dump(OUTFILE);
|
||||||
|
|
||||||
|
|
||||||
// First create all the mappedclasses, so we can add static methods to their lists
|
|
||||||
for (ClassFile c : group.getClasses())
|
|
||||||
{
|
|
||||||
if (c.getName().contains("runelite"))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final MappedClass mc = new MappedClass();
|
|
||||||
|
|
||||||
mc.obfuscatedName = DeobAnnotations.getObfuscatedName(c.getAnnotations());
|
|
||||||
mc.implementingName = DeobAnnotations.getImplements(c);
|
|
||||||
mc.superClass = c.getSuperName();
|
|
||||||
mc.interfaces = c.getInterfaces().getIntfNames();
|
|
||||||
mc.constructors = new ArrayList<>();
|
|
||||||
mc.fields = new ArrayList<>();
|
|
||||||
mc.methods = new ArrayList<>();
|
|
||||||
mc.access = c.getAccess();
|
|
||||||
mc.staticMethods = new ArrayList<>();
|
|
||||||
mc.staticFields = new ArrayList<>();
|
|
||||||
|
|
||||||
dump.classes.add(mc);
|
|
||||||
classMap.put(c.getName(), mc);
|
|
||||||
|
|
||||||
dump.totalClasses++;
|
|
||||||
if (mc.implementingName != null)
|
|
||||||
{
|
|
||||||
dump.totalNamedClasses++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ClassFile c : group.getClasses())
|
|
||||||
{
|
|
||||||
if (c.getName().contains("runelite"))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final MappedClass mc = classMap.get(c.getName());
|
|
||||||
|
|
||||||
getFields(c, mc);
|
|
||||||
|
|
||||||
getMethods(c, mc);
|
|
||||||
}
|
|
||||||
|
|
||||||
dump.totalNonStaticFields = dump.totalFields - dump.totalStaticFields;
|
|
||||||
dump.totalNamedNonStaticFields = dump.totalNamedFields - dump.totalNamedStaticFields;
|
|
||||||
dump.totalNonStaticMethods = dump.totalMethods - dump.totalStaticMethods;
|
|
||||||
dump.totalNamedNonStaticMethods = dump.totalNamedMethods - dump.totalNamedStaticMethods;
|
|
||||||
|
|
||||||
final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
|
||||||
Files.asCharSink(OUTFILE, Charset.defaultCharset()).write(gson.toJson(dump));
|
|
||||||
|
|
||||||
log.info("Dumped current mappings. revision {}", dump.revision);
|
|
||||||
log.info("Total classes: {}. Total mapped classes: {}. ({}%)", dump.totalClasses, dump.totalNamedClasses, dump.totalNamedClasses * 100 / dump.totalClasses);
|
|
||||||
log.info("Total non static methods: {}. Total mapped non static methods: {}. ({}%)", dump.totalNonStaticMethods, dump.totalNamedNonStaticMethods, dump.totalNamedNonStaticMethods * 100 / dump.totalNamedMethods);
|
|
||||||
log.info("Total methods: {}. Total mapped methods: {}. ({}%)", dump.totalMethods, dump.totalNamedMethods, dump.totalNamedMethods * 100 / dump.totalMethods);
|
|
||||||
log.info("Total fields: {}. Total mapped fields: {}. ({}%)", dump.totalFields, dump.totalNamedFields, dump.totalNamedFields * 100 / dump.totalFields);
|
|
||||||
log.info("Total non static fields: {}. Total mapped non static fields: {}. ({}%)", dump.totalNonStaticFields, dump.totalNamedNonStaticFields, dump.totalNamedNonStaticFields * 100 / dump.totalNamedFields);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getFields(final ClassFile c, final MappedClass mc)
|
|
||||||
{
|
|
||||||
for (Field f : c.getFields())
|
|
||||||
{
|
|
||||||
dump.totalFields++;
|
|
||||||
|
|
||||||
if (f.isStatic())
|
|
||||||
{
|
|
||||||
dump.totalStaticFields++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Deob.isObfuscated(f.getName()))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
dump.totalNamedFields++;
|
|
||||||
|
|
||||||
final MappedField mf = new MappedField();
|
|
||||||
|
|
||||||
mf.exportedName = f.getName();
|
|
||||||
mf.owner = mc.obfuscatedName;
|
|
||||||
mf.obfuscatedName = DeobAnnotations.getObfuscatedName(f.getAnnotations());
|
|
||||||
mf.access = f.getAccessFlags();
|
|
||||||
mf.descriptor = DeobAnnotations.getAnnotationValue(f.getAnnotations(), DeobAnnotations.OBFUSCATED_SIGNATURE);
|
|
||||||
|
|
||||||
Number decoder = DeobAnnotations.getObfuscatedGetter(f);
|
|
||||||
if (decoder != null)
|
|
||||||
{
|
|
||||||
mf.decoder = decoder.longValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mf.descriptor == null)
|
|
||||||
{
|
|
||||||
mf.descriptor = f.getType().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f.isStatic())
|
|
||||||
{
|
|
||||||
dump.staticFields.add(mf);
|
|
||||||
dump.totalNamedStaticFields++;
|
|
||||||
|
|
||||||
int _index = mf.exportedName.indexOf('_');
|
|
||||||
|
|
||||||
if (_index != -1)
|
|
||||||
{
|
|
||||||
String className = mf.exportedName.substring(0, _index);
|
|
||||||
MappedClass staticOwner = classMap.get(className);
|
|
||||||
|
|
||||||
if (staticOwner != null)
|
|
||||||
{
|
|
||||||
staticOwner.staticFields.add(mf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mc.fields.add(mf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getMethods(final ClassFile c, final MappedClass mc)
|
|
||||||
{
|
|
||||||
for (Method m : c.getMethods())
|
|
||||||
{
|
|
||||||
dump.totalMethods++;
|
|
||||||
|
|
||||||
if (m.isStatic())
|
|
||||||
{
|
|
||||||
dump.totalStaticMethods++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Deob.isObfuscated(m.getName()) || m.getName().equals("<clinit>"))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
dump.totalNamedMethods++;
|
|
||||||
|
|
||||||
final MappedMethod mm = new MappedMethod();
|
|
||||||
|
|
||||||
mm.exportedName = m.getName();
|
|
||||||
mm.owner = mc.obfuscatedName;
|
|
||||||
mm.obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations());
|
|
||||||
mm.access = m.getAccessFlags();
|
|
||||||
mm.parameters = new ArrayList<>();
|
|
||||||
mm.descriptor = DeobAnnotations.getObfuscatedSignature(m) != null ? DeobAnnotations.getObfuscatedSignature(m).toString() : m.getDescriptor().toString();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
mm.garbageValue = Long.parseLong(DeobAnnotations.getDecoder(m));
|
|
||||||
}
|
|
||||||
catch (NumberFormatException e)
|
|
||||||
{
|
|
||||||
mm.garbageValue = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Parameter p : m.getParameters())
|
|
||||||
{
|
|
||||||
mm.parameters.add(p.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m.getName().equals("<init>"))
|
|
||||||
{
|
|
||||||
mm.exportedName = null;
|
|
||||||
mc.constructors.add(mm);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m.isStatic())
|
|
||||||
{
|
|
||||||
dump.staticMethods.add(mm);
|
|
||||||
dump.totalNamedStaticMethods++;
|
|
||||||
|
|
||||||
int _index = mm.exportedName.indexOf('_');
|
|
||||||
|
|
||||||
if (_index != -1)
|
|
||||||
{
|
|
||||||
String className = mm.exportedName.substring(0, _index - 1);
|
|
||||||
MappedClass staticOwner = classMap.get(className);
|
|
||||||
|
|
||||||
if (staticOwner != null)
|
|
||||||
{
|
|
||||||
staticOwner.staticMethods.add(mm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mc.methods.add(mm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
package net.runelite.deob.deobfuscators.mapping.mappingdumper;
|
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class MappedClass
|
|
||||||
{
|
|
||||||
@SerializedName("class")
|
|
||||||
public String implementingName;
|
|
||||||
@SerializedName("name")
|
|
||||||
public String obfuscatedName;
|
|
||||||
@SerializedName("super")
|
|
||||||
public String superClass;
|
|
||||||
public int access;
|
|
||||||
public List<String> interfaces;
|
|
||||||
public List<MappedField> fields;
|
|
||||||
public List<MappedMethod> methods;
|
|
||||||
public List<MappedMethod> constructors;
|
|
||||||
// Static fields/methods belonging to this class (ClassName_name)
|
|
||||||
public List<MappedField> staticFields;
|
|
||||||
public List<MappedMethod> staticMethods;
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package net.runelite.deob.deobfuscators.mapping.mappingdumper;
|
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
|
|
||||||
public class MappedField
|
|
||||||
{
|
|
||||||
@SerializedName("field")
|
|
||||||
public String exportedName;
|
|
||||||
public String owner;
|
|
||||||
@SerializedName("name")
|
|
||||||
public String obfuscatedName;
|
|
||||||
public int access;
|
|
||||||
public String descriptor;
|
|
||||||
public Long decoder;
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package net.runelite.deob.deobfuscators.mapping.mappingdumper;
|
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class MappedMethod
|
|
||||||
{
|
|
||||||
@SerializedName("method")
|
|
||||||
public String exportedName;
|
|
||||||
public String owner;
|
|
||||||
@SerializedName("name")
|
|
||||||
public String obfuscatedName;
|
|
||||||
public int access;
|
|
||||||
public List<String> parameters;
|
|
||||||
public String descriptor;
|
|
||||||
public Long garbageValue;
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package net.runelite.deob.deobfuscators.mapping.mappingdumper;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class MappingDump
|
|
||||||
{
|
|
||||||
public int revision;
|
|
||||||
|
|
||||||
public int totalClasses;
|
|
||||||
public int totalNamedClasses;
|
|
||||||
|
|
||||||
public int totalFields;
|
|
||||||
public int totalNamedFields;
|
|
||||||
|
|
||||||
public int totalNonStaticFields;
|
|
||||||
public int totalNamedNonStaticFields;
|
|
||||||
|
|
||||||
public int totalStaticFields;
|
|
||||||
public int totalNamedStaticFields;
|
|
||||||
|
|
||||||
public int totalMethods;
|
|
||||||
public int totalNamedMethods;
|
|
||||||
|
|
||||||
public int totalNonStaticMethods;
|
|
||||||
public int totalNamedNonStaticMethods;
|
|
||||||
|
|
||||||
public int totalStaticMethods;
|
|
||||||
public int totalNamedStaticMethods;
|
|
||||||
|
|
||||||
public List<MappedClass> classes;
|
|
||||||
|
|
||||||
// Static things belonging to a certain class will be in both these lists and in the classes
|
|
||||||
public List<MappedField> staticFields;
|
|
||||||
public List<MappedMethod> staticMethods;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user