Injector, deob, mixins
This commit is contained in:
44
deobfuscator/src/test/java/net/runelite/asm/ClassUtil.java
Normal file
44
deobfuscator/src/test/java/net/runelite/asm/ClassUtil.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.asm;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import net.runelite.asm.visitors.ClassFileVisitor;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
|
||||
public class ClassUtil
|
||||
{
|
||||
public static ClassFile loadClass(InputStream in) throws IOException
|
||||
{
|
||||
ClassReader reader = new ClassReader(in);
|
||||
ClassFileVisitor cv = new ClassFileVisitor();
|
||||
|
||||
reader.accept(cv, ClassReader.SKIP_FRAMES);
|
||||
|
||||
return cv.getClassFile();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.asm.annotations;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.ClassUtil;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.Annotations;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.asm.attributes.annotation.Element;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class AnnotationTest
|
||||
{
|
||||
@Test
|
||||
public void testAnnotation() throws IOException
|
||||
{
|
||||
InputStream in = this.getClass().getClassLoader().getResourceAsStream("net/runelite/asm/annotations/TestClass.class");
|
||||
Assert.assertNotNull(in);
|
||||
|
||||
ClassGroup group = new ClassGroup();
|
||||
|
||||
ClassFile cf = ClassUtil.loadClass(in);
|
||||
group.addClass(cf);
|
||||
|
||||
byte[] out = JarUtil.writeClass(group, cf);
|
||||
|
||||
// parse it again
|
||||
cf = ClassUtil.loadClass(new ByteArrayInputStream(out));
|
||||
|
||||
Method method = cf.getMethods().get(1);
|
||||
Assert.assertEquals("method1", method.getName());
|
||||
|
||||
Annotations annotations = method.getAnnotations();
|
||||
Assert.assertNotNull(annotations);
|
||||
|
||||
Optional<Annotation> annotation = annotations.getAnnotations().stream().filter(a -> a.getType().equals(new Type("Lnet/runelite/asm/annotations/MyAnnotation;"))).findFirst();
|
||||
Assert.assertTrue(annotation.isPresent());
|
||||
|
||||
Annotation an = annotation.get();
|
||||
List<Element> elements = an.getElements();
|
||||
|
||||
Assert.assertEquals(1, elements.size());
|
||||
|
||||
Element element = elements.get(0);
|
||||
|
||||
Assert.assertEquals("value", element.getName());
|
||||
Assert.assertEquals("method1", element.getValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.asm.annotations;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface MyAnnotation
|
||||
{
|
||||
String value();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.asm.annotations;
|
||||
|
||||
public class TestClass
|
||||
{
|
||||
@MyAnnotation("field1")
|
||||
public int field1;
|
||||
|
||||
@MyAnnotation("method1")
|
||||
public void method1() { }
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.asm.attributes.code.instructions;
|
||||
|
||||
import static net.runelite.asm.Type.INT;
|
||||
import net.runelite.asm.attributes.code.Instruction;
|
||||
import net.runelite.asm.attributes.code.InstructionType;
|
||||
import net.runelite.asm.attributes.code.Instructions;
|
||||
import net.runelite.asm.execution.Frame;
|
||||
import net.runelite.asm.execution.InstructionContext;
|
||||
import net.runelite.asm.execution.Stack;
|
||||
import net.runelite.asm.execution.StackContext;
|
||||
import net.runelite.asm.execution.Value;
|
||||
import net.runelite.asm.execution.VariableContext;
|
||||
import net.runelite.asm.execution.Variables;
|
||||
import net.runelite.deob.deobfuscators.mapping.ParallelExecutorMapping;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class IfEqTest
|
||||
{
|
||||
|
||||
@Test
|
||||
public void testIsSame()
|
||||
{
|
||||
Instructions ins = mock(Instructions.class);
|
||||
Frame originalIfEqFrame = mock(Frame.class);
|
||||
Stack stack = new Stack(42);
|
||||
|
||||
Variables variables = new Variables(42);
|
||||
when(originalIfEqFrame.getStack()).thenReturn(stack);
|
||||
when(originalIfEqFrame.getVariables()).thenReturn(variables);
|
||||
|
||||
variables.set(9, new VariableContext(INT));
|
||||
|
||||
Instruction i = new LDC(ins, 0);
|
||||
InstructionContext ctx = new InstructionContext(i, originalIfEqFrame);
|
||||
|
||||
// ifeq 0
|
||||
IfEq ifeq = new IfEq(ins, InstructionType.IFEQ);
|
||||
InstructionContext ifeqCtx = new InstructionContext(ifeq, originalIfEqFrame);
|
||||
ifeqCtx.pop(new StackContext(ctx, INT, new Value(1)));
|
||||
|
||||
//
|
||||
ins = mock(Instructions.class);
|
||||
Frame originalIfIcmpNeFrame = mock(Frame.class);
|
||||
stack = new Stack(42);
|
||||
variables = new Variables(42);
|
||||
when(originalIfIcmpNeFrame.getStack()).thenReturn(stack);
|
||||
when(originalIfIcmpNeFrame.getVariables()).thenReturn(variables);
|
||||
variables.set(5, new VariableContext(INT));
|
||||
|
||||
i = new LDC(ins, 1);
|
||||
InstructionContext ctx1 = new InstructionContext(i, originalIfIcmpNeFrame);
|
||||
i = new ILoad(ins, 5);
|
||||
InstructionContext ctx2 = new InstructionContext(i, originalIfIcmpNeFrame);
|
||||
|
||||
// ificmpne 1
|
||||
IfICmpNe ificmpne = new IfICmpNe(ins, InstructionType.IF_ICMPNE);
|
||||
InstructionContext ificmpneCtx = new InstructionContext(ificmpne, originalIfIcmpNeFrame);
|
||||
ificmpneCtx.pop(
|
||||
new StackContext(ctx1, INT, new Value(1)),
|
||||
new StackContext(ctx2, INT, Value.UNKNOWN)
|
||||
);
|
||||
|
||||
assertEquals(
|
||||
ifeq.isSame(ifeqCtx, ificmpneCtx),
|
||||
ificmpne.isSame(ificmpneCtx, ifeqCtx)
|
||||
);
|
||||
|
||||
// check that both frames jump the same direction
|
||||
|
||||
Frame ifeqBranchFrame = mock(Frame.class);
|
||||
ifeqCtx.branch(ifeqBranchFrame);
|
||||
|
||||
Frame ificmpneBranchFrame = mock(Frame.class);
|
||||
ificmpneCtx.branch(ificmpneBranchFrame);
|
||||
|
||||
// initially originalIfEqFrame.other == originalIfIcmpNeFrame.other
|
||||
when(originalIfEqFrame.getOther()).thenReturn(originalIfIcmpNeFrame);
|
||||
when(originalIfIcmpNeFrame.getOther()).thenReturn(originalIfEqFrame);
|
||||
|
||||
ParallelExecutorMapping mapping = mock(ParallelExecutorMapping.class);
|
||||
ifeq.map(mapping, ifeqCtx, ificmpneCtx);
|
||||
|
||||
// verify that ifeqBranchFrame.other = ificmpneBranchFrame
|
||||
ArgumentCaptor<Frame> frameCapture = ArgumentCaptor.forClass(Frame.class);
|
||||
verify(ifeqBranchFrame).setOther(frameCapture.capture());
|
||||
assertEquals(ificmpneBranchFrame, frameCapture.getValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.asm.attributes.code.instructions;
|
||||
|
||||
import static net.runelite.asm.Type.INT;
|
||||
import net.runelite.asm.attributes.code.InstructionType;
|
||||
import net.runelite.asm.attributes.code.Instructions;
|
||||
import net.runelite.asm.execution.Frame;
|
||||
import net.runelite.asm.execution.InstructionContext;
|
||||
import net.runelite.asm.execution.Stack;
|
||||
import net.runelite.asm.execution.StackContext;
|
||||
import net.runelite.asm.execution.Value;
|
||||
import net.runelite.asm.execution.Variables;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Test;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class IfICmpEqTest
|
||||
{
|
||||
|
||||
@Test
|
||||
public void testIsSame()
|
||||
{
|
||||
Instructions ins = mock(Instructions.class);
|
||||
Frame frame = mock(Frame.class);
|
||||
Stack stack = new Stack(42);
|
||||
|
||||
Variables variables = new Variables(42);
|
||||
when(frame.getStack()).thenReturn(stack);
|
||||
when(frame.getVariables()).thenReturn(variables);
|
||||
|
||||
IfICmpEq ifeq = new IfICmpEq(ins, InstructionType.IF_ICMPEQ);
|
||||
InstructionContext ifeqCtx = new InstructionContext(ifeq, frame);
|
||||
ifeqCtx.pop(new StackContext(getConstantCtx(ins, 1), INT, new Value(1)));
|
||||
ifeqCtx.pop(new StackContext(getConstantCtx(ins, 1), INT, new Value(1)));
|
||||
|
||||
IfNe ifne = new IfNe(ins, InstructionType.IFNE);
|
||||
InstructionContext ifneCtx = new InstructionContext(ifne, frame);
|
||||
ifneCtx.pop(new StackContext(getConstantCtx(ins, 42), INT, new Value(42)));
|
||||
|
||||
assertTrue(ifeq.isSame(ifeqCtx, ifneCtx));
|
||||
}
|
||||
|
||||
private InstructionContext getConstantCtx(Instructions ins, int constant)
|
||||
{
|
||||
LDC ldc = new LDC(ins, constant);
|
||||
InstructionContext pushConstantCtx = mock(InstructionContext.class);
|
||||
when(pushConstantCtx.getInstruction()).thenReturn(ldc);
|
||||
return pushConstantCtx;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.asm.attributes.code.instructions;
|
||||
|
||||
import net.runelite.asm.attributes.code.InstructionType;
|
||||
import net.runelite.asm.attributes.code.Instructions;
|
||||
import net.runelite.asm.execution.Frame;
|
||||
import net.runelite.asm.execution.InstructionContext;
|
||||
import net.runelite.asm.execution.Stack;
|
||||
import net.runelite.asm.execution.Variables;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adam
|
||||
*/
|
||||
public class LCmpTest
|
||||
{
|
||||
|
||||
@Test
|
||||
public void testIsSame()
|
||||
{
|
||||
LCmp cmp = new LCmp(mock(Instructions.class), InstructionType.LCMP);
|
||||
LCmp cmp2 = new LCmp(mock(Instructions.class), InstructionType.LCMP);
|
||||
|
||||
Frame f1 = mock(Frame.class);
|
||||
when(f1.getStack()).thenReturn(new Stack(42));
|
||||
when(f1.getVariables()).thenReturn(new Variables(42));
|
||||
|
||||
Frame f2 = mock(Frame.class);
|
||||
when(f2.getStack()).thenReturn(new Stack(42));
|
||||
when(f2.getVariables()).thenReturn(new Variables(42));
|
||||
|
||||
InstructionContext ctx1 = new InstructionContext(cmp, f1);
|
||||
InstructionContext ctx2 = new InstructionContext(cmp2, f2);
|
||||
|
||||
boolean result = cmp.isSame(ctx1, ctx2);
|
||||
Assert.assertTrue(result);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.asm.execution;
|
||||
|
||||
import java.io.File;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ExecutionTest
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Test
|
||||
public void test() throws Exception
|
||||
{
|
||||
ClassGroup group1 = JarUtil.loadJar(new File(properties.getVanillaClient()));
|
||||
Execution e = new Execution(group1);
|
||||
e.populateInitialMethods();
|
||||
e.run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.asm.execution;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.ClassUtil;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.deob.deobfuscators.mapping.MappingExecutorUtil;
|
||||
import net.runelite.deob.deobfuscators.mapping.ParallelExecutorMapping;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ParallelMappingExecutorTest
|
||||
{
|
||||
@Test
|
||||
public void testTableswitch() throws IOException
|
||||
{
|
||||
InputStream in = ParallelMappingExecutorTest.class.getResourceAsStream("tests/TableSwitch.class");
|
||||
Assert.assertNotNull(in);
|
||||
|
||||
ClassGroup group = new ClassGroup();
|
||||
ClassFile cf = ClassUtil.loadClass(in);
|
||||
group.addClass(cf);
|
||||
|
||||
in = ParallelMappingExecutorTest.class.getResourceAsStream("tests/TableSwitch.class");
|
||||
Assert.assertNotNull(in);
|
||||
|
||||
ClassGroup group2 = new ClassGroup();
|
||||
ClassFile cf2 = ClassUtil.loadClass(in);
|
||||
group2.addClass(cf2);
|
||||
|
||||
Method m1 = cf.findMethod("method");
|
||||
Method m2 = cf2.findMethod("method");
|
||||
|
||||
ParallelExecutorMapping map = MappingExecutorUtil.map(m1, m2);
|
||||
Assert.assertEquals(cf2.findField("field2"), map.get(cf.findField("field2")));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.asm.execution;
|
||||
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.ClassUtil;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.deob.deobfuscators.mapping.MappingExecutorUtil;
|
||||
import net.runelite.deob.deobfuscators.mapping.ParallelExecutorMapping;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ParallellMappingExecutorTest
|
||||
{
|
||||
@Test
|
||||
public void testStaticStep() throws Exception
|
||||
{
|
||||
ClassFile cf1 = ClassUtil.loadClass(getClass().getResourceAsStream("mapper/StaticStepTest.class"));
|
||||
ClassFile cf2 = ClassUtil.loadClass(getClass().getResourceAsStream("mapper/StaticStepTest.class"));
|
||||
|
||||
ClassGroup group1 = new ClassGroup();
|
||||
ClassGroup group2 = new ClassGroup();
|
||||
|
||||
group1.addClass(cf1);
|
||||
group2.addClass(cf2);
|
||||
|
||||
group1.buildClassGraph();
|
||||
group1.lookup();
|
||||
|
||||
group2.buildClassGraph();
|
||||
group2.lookup();
|
||||
|
||||
Method m1 = cf1.findMethod("entry");
|
||||
Method m2 = cf2.findMethod("entry");
|
||||
|
||||
Method map1 = cf1.findMethod("map"),
|
||||
map2 = cf2.findMethod("map");
|
||||
|
||||
Assert.assertNotNull(map1);
|
||||
Assert.assertNotNull(map2);
|
||||
|
||||
ParallelExecutorMapping map = MappingExecutorUtil.map(m1, m2);
|
||||
Assert.assertEquals(map2, map.get(map1));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.asm.execution.mapper;
|
||||
|
||||
public class StaticStepTest
|
||||
{
|
||||
static void func2()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void func1()
|
||||
{
|
||||
func2();
|
||||
}
|
||||
|
||||
void map()
|
||||
{
|
||||
}
|
||||
|
||||
static void entry()
|
||||
{
|
||||
func1();
|
||||
func1();
|
||||
new StaticStepTest().map();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.asm.execution.tests;
|
||||
|
||||
public class TableSwitch
|
||||
{
|
||||
public static int field1;
|
||||
public static int field2;
|
||||
public static int field3;
|
||||
public static int field4;
|
||||
|
||||
public static void method()
|
||||
{
|
||||
switch (field1)
|
||||
{
|
||||
case 0:
|
||||
field2 = 2;
|
||||
break;
|
||||
case 1:
|
||||
field3 = 3;
|
||||
break;
|
||||
case 2:
|
||||
field4 = 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.asm.signature;
|
||||
|
||||
import net.runelite.asm.Type;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SignatureTest
|
||||
{
|
||||
@Test
|
||||
public void test()
|
||||
{
|
||||
Signature signature = new Signature("f(Ljava/lang/String;II[Lch;[ILce;IIB)V");
|
||||
Type type = signature.getTypeOfArg(3);
|
||||
Assert.assertTrue(type.isArray());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.asm.visitors;
|
||||
|
||||
import java.io.File;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
public class ClassFileVisitorTest
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
@Test
|
||||
public void test() throws Exception
|
||||
{
|
||||
ClassGroup group = JarUtil.loadJar(new File(properties.getVanillaClient()));
|
||||
|
||||
JarUtil.saveJar(group, folder.newFile());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob;
|
||||
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.Field;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.Code;
|
||||
import net.runelite.asm.attributes.code.Instructions;
|
||||
import net.runelite.asm.attributes.code.instructions.VReturn;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
|
||||
public class ClassGroupFactory
|
||||
{
|
||||
private static void addVoidMethod(ClassFile cf, String name)
|
||||
{
|
||||
Method method = new Method(cf, name, new Signature("()V"));
|
||||
method.setStatic();
|
||||
cf.addMethod(method);
|
||||
|
||||
Code code = new Code(method);
|
||||
method.setCode(code);
|
||||
|
||||
Instructions ins = code.getInstructions();
|
||||
ins.addInstruction(new VReturn(ins));
|
||||
}
|
||||
|
||||
public static ClassGroup generateGroup()
|
||||
{
|
||||
ClassGroup group = new ClassGroup();
|
||||
|
||||
ClassFile cf = new ClassFile(group);
|
||||
cf.setName("test");
|
||||
cf.setSuperName("java/lang/Object");
|
||||
group.addClass(cf);
|
||||
|
||||
Field field = new Field(cf, "field", Type.INT);
|
||||
field.setStatic();
|
||||
cf.addField(field);
|
||||
|
||||
Method method = new Method(cf, "func", new Signature("()V"));
|
||||
method.setStatic();
|
||||
cf.addMethod(method);
|
||||
|
||||
Code code = new Code(method);
|
||||
method.setCode(code);
|
||||
|
||||
{
|
||||
method = new Method(cf, "func2", new Signature("(III)V"));
|
||||
method.setStatic();
|
||||
cf.addMethod(method);
|
||||
|
||||
code = new Code(method);
|
||||
method.setCode(code);
|
||||
|
||||
Instructions ins = code.getInstructions();
|
||||
ins.addInstruction(new VReturn(ins));
|
||||
}
|
||||
|
||||
addVoidMethod(cf, "void1");
|
||||
addVoidMethod(cf, "void2");
|
||||
addVoidMethod(cf, "void3");
|
||||
addVoidMethod(cf, "void4");
|
||||
|
||||
return group;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
import org.junit.rules.ExternalResource;
|
||||
|
||||
public class DeobTestProperties extends ExternalResource
|
||||
{
|
||||
private String rsClient;
|
||||
private int rsVersion;
|
||||
private String vanillaClient;
|
||||
|
||||
@Override
|
||||
protected void before() throws Throwable
|
||||
{
|
||||
Properties properties = new Properties();
|
||||
InputStream resourceAsStream = getClass().getResourceAsStream("/deob-test.properties");
|
||||
properties.load(resourceAsStream);
|
||||
|
||||
rsClient = (String) properties.get("rs.client");
|
||||
rsVersion = Integer.parseInt((String) properties.get("rs.version"));
|
||||
vanillaClient = (String) properties.get("vanilla.client");
|
||||
}
|
||||
|
||||
public String getRsClient()
|
||||
{
|
||||
return rsClient;
|
||||
}
|
||||
|
||||
public int getRsVersion()
|
||||
{
|
||||
return rsVersion;
|
||||
}
|
||||
|
||||
public String getVanillaClient()
|
||||
{
|
||||
return vanillaClient;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.deob;
|
||||
|
||||
import java.io.File;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class TemporyFolderLocation
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(TemporyFolderLocation.class);
|
||||
|
||||
static
|
||||
{
|
||||
File tmp = new File("d:/temp");
|
||||
if (tmp.exists() || tmp.mkdir())
|
||||
System.setProperty("java.io.tmpdir", "d:/temp");
|
||||
}
|
||||
|
||||
public static TemporaryFolder getTemporaryFolder()
|
||||
{
|
||||
return new TemporaryFolder();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.clientver;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ClientVersionTest
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Test
|
||||
public void test() throws IOException
|
||||
{
|
||||
ClientVersion ver = new ClientVersion(new File(properties.getVanillaClient()));
|
||||
Assert.assertEquals(properties.getRsVersion(), ver.getVersion());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators;
|
||||
|
||||
import java.util.Optional;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.Code;
|
||||
import net.runelite.asm.attributes.code.Instruction;
|
||||
import net.runelite.asm.attributes.code.InstructionType;
|
||||
import net.runelite.asm.attributes.code.Instructions;
|
||||
import net.runelite.asm.attributes.code.instructions.AConstNull;
|
||||
import net.runelite.asm.attributes.code.instructions.CheckCast;
|
||||
import net.runelite.asm.attributes.code.instructions.IAdd;
|
||||
import net.runelite.asm.attributes.code.instructions.LDC;
|
||||
import net.runelite.asm.attributes.code.instructions.Return;
|
||||
import net.runelite.deob.ClassGroupFactory;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class CastNullTest
|
||||
{
|
||||
@Test
|
||||
public void testRun()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(3);
|
||||
|
||||
CheckCast checkCast = new CheckCast(ins);
|
||||
checkCast.setType(new Type("test"));
|
||||
|
||||
Instruction[] instructions =
|
||||
{
|
||||
new LDC(ins, 2),
|
||||
new AConstNull(ins),
|
||||
checkCast,
|
||||
new LDC(ins, 2),
|
||||
new IAdd(ins),
|
||||
new Return(ins, InstructionType.IRETURN)
|
||||
};
|
||||
|
||||
for (Instruction i : instructions)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
Assert.assertEquals(6, ins.getInstructions().size());
|
||||
|
||||
CastNull lvt = new CastNull();
|
||||
lvt.run(group);
|
||||
|
||||
Assert.assertEquals(5, ins.getInstructions().size());
|
||||
|
||||
Optional<Instruction> o = ins.getInstructions().stream().filter(i -> i instanceof CheckCast).findAny();
|
||||
Assert.assertFalse(o.isPresent());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
public class EnumDeobfuscatorTest
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(new File(properties.getRsClient()));
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group, folder.newFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testRun() throws Exception
|
||||
{
|
||||
new EnumDeobfuscator().run(group);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.deob.deobfuscators;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
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 FieldInlinerTest
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(new File(properties.getVanillaClient()));
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group, folder.newFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRun()
|
||||
{
|
||||
FieldInliner fi = new FieldInliner();
|
||||
fi.run(group);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.deob.deobfuscators;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
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 IllegalStateExceptionsTest
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(new File(properties.getVanillaClient()));
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group, folder.newFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRun()
|
||||
{
|
||||
IllegalStateExceptions ise = new IllegalStateExceptions();
|
||||
ise.run(group);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators;
|
||||
|
||||
import net.runelite.asm.ClassGroup;
|
||||
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.instructions.AConstNull;
|
||||
import net.runelite.asm.attributes.code.instructions.AStore;
|
||||
import net.runelite.asm.attributes.code.instructions.IStore;
|
||||
import net.runelite.asm.attributes.code.instructions.LDC;
|
||||
import net.runelite.asm.attributes.code.instructions.LStore;
|
||||
import net.runelite.asm.attributes.code.instructions.VReturn;
|
||||
import net.runelite.deob.ClassGroupFactory;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class LvtTest
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(LvtTest.class);
|
||||
|
||||
@Test
|
||||
public void testReuseIndex()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
Instruction body[] =
|
||||
{
|
||||
// var0 = null
|
||||
new AConstNull(ins),
|
||||
new AStore(ins, 0),
|
||||
// var0 = 0
|
||||
// this forces a reindex to varn
|
||||
new LDC(ins, 0),
|
||||
new IStore(ins, 0),
|
||||
// var2 = null
|
||||
new AConstNull(ins),
|
||||
new AStore(ins, 2),
|
||||
// var2 = 0
|
||||
// this forces a reindex to varn+1
|
||||
new LDC(ins, 0),
|
||||
new IStore(ins, 2),
|
||||
//var0 = 0L
|
||||
new LDC(ins, 0L),
|
||||
new LStore(ins, 0),
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
Lvt lvt = new Lvt();
|
||||
lvt.run(group);
|
||||
|
||||
AStore astore1 = (AStore) body[1];
|
||||
IStore istore1 = (IStore) body[3];
|
||||
AStore astore2 = (AStore) body[5];
|
||||
IStore istore2 = (IStore) body[7];
|
||||
LStore lstore1 = (LStore) body[9];
|
||||
|
||||
int astore1Idx = astore1.getVariableIndex();
|
||||
int istore1Idx = istore1.getVariableIndex();
|
||||
int astore2Idx = astore2.getVariableIndex();
|
||||
int istore2Idx = istore2.getVariableIndex();
|
||||
int lstore1Idx = lstore1.getVariableIndex();
|
||||
|
||||
logger.debug("{} -> {}", astore1, astore1.getVariableIndex());
|
||||
logger.debug("{} -> {}", istore1, istore1.getVariableIndex());
|
||||
logger.debug("{} -> {}", astore2, astore2.getVariableIndex());
|
||||
logger.debug("{} -> {}", istore2, istore2.getVariableIndex());
|
||||
logger.debug("{} -> {}", lstore1, lstore1.getVariableIndex());
|
||||
|
||||
Assert.assertNotEquals(astore1Idx, istore1Idx);
|
||||
Assert.assertNotEquals(astore2Idx, istore2Idx);
|
||||
|
||||
// assert that the lstore doesn't overwrite an existing index
|
||||
Assert.assertNotEquals(lstore1Idx + 1, astore1Idx);
|
||||
Assert.assertNotEquals(lstore1Idx + 1, istore1Idx);
|
||||
Assert.assertNotEquals(lstore1Idx + 1, astore2Idx);
|
||||
Assert.assertNotEquals(lstore1Idx + 1, istore2Idx);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
public class OrderTest
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(new File(properties.getVanillaClient()));
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group, folder.newFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testRun()
|
||||
{
|
||||
Order order = new Order();
|
||||
order.run(group);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
public class PacketHandlerOrderTest
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(new File(properties.getRsClient()));
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group, folder.newFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testRun() throws IOException
|
||||
{
|
||||
PacketHandlerOrder order = new PacketHandlerOrder();
|
||||
order.run(group);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.deob.deobfuscators;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.Field;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.asm.attributes.Code;
|
||||
import net.runelite.asm.attributes.code.Instruction;
|
||||
import net.runelite.asm.attributes.code.instruction.types.InvokeInstruction;
|
||||
import net.runelite.deob.Deob;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
public class RenameUniqueTest
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(new File(properties.getVanillaClient()));
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group, folder.newFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRun()
|
||||
{
|
||||
RenameUnique renameUnique = new RenameUnique();
|
||||
renameUnique.run(group);
|
||||
|
||||
checkRenamed();
|
||||
}
|
||||
|
||||
private void checkRenamed()
|
||||
{
|
||||
for (ClassFile cf : group.getClasses())
|
||||
{
|
||||
Assert.assertTrue(cf.getName().startsWith("class") || cf.getName().equals("client"));
|
||||
|
||||
for (Field f : cf.getFields())
|
||||
{
|
||||
// synthetic fields arent obfuscated
|
||||
if (f.isSynthetic())
|
||||
continue;
|
||||
|
||||
Assert.assertTrue(f.getName().startsWith("field"));
|
||||
}
|
||||
|
||||
for (Method m : cf.getMethods())
|
||||
{
|
||||
Assert.assertTrue(m.getName().length() > 2);
|
||||
|
||||
checkCode(m.getCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkCode(Code code)
|
||||
{
|
||||
if (code == null)
|
||||
return;
|
||||
|
||||
for (Instruction i : code.getInstructions().getInstructions())
|
||||
{
|
||||
if (!(i instanceof InvokeInstruction))
|
||||
continue;
|
||||
|
||||
InvokeInstruction ii = (InvokeInstruction) i;
|
||||
Assert.assertTrue(ii.getMethod().getName().length() > Deob.OBFUSCATED_NAME_MAX_LEN
|
||||
|| ii.getMethod().getClazz().getName().length() > Deob.OBFUSCATED_NAME_MAX_LEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.deob.deobfuscators;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
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 RuntimeExceptionsTest
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(new File(properties.getVanillaClient()));
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group, folder.newFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRun()
|
||||
{
|
||||
RuntimeExceptions re = new RuntimeExceptions();
|
||||
re.run(group);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators;
|
||||
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.ClassUtil;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.asm.attributes.code.Label;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
public class UnreachedCodeTest
|
||||
{
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
ClassFile cf = ClassUtil.loadClass(UnreachedCodeTest.class.getResourceAsStream("unreachedcode/UnreachableTest.class"));
|
||||
Assert.assertNotNull(cf);
|
||||
|
||||
group = new ClassGroup();
|
||||
group.addClass(cf);
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group, folder.newFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRun() throws IOException
|
||||
{
|
||||
UnreachedCode uc = new UnreachedCode();
|
||||
uc.run(group);
|
||||
|
||||
ClassFile cf = group.getClasses().get(0);
|
||||
|
||||
Method method = cf.findMethod("entry");
|
||||
Assert.assertFalse(method.getCode().getExceptions().getExceptions().isEmpty());
|
||||
|
||||
method = cf.findMethod("method1Unused");
|
||||
Assert.assertNotNull(method);
|
||||
Assert.assertFalse(method.getCode().getInstructions().getInstructions().stream().filter(i -> !(i instanceof Label)).findAny().isPresent());
|
||||
Assert.assertTrue(method.getCode().getExceptions().getExceptions().isEmpty());
|
||||
|
||||
// Method is now invalid, remove so jar can be saved
|
||||
cf.removeMethod(method);
|
||||
|
||||
// constructor now has no instructions
|
||||
method = cf.findMethod("<init>");
|
||||
Assert.assertNotNull(method);
|
||||
Assert.assertFalse(method.getCode().getInstructions().getInstructions().stream().filter(i -> !(i instanceof Label)).findAny().isPresent());
|
||||
|
||||
// remove it too
|
||||
cf.removeMethod(method);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.ClassUtil;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
public class UnusedClassTest
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = new ClassGroup();
|
||||
|
||||
load("EmptyInterface.class");
|
||||
load("ClassA.class");
|
||||
ClassFile emptyClass = load("EmptyClass.class");
|
||||
|
||||
emptyClass.removeMethod(emptyClass.findMethod("<init>"));
|
||||
}
|
||||
|
||||
private ClassFile load(String name) throws IOException
|
||||
{
|
||||
InputStream in = UnusedClassTest.class.getResourceAsStream("unusedclass/" + name);
|
||||
Assert.assertNotNull(in);
|
||||
|
||||
ClassFile cf = ClassUtil.loadClass(in);
|
||||
group.addClass(cf);
|
||||
|
||||
return cf;
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group, folder.newFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRun()
|
||||
{
|
||||
UnusedClass uc = new UnusedClass();
|
||||
uc.run(group);
|
||||
|
||||
Assert.assertNotNull(group.findClass("net/runelite/deob/deobfuscators/unusedclass/ClassA"));
|
||||
Assert.assertNull(group.findClass("net/runelite/deob/deobfuscators/unusedclass/EmptyClass"));
|
||||
Assert.assertNotNull(group.findClass("net/runelite/deob/deobfuscators/unusedclass/EmptyInterface"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.deob.deobfuscators;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
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
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(new File(properties.getVanillaClient()));
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group, folder.newFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRun()
|
||||
{
|
||||
UnusedFields uf = new UnusedFields();
|
||||
uf.run(group);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.deob.deobfuscators;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
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 UnusedMethodsTest
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(new File(properties.getVanillaClient()));
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group, folder.newFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRun()
|
||||
{
|
||||
UnusedMethods um = new UnusedMethods();
|
||||
um.run(group);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.deob.deobfuscators;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
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 UnusedParametersTest
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(new File(properties.getVanillaClient()));
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group, folder.newFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRun()
|
||||
{
|
||||
RenameUnique r = new RenameUnique();
|
||||
r.run(group);
|
||||
r = null;
|
||||
System.gc();
|
||||
|
||||
RuntimeExceptions re = new RuntimeExceptions();
|
||||
re.run(group);
|
||||
re = null;
|
||||
System.gc();
|
||||
|
||||
UnreachedCode uc = new UnreachedCode();
|
||||
uc.run(group);
|
||||
uc = null;
|
||||
System.gc();
|
||||
|
||||
UnusedMethods um = new UnusedMethods();
|
||||
um.run(group);
|
||||
um = null;
|
||||
System.gc();
|
||||
|
||||
IllegalStateExceptions ise = new IllegalStateExceptions();
|
||||
ise.run(group);
|
||||
ise = null;
|
||||
System.gc();
|
||||
|
||||
UnusedParameters cp = new UnusedParameters();
|
||||
cp.run(group);
|
||||
cp = null;
|
||||
System.gc();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators.arithmetic;
|
||||
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.Type;
|
||||
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.instructions.AConstNull;
|
||||
import net.runelite.asm.attributes.code.instructions.Dup;
|
||||
import net.runelite.asm.attributes.code.instructions.Dup_X1;
|
||||
import net.runelite.asm.attributes.code.instructions.GetField;
|
||||
import net.runelite.asm.attributes.code.instructions.IAdd;
|
||||
import net.runelite.asm.attributes.code.instructions.ILoad;
|
||||
import net.runelite.asm.attributes.code.instructions.IMul;
|
||||
import net.runelite.asm.attributes.code.instructions.IStore;
|
||||
import net.runelite.asm.attributes.code.instructions.LDC;
|
||||
import net.runelite.asm.attributes.code.instructions.Pop2;
|
||||
import net.runelite.asm.attributes.code.instructions.VReturn;
|
||||
import net.runelite.asm.execution.Execution;
|
||||
import net.runelite.asm.pool.Class;
|
||||
import net.runelite.asm.pool.Field;
|
||||
import net.runelite.deob.ClassGroupFactory;
|
||||
import net.runelite.deob.Deobfuscator;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class DupDeobfuscatorTest
|
||||
{
|
||||
@Test
|
||||
public void test()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(5);
|
||||
|
||||
Instruction[] prepareVariables =
|
||||
{
|
||||
new LDC(ins, 1),
|
||||
new IStore(ins, 0)
|
||||
};
|
||||
|
||||
for (Instruction i : prepareVariables)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
LDC constant1 = new LDC(ins, 1129258489),
|
||||
constant2 = new LDC(ins, -1692330935),
|
||||
constant3 = new LDC(ins, 1641298955),
|
||||
constant4 = new LDC(ins, 1043501435);
|
||||
|
||||
Instruction body[] =
|
||||
{
|
||||
new AConstNull(ins), // this
|
||||
new AConstNull(ins), // this
|
||||
new ILoad(ins, 0),
|
||||
constant1,
|
||||
new IMul(ins),
|
||||
new Dup_X1(ins),
|
||||
constant2,
|
||||
new IMul(ins),
|
||||
new Pop2(ins), // putfield
|
||||
|
||||
constant3,
|
||||
new IMul(ins),
|
||||
constant4,
|
||||
new IMul(ins),
|
||||
new Pop2(ins), // putfield
|
||||
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
Execution e = new Execution(group);
|
||||
e.populateInitialMethods();
|
||||
e.run();
|
||||
|
||||
assert constant1.getConstantAsInt() * constant2.getConstantAsInt() == 1;
|
||||
assert constant3.getConstantAsInt() * constant4.getConstantAsInt() * constant1.getConstantAsInt() == 1;
|
||||
|
||||
Deobfuscator d = new DupDeobfuscator();
|
||||
d.run(group);
|
||||
|
||||
// assert the dup_x1 was removed
|
||||
long dupCount = ins.getInstructions().stream()
|
||||
.filter(i -> i instanceof Dup_X1)
|
||||
.count();
|
||||
Assert.assertEquals(0, dupCount);
|
||||
}
|
||||
|
||||
//035 aload_0 // this
|
||||
//036 dup // this this
|
||||
//037 getfield class153/field2097 I // this I
|
||||
//038 ldc 830083863
|
||||
//039 imul // this I
|
||||
//040 ldc 830083863
|
||||
//041 iadd // this I
|
||||
//042 dup_x1 // I this I
|
||||
@Test
|
||||
public void test2()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(3);
|
||||
|
||||
Instruction body[] =
|
||||
{
|
||||
new AConstNull(ins), // this
|
||||
new Dup(ins), // this this
|
||||
new GetField(ins, new Field(new Class("test"), "field", Type.INT)),
|
||||
new LDC(ins, 830083863), // this this I I
|
||||
new IMul(ins), // this this I
|
||||
new LDC(ins, 830083863),
|
||||
new IAdd(ins),
|
||||
new Dup_X1(ins),
|
||||
new LDC(ins, 636900519),
|
||||
new IMul(ins), // pops dup
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
Execution e = new Execution(group);
|
||||
e.populateInitialMethods();
|
||||
e.run();
|
||||
|
||||
Deobfuscator d = new DupDeobfuscator();
|
||||
d.run(group);
|
||||
|
||||
// assert the dup wasn't duplicated
|
||||
long dupCount = ins.getInstructions().stream()
|
||||
.filter(i -> i instanceof Dup)
|
||||
.count();
|
||||
Assert.assertEquals(1, dupCount);
|
||||
|
||||
// assert the dup_x1 was removed
|
||||
dupCount = ins.getInstructions().stream()
|
||||
.filter(i -> i instanceof Dup_X1)
|
||||
.count();
|
||||
Assert.assertEquals(0, dupCount);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.deob.deobfuscators.arithmetic;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
public class ModArithTest
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(new File(properties.getVanillaClient()));
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group, folder.newFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testRun()
|
||||
{
|
||||
ModArith mod = new ModArith();
|
||||
mod.run(group);
|
||||
|
||||
int last = -1, cur;
|
||||
while ((cur = mod.runOnce()) > 0)
|
||||
{
|
||||
new MultiplicationDeobfuscator().run(group);
|
||||
|
||||
new MultiplyOneDeobfuscator(true).run(group);
|
||||
|
||||
new MultiplyZeroDeobfuscator().run(group);
|
||||
|
||||
if (last == cur)
|
||||
break;
|
||||
|
||||
last = cur;
|
||||
}
|
||||
|
||||
mod.annotateEncryption();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,919 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators.arithmetic;
|
||||
|
||||
import net.runelite.asm.ClassGroup;
|
||||
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.Label;
|
||||
import net.runelite.asm.attributes.code.instructions.AConstNull;
|
||||
import net.runelite.asm.attributes.code.instructions.Dup2_X1;
|
||||
import net.runelite.asm.attributes.code.instructions.Dup_X1;
|
||||
import net.runelite.asm.attributes.code.instructions.Goto;
|
||||
import net.runelite.asm.attributes.code.instructions.IAdd;
|
||||
import net.runelite.asm.attributes.code.instructions.ILoad;
|
||||
import net.runelite.asm.attributes.code.instructions.IMul;
|
||||
import net.runelite.asm.attributes.code.instructions.IStore;
|
||||
import net.runelite.asm.attributes.code.instructions.IfEq;
|
||||
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
|
||||
import net.runelite.asm.attributes.code.instructions.LDC;
|
||||
import net.runelite.asm.attributes.code.instructions.LLoad;
|
||||
import net.runelite.asm.attributes.code.instructions.LMul;
|
||||
import net.runelite.asm.attributes.code.instructions.LStore;
|
||||
import net.runelite.asm.attributes.code.instructions.Pop;
|
||||
import net.runelite.asm.attributes.code.instructions.Pop2;
|
||||
import net.runelite.asm.attributes.code.instructions.SiPush;
|
||||
import net.runelite.asm.attributes.code.instructions.Swap;
|
||||
import net.runelite.asm.attributes.code.instructions.VReturn;
|
||||
import net.runelite.asm.execution.Execution;
|
||||
import net.runelite.deob.ClassGroupFactory;
|
||||
import net.runelite.deob.Deobfuscator;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class MultiplicationDeobfuscatorTest
|
||||
{
|
||||
// aload 2
|
||||
// ldc_w 1587543155
|
||||
// iload 4
|
||||
// imul
|
||||
// dup_x1
|
||||
// ldc_w -2130376517
|
||||
// imul
|
||||
// putfield class2/field279 I
|
||||
// ldc_w -67313687
|
||||
// imul
|
||||
// putstatic class29/field949 I
|
||||
@Test
|
||||
public void test1()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(5);
|
||||
|
||||
// vars[0] = 3
|
||||
Instruction[] prepareVariables =
|
||||
{
|
||||
new LDC(ins, 3),
|
||||
new IStore(ins, 0)
|
||||
};
|
||||
|
||||
for (Instruction i : prepareVariables)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
LDC constant1 = new LDC(ins, 1587543155),
|
||||
constant2 = new LDC(ins, -2130376517),
|
||||
constant3 = new LDC(ins, -67313687);
|
||||
|
||||
Instruction body[] =
|
||||
{
|
||||
new LDC(ins, 0), // for dup_x1 to place before this
|
||||
constant1,
|
||||
new ILoad(ins, 0),
|
||||
new IMul(ins),
|
||||
new Dup_X1(ins),
|
||||
constant2,
|
||||
new IMul(ins),
|
||||
new Pop(ins),
|
||||
new Pop(ins),
|
||||
constant3,
|
||||
new IMul(ins),
|
||||
new Pop(ins),
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
// check execution runs ok
|
||||
Execution e = new Execution(group);
|
||||
e.populateInitialMethods();
|
||||
e.run();
|
||||
|
||||
assert constant1.getConstantAsInt() * constant2.getConstantAsInt() == 1;
|
||||
assert constant1.getConstantAsInt() * constant3.getConstantAsInt() == -1_095_175_765;
|
||||
|
||||
Deobfuscator d = new MultiplicationDeobfuscator();
|
||||
d.run(group);
|
||||
|
||||
Assert.assertEquals(1, constant1.getConstantAsInt());
|
||||
Assert.assertEquals(1, constant2.getConstantAsInt());
|
||||
Assert.assertEquals(-1_095_175_765, constant3.getConstantAsInt());
|
||||
}
|
||||
|
||||
// aload_0
|
||||
// dup
|
||||
// getfield class118/field2201 I
|
||||
// ldc_w -2079217519
|
||||
// imul
|
||||
// ldc -2079217519
|
||||
// iadd
|
||||
// dup_x1
|
||||
// ldc_w 561453169
|
||||
// imul
|
||||
// putfield class118/field2201 I
|
||||
// ldc 561453169
|
||||
// imul
|
||||
@Test
|
||||
public void test2()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(4);
|
||||
|
||||
// vars[0] = 3
|
||||
Instruction[] prepareVariables =
|
||||
{
|
||||
new LDC(ins, 3),
|
||||
new IStore(ins, 0)
|
||||
};
|
||||
|
||||
for (Instruction i : prepareVariables)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
LDC constant1 = new LDC(ins, -2079217519),
|
||||
constant2 = new LDC(ins, -2079217519),
|
||||
constant3 = new LDC(ins, 561453169),
|
||||
constant4 = new LDC(ins, 561453169);
|
||||
|
||||
Instruction body[] =
|
||||
{
|
||||
new LDC(ins, 0), // for dup_x1 to place before this
|
||||
new ILoad(ins, 0),
|
||||
constant1,
|
||||
new IMul(ins),
|
||||
constant2,
|
||||
new IAdd(ins),
|
||||
new Dup_X1(ins), // result, 0, result
|
||||
constant3,
|
||||
new IMul(ins),
|
||||
new Pop(ins),
|
||||
new Pop(ins),
|
||||
constant4,
|
||||
new IMul(ins),
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
Execution e = new Execution(group);
|
||||
e.populateInitialMethods();
|
||||
e.run();
|
||||
|
||||
assert constant1.getConstantAsInt() * constant3.getConstantAsInt() == 1;
|
||||
assert constant2.getConstantAsInt() * constant4.getConstantAsInt() == 1;
|
||||
|
||||
Deobfuscator d = new MultiplicationDeobfuscator();
|
||||
d.run(group);
|
||||
|
||||
Assert.assertEquals(1, constant1.getConstantAsInt());
|
||||
Assert.assertEquals(1, constant2.getConstantAsInt());
|
||||
Assert.assertEquals(1, constant3.getConstantAsInt());
|
||||
Assert.assertEquals(1, constant4.getConstantAsInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test3()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(2);
|
||||
|
||||
Instruction[] prepareVariables =
|
||||
{
|
||||
new LDC(ins, 3),
|
||||
new IStore(ins, 0),
|
||||
};
|
||||
|
||||
for (Instruction i : prepareVariables)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
LDC constant1 = new LDC(ins, 1381104939),
|
||||
constant2 = new LDC(ins, 1381104939),
|
||||
constant3 = new LDC(ins, 981643079),
|
||||
constant4 = new LDC(ins, 1807370871),
|
||||
constant5 = new LDC(ins, 981643079);
|
||||
|
||||
Label label1 = new Label(ins);
|
||||
|
||||
Instruction body[] =
|
||||
{
|
||||
constant4,
|
||||
constant1,
|
||||
new ILoad(ins, 0),
|
||||
new IMul(ins),
|
||||
new LDC(ins, 0),
|
||||
new IfEq(ins, label1),
|
||||
constant2,
|
||||
new IMul(ins),
|
||||
label1,
|
||||
constant3,
|
||||
new IMul(ins),
|
||||
new IMul(ins), // constant4
|
||||
constant5,
|
||||
new IMul(ins),
|
||||
new Pop(ins),
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
Execution e = new Execution(group);
|
||||
e.populateInitialMethods();
|
||||
e.run();
|
||||
|
||||
assert constant4.getConstantAsInt() * constant5.getConstantAsInt() == 1;
|
||||
|
||||
// {
|
||||
// Collection<InstructionContext> ctxs = e.getInstructonContexts(body[3]);
|
||||
// assert ctxs.size() == 1;
|
||||
//
|
||||
// InstructionContext ictx = ctxs.iterator().next();
|
||||
// boolean onlyPath = MultiplicationDeobfuscator.isOnlyPath(e, ictx);
|
||||
// Assert.assertFalse(onlyPath);
|
||||
// }
|
||||
Deobfuscator d = new MultiplicationDeobfuscator();
|
||||
d.run(group);
|
||||
|
||||
Assert.assertEquals(1381104939, constant1.getConstantAsInt());
|
||||
Assert.assertEquals(1381104939, constant2.getConstantAsInt());
|
||||
Assert.assertEquals(1, constant3.getConstantAsInt());
|
||||
Assert.assertEquals(1, constant4.getConstantAsInt());
|
||||
Assert.assertEquals(981643079, constant5.getConstantAsInt()); // assumes result is moved to the end here.
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test4()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(2);
|
||||
|
||||
Instruction[] prepareVariables =
|
||||
{
|
||||
new LDC(ins, 3),
|
||||
new IStore(ins, 0),
|
||||
};
|
||||
|
||||
for (Instruction i : prepareVariables)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
LDC constant1 = new LDC(ins, 1807370871);
|
||||
LDC constant2 = new LDC(ins, 981643079);
|
||||
|
||||
Label label1 = new Label(ins);
|
||||
|
||||
Instruction body[] =
|
||||
{
|
||||
new ILoad(ins, 0),
|
||||
new LDC(ins, 2),
|
||||
new IMul(ins),
|
||||
new LDC(ins, 0),
|
||||
new IfEq(ins, label1),
|
||||
new Pop(ins),
|
||||
new LDC(ins, 3),
|
||||
label1,
|
||||
constant1,
|
||||
new IMul(ins),
|
||||
constant2,
|
||||
new IMul(ins),
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
Execution e = new Execution(group);
|
||||
e.populateInitialMethods();
|
||||
e.run();
|
||||
|
||||
assert constant1.getConstantAsInt() * constant2.getConstantAsInt() == 1;
|
||||
|
||||
Deobfuscator d = new MultiplicationDeobfuscator();
|
||||
d.run(group);
|
||||
|
||||
Assert.assertEquals(1, constant1.getConstantAsInt());
|
||||
Assert.assertEquals(1, constant2.getConstantAsInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test5()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(2);
|
||||
|
||||
Instruction[] prepareVariables =
|
||||
{
|
||||
new LDC(ins, 3),
|
||||
new IStore(ins, 0),
|
||||
new LDC(ins, 2),
|
||||
new IStore(ins, 1)
|
||||
};
|
||||
|
||||
for (Instruction i : prepareVariables)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
LDC constant1 = new LDC(ins, -2079217519),
|
||||
constant2 = new LDC(ins, -2079217519),
|
||||
constant3 = new LDC(ins, 561453169);
|
||||
|
||||
Instruction body[] =
|
||||
{
|
||||
new ILoad(ins, 0),
|
||||
constant1,
|
||||
new IMul(ins),
|
||||
new IStore(ins, 2),
|
||||
new ILoad(ins, 2),
|
||||
new ILoad(ins, 1),
|
||||
constant2,
|
||||
new IMul(ins),
|
||||
new IAdd(ins),
|
||||
constant3,
|
||||
new IMul(ins),
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
Execution e = new Execution(group);
|
||||
e.populateInitialMethods();
|
||||
e.run();
|
||||
|
||||
assert constant1.getConstantAsInt() * constant3.getConstantAsInt() == 1;
|
||||
|
||||
Deobfuscator d = new MultiplicationDeobfuscator();
|
||||
d.run(group);
|
||||
|
||||
Assert.assertEquals(1, constant1.getConstantAsInt());
|
||||
Assert.assertEquals(1, constant2.getConstantAsInt());
|
||||
Assert.assertEquals(1, constant3.getConstantAsInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test6()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(2);
|
||||
|
||||
Instruction[] prepareVariables =
|
||||
{
|
||||
new LDC(ins, 3),
|
||||
new IStore(ins, 0),
|
||||
new LDC(ins, 2),
|
||||
new IStore(ins, 1)
|
||||
};
|
||||
|
||||
for (Instruction i : prepareVariables)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
LDC constant1 = new LDC(ins, 575391417);
|
||||
LDC constant2 = new LDC(ins, -497786999);
|
||||
|
||||
Instruction body[] =
|
||||
{
|
||||
new ILoad(ins, 0),
|
||||
new ILoad(ins, 1),
|
||||
new Dup_X1(ins),
|
||||
new Pop(ins),
|
||||
new Pop(ins),
|
||||
constant1,
|
||||
new IMul(ins),
|
||||
constant2,
|
||||
new IMul(ins),
|
||||
new Pop(ins),
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
Execution e = new Execution(group);
|
||||
e.populateInitialMethods();
|
||||
e.run();
|
||||
|
||||
assert constant1.getConstantAsInt() * constant2.getConstantAsInt() == 1;
|
||||
|
||||
Deobfuscator d = new MultiplicationDeobfuscator();
|
||||
d.run(group);
|
||||
|
||||
Assert.assertEquals(1, constant1.getConstantAsInt());
|
||||
Assert.assertEquals(1, constant2.getConstantAsInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test7()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(2);
|
||||
|
||||
Instruction[] prepareVariables =
|
||||
{
|
||||
new LDC(ins, 3),
|
||||
new IStore(ins, 0),
|
||||
new LDC(ins, 2),
|
||||
new IStore(ins, 1)
|
||||
};
|
||||
|
||||
for (Instruction i : prepareVariables)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
LDC constant1 = new LDC(ins, 2131037801),
|
||||
constant2 = new LDC(ins, -1306959399),
|
||||
constant3 = new LDC(ins, -1);
|
||||
|
||||
Instruction body[] =
|
||||
{
|
||||
constant3,
|
||||
constant1,
|
||||
new IMul(ins),
|
||||
constant2,
|
||||
new IMul(ins),
|
||||
new Pop(ins),
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
Execution e = new Execution(group);
|
||||
e.populateInitialMethods();
|
||||
e.run();
|
||||
|
||||
assert constant1.getConstantAsInt() * constant2.getConstantAsInt() == 1;
|
||||
|
||||
Deobfuscator d = new MultiplicationDeobfuscator();
|
||||
d.run(group);
|
||||
|
||||
Assert.assertEquals(1, constant1.getConstantAsInt());
|
||||
Assert.assertEquals(-1, constant2.getConstantAsInt());
|
||||
Assert.assertEquals(1, constant3.getConstantAsInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test8()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(2);
|
||||
|
||||
Instruction[] prepareVariables =
|
||||
{
|
||||
new LDC(ins, 3),
|
||||
new IStore(ins, 0)
|
||||
};
|
||||
|
||||
for (Instruction i : prepareVariables)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
LDC constant1 = new LDC(ins, -1616202347);
|
||||
LDC constant2 = new LDC(ins, 2747837);
|
||||
|
||||
Label label1 = new Label(ins),
|
||||
label2 = new Label(ins),
|
||||
label3 = new Label(ins);
|
||||
|
||||
Instruction body[] =
|
||||
{
|
||||
constant1,
|
||||
constant2,
|
||||
new IMul(ins),
|
||||
new ILoad(ins, 0),
|
||||
new LDC(ins, 42),
|
||||
new IfEq(ins, label1),
|
||||
new Goto(ins, label2),
|
||||
label1,
|
||||
new LDC(ins, -1),
|
||||
new Goto(ins, label3),
|
||||
label2,
|
||||
new LDC(ins, 0),
|
||||
new Goto(ins, label3),
|
||||
label3,
|
||||
new InvokeStatic(ins, group.findClass("test").findMethod("func2").getPoolMethod()),
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
Execution e = new Execution(group);
|
||||
e.populateInitialMethods();
|
||||
e.run();
|
||||
|
||||
assert constant1.getConstantAsInt() * constant2.getConstantAsInt() == 1;
|
||||
|
||||
Deobfuscator d = new MultiplicationDeobfuscator();
|
||||
d.run(group);
|
||||
|
||||
Assert.assertEquals(1, constant1.getConstantAsInt());
|
||||
Assert.assertEquals(1, constant2.getConstantAsInt());
|
||||
}
|
||||
|
||||
// aload 0
|
||||
// aload 0
|
||||
// aload 1
|
||||
// invokevirtual class226/method4078()J
|
||||
// ldc2_w -81013729583719545
|
||||
// lmul
|
||||
// dup2_x1
|
||||
// ldc2_w -6236978337732675017
|
||||
// lmul
|
||||
// putfield class227/field3204 J
|
||||
// ldc2_w -6236978337732675017
|
||||
// lmul
|
||||
// putfield class227/field3196 J
|
||||
@Test
|
||||
public void test9()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(3);
|
||||
|
||||
Instruction[] prepareVariables =
|
||||
{
|
||||
new LDC(ins, 1L),
|
||||
new LStore(ins, 0)
|
||||
};
|
||||
|
||||
for (Instruction i : prepareVariables)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
LDC constant1 = new LDC(ins, -81013729583719545L),
|
||||
constant2 = new LDC(ins, -6236978337732675017L),
|
||||
constant3 = new LDC(ins, -6236978337732675017L);
|
||||
|
||||
Instruction body[] =
|
||||
{
|
||||
new LDC(ins, 0),
|
||||
new LLoad(ins, 0),
|
||||
constant1,
|
||||
new LMul(ins),
|
||||
new Dup2_X1(ins), // lmul, 0, lmul
|
||||
|
||||
constant2,
|
||||
new LMul(ins),
|
||||
new Pop(ins),
|
||||
new Pop(ins),
|
||||
constant3,
|
||||
new LMul(ins),
|
||||
new Pop(ins),
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
Execution e = new Execution(group);
|
||||
e.populateInitialMethods();
|
||||
e.run();
|
||||
|
||||
assert constant1.getConstantAsLong() * constant2.getConstantAsLong() == 1L;
|
||||
|
||||
Deobfuscator d = new MultiplicationDeobfuscator();
|
||||
d.run(group);
|
||||
|
||||
Assert.assertEquals(1L, constant1.getConstantAsLong());
|
||||
Assert.assertEquals(1L, constant2.getConstantAsLong());
|
||||
Assert.assertEquals(1L, constant3.getConstantAsLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test10()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(5);
|
||||
|
||||
// vars[0] = 3
|
||||
Instruction[] prepareVariables =
|
||||
{
|
||||
new LDC(ins, 3),
|
||||
new IStore(ins, 0)
|
||||
};
|
||||
|
||||
for (Instruction i : prepareVariables)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
LDC constant1 = new LDC(ins, -1729723287);
|
||||
LDC constant2 = new LDC(ins, -143176743);
|
||||
|
||||
Instruction body[] =
|
||||
{
|
||||
new ILoad(ins, 0),
|
||||
constant1,
|
||||
new IMul(ins),
|
||||
constant2,
|
||||
new IMul(ins),
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
// check execution runs ok
|
||||
Execution e = new Execution(group);
|
||||
e.populateInitialMethods();
|
||||
e.run();
|
||||
|
||||
assert constant1.getConstantAsInt() * constant2.getConstantAsInt() == 1;
|
||||
|
||||
Deobfuscator d = new MultiplicationDeobfuscator();
|
||||
d.run(group);
|
||||
|
||||
Assert.assertEquals(1, constant1.getConstantAsInt());
|
||||
Assert.assertEquals(1, constant2.getConstantAsInt());
|
||||
}
|
||||
|
||||
//020 aload_0
|
||||
//021 aload_0
|
||||
//022 iload_1
|
||||
//023 ldc 1129258489
|
||||
//024 imul
|
||||
//025 dup_x1
|
||||
//026 ldc -1692330935
|
||||
//027 imul
|
||||
//028 putfield class81/field1351 I
|
||||
//029 ldc 1641298955
|
||||
//030 imul // this pops other side of dup_x1
|
||||
//031 ldc 1043501435
|
||||
//032 imul
|
||||
//033 putfield class81/field1326 I
|
||||
@Test
|
||||
public void test11()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(5);
|
||||
|
||||
Instruction[] prepareVariables =
|
||||
{
|
||||
new LDC(ins, 1),
|
||||
new IStore(ins, 0)
|
||||
};
|
||||
|
||||
for (Instruction i : prepareVariables)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
LDC constant1 = new LDC(ins, 1129258489),
|
||||
constant2 = new LDC(ins, -1692330935),
|
||||
constant3 = new LDC(ins, 1641298955),
|
||||
constant4 = new LDC(ins, 1043501435);
|
||||
|
||||
Instruction body[] =
|
||||
{
|
||||
new AConstNull(ins), // this
|
||||
new AConstNull(ins), // this
|
||||
new ILoad(ins, 0),
|
||||
constant1,
|
||||
new IMul(ins),
|
||||
new Dup_X1(ins),
|
||||
constant2,
|
||||
new IMul(ins),
|
||||
new Pop2(ins), // putfield
|
||||
|
||||
constant3,
|
||||
new IMul(ins),
|
||||
constant4,
|
||||
new IMul(ins),
|
||||
new Pop2(ins), // putfield
|
||||
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
Execution e = new Execution(group);
|
||||
e.populateInitialMethods();
|
||||
e.run();
|
||||
|
||||
assert constant1.getConstantAsInt() * constant2.getConstantAsInt() == 1;
|
||||
assert constant3.getConstantAsInt() * constant4.getConstantAsInt() * constant1.getConstantAsInt() == 1;
|
||||
;
|
||||
Deobfuscator d = new MultiplicationDeobfuscator();
|
||||
d.run(group);
|
||||
|
||||
Assert.assertEquals(1, constant1.getConstantAsInt());
|
||||
Assert.assertEquals(1, constant2.getConstantAsInt());
|
||||
Assert.assertEquals(1, constant3.getConstantAsInt());
|
||||
Assert.assertEquals(1, constant4.getConstantAsInt());
|
||||
}
|
||||
|
||||
//020 aload_0
|
||||
//021 aload_0
|
||||
//022 iload_1
|
||||
//023 ldc 1129258489
|
||||
//024 imul // this, this, mul
|
||||
//025 swap // this, mul s, this
|
||||
//026 iload_1
|
||||
//027 iconst_1
|
||||
//028 imul // this, mul s, this, mul
|
||||
//029 iconst_1
|
||||
//030 imul
|
||||
//031 putfield class81/field1351 I // this, mul
|
||||
//032 iconst_1
|
||||
//033 imul
|
||||
//034 ldc -1692330935
|
||||
//035 imul
|
||||
//036 putfield class81/field1326 I
|
||||
@Test
|
||||
public void test12()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(5);
|
||||
|
||||
Instruction[] prepareVariables =
|
||||
{
|
||||
new LDC(ins, 1),
|
||||
new IStore(ins, 0)
|
||||
};
|
||||
|
||||
for (Instruction i : prepareVariables)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
LDC constant1 = new LDC(ins, 1129258489);
|
||||
LDC constant2 = new LDC(ins, -1692330935);
|
||||
|
||||
Instruction body[] =
|
||||
{
|
||||
new AConstNull(ins), // this
|
||||
new AConstNull(ins), // this
|
||||
new ILoad(ins, 0),
|
||||
constant1,
|
||||
new IMul(ins),
|
||||
new Swap(ins), // null, mul, null
|
||||
|
||||
new ILoad(ins, 0),
|
||||
new Pop2(ins), // putfield
|
||||
|
||||
constant2,
|
||||
new IMul(ins),
|
||||
new Pop2(ins), // putfield
|
||||
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
Execution e = new Execution(group);
|
||||
e.populateInitialMethods();
|
||||
e.run();
|
||||
|
||||
assert constant1.getConstantAsInt() * constant2.getConstantAsInt() == 1;
|
||||
|
||||
Deobfuscator d = new MultiplicationDeobfuscator();
|
||||
d.run(group);
|
||||
|
||||
Assert.assertEquals(1, constant1.getConstantAsInt());
|
||||
Assert.assertEquals(1, constant2.getConstantAsInt());
|
||||
}
|
||||
|
||||
//sipush 512
|
||||
//ldc -688421113
|
||||
//imul
|
||||
//ldc -585812297
|
||||
//imul
|
||||
//putstatic class134/field2009 I
|
||||
@Test
|
||||
public void test13()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(2);
|
||||
|
||||
LDC constant1 = new LDC(ins, -688421113);
|
||||
LDC constant2 = new LDC(ins, -585812297);
|
||||
|
||||
Instruction body[] =
|
||||
{
|
||||
new SiPush(ins, (short) 512),
|
||||
constant1,
|
||||
new IMul(ins),
|
||||
constant2,
|
||||
new IMul(ins),
|
||||
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
Execution e = new Execution(group);
|
||||
e.populateInitialMethods();
|
||||
e.run();
|
||||
|
||||
assert constant1.getConstantAsInt() * constant2.getConstantAsInt() == 1;
|
||||
|
||||
Deobfuscator d = new MultiplicationDeobfuscator();
|
||||
d.run(group);
|
||||
|
||||
Assert.assertEquals(1, constant1.getConstantAsInt());
|
||||
Assert.assertEquals(1, constant2.getConstantAsInt());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.deob.deobfuscators.arithmetic;
|
||||
|
||||
import net.runelite.asm.ClassGroup;
|
||||
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.Label;
|
||||
import net.runelite.asm.attributes.code.instructions.Goto;
|
||||
import net.runelite.asm.attributes.code.instructions.IDiv;
|
||||
import net.runelite.asm.attributes.code.instructions.ILoad;
|
||||
import net.runelite.asm.attributes.code.instructions.IMul;
|
||||
import net.runelite.asm.attributes.code.instructions.IStore;
|
||||
import net.runelite.asm.attributes.code.instructions.IfEq;
|
||||
import net.runelite.asm.attributes.code.instructions.IfICmpEq;
|
||||
import net.runelite.asm.attributes.code.instructions.LDC;
|
||||
import net.runelite.asm.attributes.code.instructions.SiPush;
|
||||
import net.runelite.asm.attributes.code.instructions.VReturn;
|
||||
import net.runelite.asm.execution.Execution;
|
||||
import net.runelite.deob.ClassGroupFactory;
|
||||
import net.runelite.deob.Deobfuscator;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class MultiplyOneDeobfuscatorTest
|
||||
{
|
||||
@Test
|
||||
public void testDir()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(2);
|
||||
|
||||
// vars[0] = 3
|
||||
Instruction[] prepareVariables = {
|
||||
new LDC(ins, 3),
|
||||
new IStore(ins, 0)
|
||||
};
|
||||
|
||||
for (Instruction i : prepareVariables)
|
||||
ins.addInstruction(i);
|
||||
|
||||
Label label = new Label(ins),
|
||||
label2 = new Label(ins);
|
||||
|
||||
LDC one = new LDC(ins, 1);
|
||||
|
||||
Instruction body[] = {
|
||||
new SiPush(ins, (short) 256),
|
||||
|
||||
new ILoad(ins, 0),
|
||||
new IfEq(ins, label),
|
||||
|
||||
new LDC(ins, 2),
|
||||
new Goto(ins, label2),
|
||||
|
||||
label,
|
||||
one,
|
||||
|
||||
label2,
|
||||
new IMul(ins),
|
||||
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
ins.addInstruction(i);
|
||||
|
||||
// check execution runs ok
|
||||
Execution e = new Execution(group);
|
||||
e.populateInitialMethods();
|
||||
e.run();
|
||||
|
||||
Deobfuscator d = new MultiplyOneDeobfuscator(false);
|
||||
d.run(group);
|
||||
|
||||
Assert.assertTrue(one.getInstructions() != null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(2);
|
||||
|
||||
// vars[0] = 3
|
||||
Instruction[] prepareVariables = {
|
||||
new LDC(ins, 3),
|
||||
new IStore(ins, 0)
|
||||
};
|
||||
|
||||
for (Instruction i : prepareVariables)
|
||||
ins.addInstruction(i);
|
||||
|
||||
Label label = new Label(ins),
|
||||
label2 = new Label(ins);
|
||||
|
||||
LDC one = new LDC(ins, 1);
|
||||
IMul mul = new IMul(ins);
|
||||
|
||||
Instruction body[] = {
|
||||
new SiPush(ins, (short) 256),
|
||||
|
||||
new ILoad(ins, 0),
|
||||
new IfEq(ins, label),
|
||||
|
||||
label,
|
||||
one,
|
||||
|
||||
label2,
|
||||
mul,
|
||||
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
ins.addInstruction(i);
|
||||
|
||||
// check execution runs ok
|
||||
Execution e = new Execution(group);
|
||||
e.populateInitialMethods();
|
||||
e.run();
|
||||
|
||||
Deobfuscator d = new MultiplyOneDeobfuscator(false);
|
||||
d.run(group);
|
||||
|
||||
Assert.assertTrue(one.getInstructions() == null);
|
||||
Assert.assertTrue(mul.getInstructions() == null);
|
||||
}
|
||||
|
||||
// iconst_1
|
||||
// iconst_m1
|
||||
// iload 5
|
||||
// if_icmpeq LABEL0x56d1
|
||||
// iload 5
|
||||
// iconst_1
|
||||
// if_icmpne LABEL0x56e8
|
||||
// goto LABEL0x56d1
|
||||
//LABEL0x56d1:
|
||||
// getstatic class139/field2130 I
|
||||
// ldc_w -1440517609
|
||||
// imul
|
||||
// goto LABEL0x5708
|
||||
//LABEL0x56e8:
|
||||
// getstatic class139/field2130 I
|
||||
// ldc_w -1440517609
|
||||
// imul
|
||||
// getstatic client/field377 I
|
||||
// iadd
|
||||
// iconst_2
|
||||
// idiv
|
||||
//LABEL0x5708:
|
||||
// imul
|
||||
// putstatic client/field377 I
|
||||
//
|
||||
// client.field377 = 1 * (-1 != var5 && var5 != 1?(class139.field2130 + client.field377) / 2:class139.field2130);
|
||||
@Test
|
||||
public void test2()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(2);
|
||||
|
||||
// vars[0] = 3
|
||||
Instruction[] prepareVariables = {
|
||||
new LDC(ins, 3),
|
||||
new IStore(ins, 0),
|
||||
new LDC(ins, 2),
|
||||
new IStore(ins, 1)
|
||||
};
|
||||
|
||||
for (Instruction i : prepareVariables)
|
||||
ins.addInstruction(i);
|
||||
|
||||
Label label = new Label(ins),
|
||||
label2 = new Label(ins),
|
||||
label3 = new Label(ins);
|
||||
|
||||
LDC one = new LDC(ins, 1);
|
||||
IMul mul = new IMul(ins);
|
||||
|
||||
Instruction body[] = {
|
||||
one,
|
||||
|
||||
new LDC(ins, -1),
|
||||
new ILoad(ins, 0),
|
||||
new IfICmpEq(ins, label),
|
||||
|
||||
new Goto(ins, label2),
|
||||
|
||||
label,
|
||||
new ILoad(ins, 1),
|
||||
new LDC(ins, -1440517609),
|
||||
new IDiv(ins),
|
||||
new Goto(ins, label3),
|
||||
|
||||
label2,
|
||||
new ILoad(ins, 1),
|
||||
new LDC(ins, -1440517609),
|
||||
new IDiv(ins),
|
||||
|
||||
label3,
|
||||
mul,
|
||||
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
ins.addInstruction(i);
|
||||
|
||||
// check execution runs ok
|
||||
Execution e = new Execution(group);
|
||||
e.populateInitialMethods();
|
||||
e.run();
|
||||
|
||||
Deobfuscator d = new MultiplyOneDeobfuscator(false);
|
||||
d.run(group);
|
||||
|
||||
Assert.assertTrue(one.getInstructions() == null);
|
||||
Assert.assertTrue(mul.getInstructions() == null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.deob.deobfuscators.arithmetic;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
public class MultiplyZeroDeobfuscatorTest
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(new File(properties.getVanillaClient()));
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group, folder.newFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testRun()
|
||||
{
|
||||
MultiplyZeroDeobfuscator m = new MultiplyZeroDeobfuscator();
|
||||
m.run(group);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators.arithmetic;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.ClassUtil;
|
||||
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.instructions.LDC;
|
||||
import net.runelite.deob.Deobfuscator;
|
||||
import org.junit.Assert;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import org.junit.Test;
|
||||
|
||||
class TestClass
|
||||
{
|
||||
private static int dummy(Object... args)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int field1051 = -1611704481;
|
||||
private int field2701;
|
||||
private int field2138, field2130;
|
||||
|
||||
public void test()
|
||||
{
|
||||
TestClass tc = new TestClass(); // to trick executor to call the constructor
|
||||
int var = 42;
|
||||
|
||||
if (-1 != this.field1051 * 1928543073)
|
||||
{
|
||||
dummy(this.field1051 * 1928543073);
|
||||
this.field1051 = dummy() * 1611704481;
|
||||
}
|
||||
|
||||
if (field2701 * 1550405721 > 30000)
|
||||
{
|
||||
field2701 += -1868498967 * var;
|
||||
}
|
||||
|
||||
field2138 = tc.dummy() * 1510226873;
|
||||
field2130 = 572701809 * tc.field2138;
|
||||
if (-1722291303 * field2130 >= var)
|
||||
{
|
||||
var = field2130 * -1722291303;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TestClass2
|
||||
{
|
||||
int field2863;
|
||||
int array[];
|
||||
|
||||
public void test()
|
||||
{
|
||||
TestClass2 tc = new TestClass2();
|
||||
|
||||
field2863 = -1446933277;
|
||||
|
||||
array[378529589 * tc.field2863] = 1;
|
||||
|
||||
int var = 32;
|
||||
|
||||
tc.field2863 = var * 1446933277;
|
||||
|
||||
array[378529589 * tc.field2863] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
public class SimpleModArithTest
|
||||
{
|
||||
static boolean isBig(int val)
|
||||
{
|
||||
if ((val & 0x80000000) != 0)
|
||||
{
|
||||
val = ~val + 1;
|
||||
}
|
||||
return (val & 0x7ff00000) != 0;
|
||||
}
|
||||
|
||||
private void checkConstants(ClassFile cf)
|
||||
{
|
||||
for (Method m : cf.getMethods())
|
||||
{
|
||||
Code code = m.getCode();
|
||||
Instructions instructions = code.getInstructions();
|
||||
for (Instruction i : instructions.getInstructions())
|
||||
{
|
||||
if (i instanceof LDC)
|
||||
{
|
||||
LDC ldc = (LDC) i;
|
||||
Integer value = (Integer) ldc.getConstantAsInt();
|
||||
assertFalse(isBig(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws IOException
|
||||
{
|
||||
InputStream in = this.getClass().getClassLoader().getResourceAsStream("net/runelite/deob/deobfuscators/arithmetic/TestClass.class");
|
||||
Assert.assertNotNull(in);
|
||||
|
||||
ClassGroup group = new ClassGroup();
|
||||
|
||||
ClassFile cf = ClassUtil.loadClass(in);
|
||||
group.addClass(cf);
|
||||
|
||||
ModArith d1 = new ModArith();
|
||||
d1.run(group);
|
||||
d1.runOnce();
|
||||
|
||||
Deobfuscator d2 = new MultiplicationDeobfuscator();
|
||||
d2.run(group);
|
||||
|
||||
this.checkConstants(cf);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2() throws IOException
|
||||
{
|
||||
InputStream in = this.getClass().getClassLoader().getResourceAsStream("net/runelite/deob/deobfuscators/arithmetic/TestClass2.class");
|
||||
Assert.assertNotNull(in);
|
||||
|
||||
ClassGroup group = new ClassGroup();
|
||||
|
||||
ClassFile cf = ClassUtil.loadClass(in);
|
||||
group.addClass(cf);
|
||||
|
||||
ModArith d1 = new ModArith();
|
||||
d1.run(group);
|
||||
d1.runOnce();
|
||||
|
||||
Deobfuscator d2 = new MultiplicationDeobfuscator();
|
||||
d2.run(group);
|
||||
|
||||
Encryption e = d1.getEncryption();
|
||||
|
||||
Pair pair = e.getField(cf.findField("field2863").getPoolField());
|
||||
|
||||
Assert.assertEquals(378529589, (int) pair.getter);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators.cfg;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
public class ControlFlowDeobfuscatorTest
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(new File(properties.getVanillaClient()));
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group, folder.newFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testRun() throws Exception
|
||||
{
|
||||
new ControlFlowDeobfuscator().run(group);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators.constparam;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
public class ConstantParameterTest
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(new File(properties.getVanillaClient()));
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group, folder.newFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testRun()
|
||||
{
|
||||
ConstantParameter cp = new ConstantParameter();
|
||||
cp.run(group);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,391 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators.exprargorder;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.attributes.Code;
|
||||
import net.runelite.asm.attributes.code.Instruction;
|
||||
import static net.runelite.asm.attributes.code.InstructionType.IADD;
|
||||
import static net.runelite.asm.attributes.code.InstructionType.IAND;
|
||||
import static net.runelite.asm.attributes.code.InstructionType.IF_ICMPEQ;
|
||||
import static net.runelite.asm.attributes.code.InstructionType.ILOAD;
|
||||
import static net.runelite.asm.attributes.code.InstructionType.LDC;
|
||||
import static net.runelite.asm.attributes.code.InstructionType.SIPUSH;
|
||||
import net.runelite.asm.attributes.code.Instructions;
|
||||
import net.runelite.asm.attributes.code.Label;
|
||||
import net.runelite.asm.attributes.code.instructions.IAdd;
|
||||
import net.runelite.asm.attributes.code.instructions.IAnd;
|
||||
import net.runelite.asm.attributes.code.instructions.ILoad;
|
||||
import net.runelite.asm.attributes.code.instructions.IMul;
|
||||
import net.runelite.asm.attributes.code.instructions.IStore;
|
||||
import net.runelite.asm.attributes.code.instructions.IfICmpEq;
|
||||
import net.runelite.asm.attributes.code.instructions.LDC;
|
||||
import net.runelite.asm.attributes.code.instructions.Pop;
|
||||
import net.runelite.asm.attributes.code.instructions.SiPush;
|
||||
import net.runelite.asm.attributes.code.instructions.VReturn;
|
||||
import net.runelite.deob.ClassGroupFactory;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ExprArgOrderTest
|
||||
{
|
||||
@Test
|
||||
public void test()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(2);
|
||||
|
||||
// vars[0] = 3
|
||||
Instruction[] prepareVariables =
|
||||
{
|
||||
new LDC(ins, 3),
|
||||
new IStore(ins, 0)
|
||||
};
|
||||
|
||||
for (Instruction i : prepareVariables)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
Instruction body[] =
|
||||
{
|
||||
// 3 + var0 -> var0 + 3
|
||||
new LDC(ins, 3), // 2
|
||||
new ILoad(ins, 0),
|
||||
new IAdd(ins),
|
||||
new Pop(ins),
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
ExprArgOrder exprArgOrder = new ExprArgOrder();
|
||||
exprArgOrder.run(group);
|
||||
|
||||
List<Instruction> instructions = ins.getInstructions();
|
||||
|
||||
assertEquals(ILOAD, instructions.get(2).getType());
|
||||
assertEquals(LDC, instructions.get(3).getType());
|
||||
assertEquals(IADD, instructions.get(4).getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(2);
|
||||
|
||||
// vars[0] = 3
|
||||
Instruction[] prepareVariables =
|
||||
{
|
||||
new LDC(ins, 3),
|
||||
new IStore(ins, 0)
|
||||
};
|
||||
|
||||
for (Instruction i : prepareVariables)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
Instruction body[] =
|
||||
{
|
||||
// var0 + 3 -> var0 + 3
|
||||
new ILoad(ins, 0), // 2
|
||||
new LDC(ins, 3),
|
||||
new IAdd(ins),
|
||||
new Pop(ins),
|
||||
// (3 + var0) + 512 -> (var0 + 3) + 512
|
||||
new LDC(ins, 3), // 6
|
||||
new ILoad(ins, 0),
|
||||
new IAdd(ins),
|
||||
new SiPush(ins, (short) 512),
|
||||
new IAdd(ins),
|
||||
new Pop(ins),
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
ExprArgOrder exprArgOrder = new ExprArgOrder();
|
||||
exprArgOrder.run(group);
|
||||
|
||||
List<Instruction> instructions = ins.getInstructions();
|
||||
|
||||
// ensure this stays the same
|
||||
assertEquals(ILOAD, instructions.get(2).getType());
|
||||
assertEquals(LDC, instructions.get(3).getType());
|
||||
assertEquals(IADD, instructions.get(4).getType());
|
||||
|
||||
//
|
||||
assertEquals(ILOAD, instructions.get(6).getType());
|
||||
assertEquals(SIPUSH, instructions.get(7).getType());
|
||||
assertEquals(IADD, instructions.get(8).getType());
|
||||
assertEquals(LDC, instructions.get(9).getType());
|
||||
assertEquals(IADD, instructions.get(10).getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test3()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(2);
|
||||
|
||||
// vars[0] = 3
|
||||
Instruction[] prepareVariables =
|
||||
{
|
||||
new LDC(ins, 3),
|
||||
new IStore(ins, 0)
|
||||
};
|
||||
|
||||
for (Instruction i : prepareVariables)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
Instruction body[] =
|
||||
{
|
||||
// 512 + (3 + var1) -> var1 + 3 + 512
|
||||
new LDC(ins, 512),
|
||||
new LDC(ins, 3),
|
||||
new ILoad(ins, 0),
|
||||
new IAdd(ins),
|
||||
new IAdd(ins),
|
||||
new Pop(ins),
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
ExprArgOrder exprArgOrder = new ExprArgOrder();
|
||||
exprArgOrder.run(group);
|
||||
|
||||
List<Instruction> instructions = ins.getInstructions();
|
||||
|
||||
// 2: iload
|
||||
// 3: iconst 3
|
||||
// 4: iadd
|
||||
// 5: ldc
|
||||
// 6: add
|
||||
assertEquals(IADD, instructions.get(4).getType());
|
||||
assertEquals(IADD, instructions.get(6).getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test4()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(2);
|
||||
|
||||
// vars[0] = 3
|
||||
Instruction[] prepareVariables =
|
||||
{
|
||||
new LDC(ins, 3),
|
||||
new IStore(ins, 0)
|
||||
};
|
||||
|
||||
for (Instruction i : prepareVariables)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
Instruction body[] =
|
||||
{
|
||||
new SiPush(ins, (short) 600),
|
||||
new ILoad(ins, 0),
|
||||
new LDC(ins, 3),
|
||||
new IMul(ins),
|
||||
new IAdd(ins),
|
||||
new Pop(ins),
|
||||
new ILoad(ins, 0),
|
||||
new LDC(ins, 3),
|
||||
new IMul(ins),
|
||||
new SiPush(ins, (short) 600),
|
||||
new IAdd(ins),
|
||||
new Pop(ins),
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
ExprArgOrder exprArgOrder = new ExprArgOrder();
|
||||
exprArgOrder.run(group);
|
||||
|
||||
List<Instruction> instructions = ins.getInstructions();
|
||||
|
||||
for (int i = 2; i <= 7; ++i)
|
||||
{
|
||||
assertEquals(instructions.get(i).getType(), instructions.get(i + 6).getType());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test5()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(2);
|
||||
|
||||
// vars[0] = 3
|
||||
Instruction[] prepareVariables =
|
||||
{
|
||||
new LDC(ins, 3),
|
||||
new IStore(ins, 0)
|
||||
};
|
||||
|
||||
for (Instruction i : prepareVariables)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
Label label = new Label(ins);
|
||||
|
||||
Instruction body[] =
|
||||
{
|
||||
// if (0 == 3 + var0) -> if (var0 + 3 == 0)
|
||||
new LDC(ins, 0),
|
||||
new LDC(ins, 3),
|
||||
new ILoad(ins, 0),
|
||||
new IAdd(ins),
|
||||
new IfICmpEq(ins, label),
|
||||
label,
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
ExprArgOrder exprArgOrder = new ExprArgOrder();
|
||||
exprArgOrder.run(group);
|
||||
|
||||
List<Instruction> instructions = ins.getInstructions();
|
||||
|
||||
// ldc iload add -> iload ldc iadd
|
||||
assertEquals(ILOAD, instructions.get(2).getType());
|
||||
assertEquals(LDC, instructions.get(3).getType());
|
||||
assertEquals(IADD, instructions.get(4).getType());
|
||||
|
||||
// idc moves from 2 to 5
|
||||
assertEquals(LDC, instructions.get(5).getType());
|
||||
assertEquals(IF_ICMPEQ, instructions.get(6).getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test6()
|
||||
{
|
||||
ClassGroup group = ClassGroupFactory.generateGroup();
|
||||
Code code = group.findClass("test").findMethod("func").getCode();
|
||||
Instructions ins = code.getInstructions();
|
||||
|
||||
code.setMaxStack(2);
|
||||
|
||||
// vars[0] = 3
|
||||
Instruction[] prepareVariables =
|
||||
{
|
||||
new LDC(ins, 3),
|
||||
new IStore(ins, 0)
|
||||
};
|
||||
|
||||
for (Instruction i : prepareVariables)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
Label label = new Label(ins);
|
||||
|
||||
/*
|
||||
iconst_0
|
||||
ldc 8388608
|
||||
iload_3
|
||||
iadd
|
||||
ldc -16777216
|
||||
iand
|
||||
if_icmpeq LABEL0x49
|
||||
*/
|
||||
Instruction body[] =
|
||||
{
|
||||
new LDC(ins, 0),
|
||||
new LDC(ins, 8388608),
|
||||
new ILoad(ins, 0),
|
||||
new IAdd(ins),
|
||||
new LDC(ins, -16777216),
|
||||
new IAnd(ins),
|
||||
new IfICmpEq(ins, label), // 8
|
||||
label,
|
||||
new VReturn(ins)
|
||||
};
|
||||
|
||||
for (Instruction i : body)
|
||||
{
|
||||
ins.addInstruction(i);
|
||||
}
|
||||
|
||||
ExprArgOrder exprArgOrder = new ExprArgOrder();
|
||||
exprArgOrder.run(group);
|
||||
|
||||
List<Instruction> instructions = ins.getInstructions();
|
||||
|
||||
assertEquals(ILOAD, instructions.get(2).getType());
|
||||
assertEquals(LDC, instructions.get(3).getType());
|
||||
assertEquals(IADD, instructions.get(4).getType());
|
||||
|
||||
assertEquals(LDC, instructions.get(5).getType());
|
||||
assertEquals(IAND, instructions.get(6).getType());
|
||||
|
||||
assertEquals(LDC, instructions.get(7).getType());
|
||||
assertEquals(IF_ICMPEQ, instructions.get(8).getType());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,315 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators.mapping;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.Field;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
import net.runelite.deob.DeobAnnotations;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
public class MappingDumper
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Test
|
||||
public void dump() throws IOException
|
||||
{
|
||||
ClassGroup group = JarUtil.loadJar(new File(properties.getRsClient()));
|
||||
|
||||
final String GAP = "%-40s";
|
||||
int classes = 0, methods = 0, fields = 0;
|
||||
|
||||
StringBuilder mBuilder = new StringBuilder();
|
||||
StringBuilder sBuilder = new StringBuilder();
|
||||
StringBuilder tmp;
|
||||
|
||||
for (ClassFile cf : group.getClasses())
|
||||
{
|
||||
String implName = DeobAnnotations.getImplements(cf);
|
||||
String className = DeobAnnotations.getObfuscatedName(cf.getAnnotations());
|
||||
|
||||
if (implName != null)
|
||||
{
|
||||
mBuilder.append("\n").append(implName).append(" -> ").append(className).append("\n");
|
||||
++classes;
|
||||
}
|
||||
|
||||
for (Field f : cf.getFields())
|
||||
{
|
||||
String exportName = DeobAnnotations.getExportedName(f.getAnnotations());
|
||||
|
||||
if (exportName == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
++fields;
|
||||
|
||||
String fieldName = DeobAnnotations.getObfuscatedName(f.getAnnotations());
|
||||
Type type = f.getType();
|
||||
Number getter = DeobAnnotations.getObfuscatedGetter(f);
|
||||
|
||||
String fieldType = typeToString(type);
|
||||
|
||||
if (f.isStatic())
|
||||
{
|
||||
tmp = sBuilder;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
tmp = mBuilder;
|
||||
}
|
||||
|
||||
tmp.append("\t").append(String.format(GAP, fieldType)).append(String.format(GAP, exportName))
|
||||
.append(className).append(".").append(fieldName);
|
||||
|
||||
if (getter != null)
|
||||
{
|
||||
tmp.append(" * ").append(getter).append("\n");
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
tmp.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
for (Method m : cf.getMethods())
|
||||
{
|
||||
String exportName = DeobAnnotations.getExportedName(m.getAnnotations());
|
||||
|
||||
if (exportName == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
methods++;
|
||||
|
||||
String methodName = DeobAnnotations.getObfuscatedName(m.getAnnotations());
|
||||
Signature signature = DeobAnnotations.getObfuscatedSignature(m);
|
||||
String garbageValue = DeobAnnotations.getObfuscatedValue(m);
|
||||
|
||||
if (signature == null)
|
||||
{
|
||||
signature = m.getDescriptor();
|
||||
}
|
||||
|
||||
String returnType = typeToString(m.getDescriptor().getReturnValue());
|
||||
String[] paramTypes = new String[signature.size()];
|
||||
for (int i = 0; i < paramTypes.length; i++)
|
||||
{
|
||||
paramTypes[i] = typeToString(signature.getTypeOfArg(i));
|
||||
}
|
||||
|
||||
if (m.isStatic())
|
||||
{
|
||||
tmp = sBuilder;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
tmp = mBuilder;
|
||||
}
|
||||
|
||||
tmp.append("\t").append(String.format(GAP, returnType)).append(String.format(GAP, exportName))
|
||||
.append(className).append(".").append(methodName);
|
||||
|
||||
tmp.append("(");
|
||||
for (int i = 0; i < paramTypes.length; i++)
|
||||
{
|
||||
tmp.append(paramTypes[i]);
|
||||
|
||||
if (i == paramTypes.length - 1)
|
||||
{
|
||||
if (garbageValue != null)
|
||||
{
|
||||
tmp.append(" = ").append(garbageValue);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
tmp.append(", ");
|
||||
}
|
||||
}
|
||||
tmp.append(")\n");
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("RuneLite http://github.com/runelite");
|
||||
System.out.println("Run " + Instant.now());
|
||||
System.out.println("Classes: " + classes + ", methods: " + methods + ", fields: " + fields);
|
||||
System.out.println("Gamepack " + properties.getRsVersion());
|
||||
System.out.println(mBuilder.toString());
|
||||
System.out.println("Static ->");
|
||||
System.out.println(sBuilder.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dumpJson() throws IOException
|
||||
{
|
||||
ClassGroup group = JarUtil.loadJar(new File(properties.getRsClient()));
|
||||
|
||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
JsonObject jObject = new JsonObject();
|
||||
JsonArray jFields = new JsonArray();
|
||||
JsonArray jMethods = new JsonArray();
|
||||
|
||||
for (ClassFile cf : group.getClasses())
|
||||
{
|
||||
String implName = DeobAnnotations.getImplements(cf);
|
||||
String className = DeobAnnotations.getObfuscatedName(cf.getAnnotations());
|
||||
|
||||
for (Field f : cf.getFields())
|
||||
{
|
||||
String exportName = DeobAnnotations.getExportedName(f.getAnnotations());
|
||||
|
||||
if (exportName == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
String fieldName = DeobAnnotations.getObfuscatedName(f.getAnnotations());
|
||||
Type obfType = DeobAnnotations.getObfuscatedType(f);
|
||||
Number getter = DeobAnnotations.getObfuscatedGetter(f);
|
||||
|
||||
JsonObject jField = new JsonObject();
|
||||
|
||||
jField.addProperty("name", exportName);
|
||||
jField.addProperty("owner", f.isStatic() ? "" : implName);
|
||||
jField.addProperty("class", className);
|
||||
jField.addProperty("field", fieldName);
|
||||
jField.addProperty("obfSignature", (obfType != null ? obfType.toString() : ""));
|
||||
jField.addProperty("signature", f.getType().toString());
|
||||
jField.addProperty("multiplier", (getter != null ? getter : 0));
|
||||
jField.addProperty("static", f.isStatic());
|
||||
|
||||
jFields.add(jField);
|
||||
}
|
||||
|
||||
for (Method m : cf.getMethods())
|
||||
{
|
||||
|
||||
String exportName = DeobAnnotations.getExportedName(m.getAnnotations());
|
||||
|
||||
if (exportName == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
String methodName = DeobAnnotations.getObfuscatedName(m.getAnnotations());
|
||||
Signature obfSignature = DeobAnnotations.getObfuscatedSignature(m);
|
||||
String predicate = DeobAnnotations.getObfuscatedValue(m);
|
||||
|
||||
JsonObject jMethod = new JsonObject();
|
||||
|
||||
jMethod.addProperty("name", exportName);
|
||||
jMethod.addProperty("owner", m.isStatic() ? "" : implName);
|
||||
jMethod.addProperty("class", className);
|
||||
jMethod.addProperty("field", methodName);
|
||||
jMethod.addProperty("obfSignature", (obfSignature != null ? obfSignature.toString() : ""));
|
||||
jMethod.addProperty("signature", m.getDescriptor().toString());
|
||||
jMethod.addProperty("predicate", (predicate != null ? predicate : ""));
|
||||
jMethod.addProperty("static", m.isStatic());
|
||||
|
||||
jMethods.add(jMethod);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
jObject.addProperty("runelite", "http://github.com/runelite");
|
||||
jObject.addProperty("run", Instant.now().toString());
|
||||
jObject.addProperty("gamepack", properties.getRsVersion());
|
||||
jObject.add("fields", jFields);
|
||||
jObject.add("methods", jMethods);
|
||||
|
||||
System.out.println(gson.toJson(jObject));
|
||||
}
|
||||
|
||||
private static String typeToString(Type type)
|
||||
{
|
||||
String subType;
|
||||
switch (type.toString())
|
||||
{
|
||||
case "B":
|
||||
subType = byte.class.getCanonicalName();
|
||||
break;
|
||||
case "C":
|
||||
subType = char.class.getCanonicalName();
|
||||
break;
|
||||
case "I":
|
||||
subType = int.class.getCanonicalName();
|
||||
break;
|
||||
case "S":
|
||||
subType = short.class.getCanonicalName();
|
||||
break;
|
||||
case "Z":
|
||||
subType = boolean.class.getCanonicalName();
|
||||
break;
|
||||
case "D":
|
||||
subType = double.class.getCanonicalName();
|
||||
break;
|
||||
case "F":
|
||||
subType = float.class.getCanonicalName();
|
||||
break;
|
||||
case "J":
|
||||
subType = long.class.getCanonicalName();
|
||||
break;
|
||||
case "V":
|
||||
subType = void.class.getCanonicalName();
|
||||
break;
|
||||
default:
|
||||
subType = type.getInternalName();
|
||||
break;
|
||||
}
|
||||
|
||||
if (type.isArray())
|
||||
{
|
||||
for (int i = 0; i < type.getDimensions(); ++i)
|
||||
{
|
||||
subType += "[]";
|
||||
}
|
||||
}
|
||||
|
||||
return subType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators.menuaction;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
public class MenuActionDeobfuscatorTest
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(new File(properties.getRsClient()));
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group, folder.newFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testRun()
|
||||
{
|
||||
new MenuActionDeobfuscator().run(group);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators.packethandler;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
public class PacketTypeFinderTest
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(new File(properties.getRsClient()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testRun() throws IOException
|
||||
{
|
||||
PacketTypeFinder bf = new PacketTypeFinder(group);
|
||||
bf.find();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators.packetwrite;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
public class PacketWriteDeobfuscatorTest
|
||||
{
|
||||
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(new File(properties.getRsClient()));
|
||||
group.removeClass(group.findClass("net/runelite/rs/Reflection"));
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group, folder.newFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testRun() throws IOException
|
||||
{
|
||||
PacketWriteDeobfuscator pw = new PacketWriteDeobfuscator();
|
||||
pw.run(group);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.deob.deobfuscators.transformers;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ClientErrorTransformerTest
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(ClientErrorTransformerTest.class);
|
||||
|
||||
private static final File GAMEPACK = new File("C:\\Users\\Adam\\.m2\\repository\\net\\runelite\\rs\\rs-client\\127.2-SNAPSHOT\\rs-client-127.2-SNAPSHOT.jar");
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(GAMEPACK);
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
File out = folder.newFile();
|
||||
|
||||
JarUtil.saveJar(group, out);
|
||||
|
||||
logger.info("Wrote to {}", out);
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void testRun()
|
||||
{
|
||||
ClientErrorTransformer e = new ClientErrorTransformer();
|
||||
e.transform(group);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators.transformers.buffer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
public class BufferFinderTest
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(new File(properties.getRsClient()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testRun() throws IOException
|
||||
{
|
||||
BufferFinder bf = new BufferFinder(group);
|
||||
bf.find();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators.transformers.buffer;
|
||||
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adam
|
||||
*/
|
||||
public class RuneliteBufferTest
|
||||
{
|
||||
@Test
|
||||
public void testRuneliteFinishPacket()
|
||||
{
|
||||
RuneliteBuffer buffer = new RuneliteBuffer();
|
||||
byte[] b = new byte[7];
|
||||
|
||||
buffer.setPayload(b);
|
||||
buffer.runeliteWriteByte((byte) 0);
|
||||
buffer.runeliteInitPacket();
|
||||
buffer.runeliteWriteInt(42);
|
||||
assertEquals(0, b[2]); // non finished lenghts are 0 initialized
|
||||
buffer.runeliteFinishPacket();
|
||||
|
||||
assertEquals(7, b.length);
|
||||
assertEquals(0, b[0]);
|
||||
|
||||
assertEquals(0, b[1]);
|
||||
assertEquals(4, b[2]);
|
||||
|
||||
assertEquals(0, b[3]);
|
||||
assertEquals(0, b[4]);
|
||||
assertEquals(0, b[5]);
|
||||
assertEquals(42, b[6]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators.unreachedcode;
|
||||
|
||||
public class UnreachableTest
|
||||
{
|
||||
public UnreachableTest()
|
||||
{
|
||||
}
|
||||
|
||||
public void entry()
|
||||
{
|
||||
try
|
||||
{
|
||||
System.out.println("used");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.out.println("should be hit");
|
||||
}
|
||||
}
|
||||
|
||||
public void method1Unused()
|
||||
{
|
||||
try
|
||||
{
|
||||
System.out.println("unused");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.out.println("oh no, an exception");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators.unusedclass;
|
||||
|
||||
public class ClassA implements EmptyInterface
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
System.out.append("code!");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators.unusedclass;
|
||||
|
||||
public class EmptyClass
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.deobfuscators.unusedclass;
|
||||
|
||||
public interface EmptyInterface
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.injection;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
|
||||
public class TestingClassLoader extends ClassLoader
|
||||
{
|
||||
private ClassGroup group;
|
||||
private Map<String, Class<?>> classes = new HashMap<>();
|
||||
|
||||
public TestingClassLoader(ClassGroup group)
|
||||
{
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> findClass(String name) throws ClassNotFoundException
|
||||
{
|
||||
ClassFile cf = group.findClass(name);
|
||||
if (cf == null)
|
||||
{
|
||||
return super.findClass(name);
|
||||
}
|
||||
|
||||
Class<?> c = classes.get(name);
|
||||
if (c != null)
|
||||
{
|
||||
return c;
|
||||
}
|
||||
|
||||
byte[] clazz = JarUtil.writeClass(group, cf);
|
||||
return defineClass(name, clazz);
|
||||
}
|
||||
|
||||
private Class<?> defineClass(String name, byte[] b)
|
||||
{
|
||||
Class<?> c = super.defineClass(name.replace('/', '.'), b, 0, b.length);
|
||||
classes.put(name, c);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.updater;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
public class AnnotationCopierTest
|
||||
{
|
||||
private static final Type EXPORT = new Type("Lnet/runelite/mapping/Export;");
|
||||
private static final Type IMPLEMENTS = new Type("Lnet/runelite/mapping/Implements;");
|
||||
private static final Type REPLACE = new Type("Lnet/runelite/mapping/Replace;");
|
||||
|
||||
private static final String JAR1 = "C:\\Users\\Adam\\.m2\\repository\\net\\runelite\\rs\\rs-client\\116.2-SNAPSHOT\\in.jar",
|
||||
JAR2 = "d:/rs/07/gamepack_116_deobfuscated.jar",
|
||||
OUT = "d:/rs/07/adamout.jar";
|
||||
|
||||
private ClassGroup group1, group2;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group1 = JarUtil.loadJar(new File(JAR1));
|
||||
group2 = JarUtil.loadJar(new File(JAR2));
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group2, new File(OUT));
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void testCopy()
|
||||
{
|
||||
AnnotationCopier ac = new AnnotationCopier(group1, group2, EXPORT, IMPLEMENTS, REPLACE);
|
||||
ac.copy();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.deob.updater;
|
||||
|
||||
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.Test;
|
||||
|
||||
public class AnnotationRenamerTest
|
||||
{
|
||||
private static final String JAR = "C:\\Users\\Adam\\.m2\\repository\\net\\runelite\\rs\\rs-client\\120.2-SNAPSHOT\\rs-client-120.2-SNAPSHOT.jar",
|
||||
OUT = "d:/rs/07/adamout.jar";
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(new File(JAR));
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group, new File(OUT));
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void testRename()
|
||||
{
|
||||
AnnotationRenamer ar = new AnnotationRenamer(group);
|
||||
ar.run();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.deob.updater;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.Field;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.deob.DeobAnnotations;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.deobfuscators.mapping.AnnotationIntegrityChecker;
|
||||
import net.runelite.deob.deobfuscators.mapping.AnnotationMapper;
|
||||
import net.runelite.deob.deobfuscators.mapping.Mapper;
|
||||
import net.runelite.deob.deobfuscators.mapping.ParallelExecutorMapping;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class UpdateMappingsTest
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(UpdateMappingsTest.class);
|
||||
|
||||
private static final String JAR = "d:/rs/07/gamepack_139_deobfuscated.jar",
|
||||
OUT = "d:/rs/07/adamout.jar";
|
||||
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testManual() throws IOException
|
||||
{
|
||||
File client = new File(properties.getRsClient());
|
||||
|
||||
ClassGroup group1 = JarUtil.loadJar(client);
|
||||
ClassGroup group2 = JarUtil.loadJar(new File(JAR));
|
||||
|
||||
map(group1, group2);
|
||||
|
||||
JarUtil.saveJar(group2, new File(OUT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRun() throws IOException
|
||||
{
|
||||
File client = new File(properties.getRsClient());
|
||||
|
||||
ClassGroup group1 = JarUtil.loadJar(client);
|
||||
ClassGroup group2 = JarUtil.loadJar(client);
|
||||
|
||||
// Remove existing annotations
|
||||
unannotate(group2);
|
||||
|
||||
// Map the client against itself
|
||||
map(group1, group2);
|
||||
|
||||
check(group1, group2);
|
||||
}
|
||||
|
||||
private void unannotate(ClassGroup group)
|
||||
{
|
||||
for (ClassFile cf : group.getClasses())
|
||||
{
|
||||
cf.getAnnotations().clearAnnotations();
|
||||
|
||||
for (Field f : cf.getFields())
|
||||
{
|
||||
f.getAnnotations().clearAnnotations();
|
||||
}
|
||||
|
||||
for (Method m : cf.getMethods())
|
||||
{
|
||||
m.getAnnotations().clearAnnotations();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void check(ClassGroup group1, ClassGroup group2)
|
||||
{
|
||||
for (ClassFile cf : group1.getClasses())
|
||||
{
|
||||
ClassFile other = group2.findClass(cf.getName());
|
||||
|
||||
String implname = DeobAnnotations.getImplements(cf);
|
||||
String otherimplname = DeobAnnotations.getImplements(other);
|
||||
|
||||
Assert.assertEquals(implname, otherimplname);
|
||||
|
||||
for (Field f : cf.getFields())
|
||||
{
|
||||
Field otherf = other.findField(f.getName(), f.getType());
|
||||
|
||||
assert otherf != null : "unable to find " + f;
|
||||
|
||||
String name = DeobAnnotations.getExportedName(f.getAnnotations());
|
||||
String otherName = DeobAnnotations.getExportedName(otherf.getAnnotations());
|
||||
|
||||
Assert.assertEquals(name + " <-> " + otherName, name, otherName);
|
||||
}
|
||||
|
||||
for (Method m : cf.getMethods())
|
||||
{
|
||||
Method otherm = other.findMethod(m.getName(), m.getDescriptor());
|
||||
|
||||
assert otherm != null : "unable to find " + m;
|
||||
|
||||
String name = DeobAnnotations.getExportedName(m.getAnnotations());
|
||||
String otherName = DeobAnnotations.getExportedName(otherm.getAnnotations());
|
||||
|
||||
Assert.assertEquals(name + " <-> " + otherName, name, otherName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void map(ClassGroup group1, ClassGroup group2)
|
||||
{
|
||||
logger.info("Mapping group1 ({}) vs group2 ({})", desc(group1), desc(group2));
|
||||
|
||||
Mapper mapper = new Mapper(group1, group2);
|
||||
mapper.run();
|
||||
ParallelExecutorMapping mapping = mapper.getMapping();
|
||||
|
||||
summary(mapping, group1);
|
||||
|
||||
AnnotationMapper amapper = new AnnotationMapper(group1, group2, mapping);
|
||||
amapper.run();
|
||||
|
||||
AnnotationIntegrityChecker aic = new AnnotationIntegrityChecker(group1, group2, mapping);
|
||||
aic.run();
|
||||
|
||||
if (aic.getErrors() > 0)
|
||||
{
|
||||
Assert.fail("Errors in annotation integrity checker");
|
||||
}
|
||||
|
||||
AnnotationRenamer an = new AnnotationRenamer(group2);
|
||||
an.run();
|
||||
}
|
||||
|
||||
private static String desc(ClassGroup cg)
|
||||
{
|
||||
int methods = 0, fields = 0, classes = 0;
|
||||
for (ClassFile cf : cg.getClasses())
|
||||
{
|
||||
++classes;
|
||||
methods += cf.getMethods().size();
|
||||
fields += cf.getFields().size();
|
||||
}
|
||||
int total = methods + fields + classes;
|
||||
return "total: " + total + ", " + methods + " methods, " + fields + " fields, " + classes + " classes";
|
||||
}
|
||||
|
||||
public static void summary(ParallelExecutorMapping finalm, ClassGroup in)
|
||||
{
|
||||
int fields = 0, staticMethod = 0, method = 0, total = 0, classes = 0;
|
||||
for (Map.Entry<Object, Object> e : finalm.getMap().entrySet())
|
||||
{
|
||||
Object o = e.getKey();
|
||||
if (o instanceof Field)
|
||||
{
|
||||
++fields;
|
||||
|
||||
Field f = (Field) o;
|
||||
assert f.getClassFile().getGroup() == in;
|
||||
}
|
||||
else if (o instanceof Method)
|
||||
{
|
||||
Method m = (Method) o;
|
||||
assert m.getClassFile().getGroup() == in;
|
||||
|
||||
if (m.isStatic())
|
||||
{
|
||||
++staticMethod;
|
||||
}
|
||||
else
|
||||
{
|
||||
++method;
|
||||
}
|
||||
}
|
||||
else if (o instanceof ClassFile)
|
||||
{
|
||||
++classes;
|
||||
}
|
||||
|
||||
++total;
|
||||
}
|
||||
|
||||
logger.info("Total mapped: {}. {} fields, {} static methods, {} member methods, {} classes",
|
||||
total, fields, staticMethod, method, classes);
|
||||
}
|
||||
|
||||
}
|
||||
331
deobfuscator/src/test/java/net/runelite/osb/HookImporter.java
Normal file
331
deobfuscator/src/test/java/net/runelite/osb/HookImporter.java
Normal file
@@ -0,0 +1,331 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.osb;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Map;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.Field;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.Annotations;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.asm.attributes.annotation.Element;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import net.runelite.osb.inject.ClassHook;
|
||||
import net.runelite.osb.inject.FieldHook;
|
||||
import net.runelite.osb.inject.MethodHook;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
public class HookImporter
|
||||
{
|
||||
private static final File IN = new File("C:\\Users\\Adam\\.m2\\repository\\net\\runelite\\rs\\rs-client\\114.2-SNAPSHOT\\rs-client-114.2-SNAPSHOT.jar");
|
||||
private static final File OUT = new File("c:\\rs\\adamout.jar");
|
||||
|
||||
private static final Type OBFUSCATED_NAME = new Type("Lnet/runelite/mapping/ObfuscatedName;");
|
||||
private static final Type IMPLEMENTS = new Type("Lnet/runelite/mapping/Implements;");
|
||||
private static final Type EXPORT = new Type("Lnet/runelite/mapping/Export;");
|
||||
private static final Type OBFUSCATED_SIGNATURE = new Type("Lnet/runelite/mapping/ObfuscatedSignature;");
|
||||
|
||||
private Map<String, ClassHook> hooks;
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
InputStream is = HookImporter.class.getResourceAsStream("osbmappings-114.json");
|
||||
Assert.assertNotNull(is);
|
||||
|
||||
Gson gson = new Gson();
|
||||
java.lang.reflect.Type type = new TypeToken<Map<String, ClassHook>>()
|
||||
{
|
||||
}.getType();
|
||||
hooks = gson.fromJson(new InputStreamReader(is), type);
|
||||
|
||||
group = JarUtil.loadJar(IN);
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group, OUT);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void importHooks()
|
||||
{
|
||||
int classes = 0, fields = 0, methods = 0, callbacks = 0;
|
||||
|
||||
for (String deobfuscatedClassName : hooks.keySet())
|
||||
{
|
||||
ClassHook ch = hooks.get(deobfuscatedClassName);
|
||||
ClassFile cf = this.findClassWithObfuscatedName(ch.getClazz());
|
||||
|
||||
assert cf != null;
|
||||
|
||||
String implementsName = getAnnotation(cf.getAnnotations(), IMPLEMENTS);
|
||||
if (implementsName.isEmpty())
|
||||
{
|
||||
cf.getAnnotations().addAnnotation(IMPLEMENTS, "value", deobfuscatedClassName);
|
||||
++classes;
|
||||
}
|
||||
|
||||
for (String deobfuscatedFieldName : ch.getFields().keySet())
|
||||
{
|
||||
FieldHook fh = ch.getFields().get(deobfuscatedFieldName);
|
||||
|
||||
String[] s = fh.getField().split("\\.");
|
||||
Field f;
|
||||
|
||||
if (s.length == 2)
|
||||
{
|
||||
ClassFile cf2 = this.findClassWithObfuscatedName(s[0]);
|
||||
assert cf2 != null;
|
||||
|
||||
f = this.findFieldWithObfuscatedName(cf2, s[1]);
|
||||
}
|
||||
else if (s.length == 1)
|
||||
{
|
||||
f = this.findFieldWithObfuscatedName(cf, fh.getField());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
assert f != null;
|
||||
|
||||
String exportedName = getAnnotation(f.getAnnotations(), EXPORT);
|
||||
if (exportedName.isEmpty())
|
||||
{
|
||||
f.getAnnotations().addAnnotation(EXPORT, "value", deobfuscatedFieldName);
|
||||
++fields;
|
||||
}
|
||||
}
|
||||
|
||||
for (String deobfuscatedMethodName : ch.getMethods().keySet())
|
||||
{
|
||||
MethodHook mh = ch.getMethods().get(deobfuscatedMethodName);
|
||||
|
||||
String[] s = mh.getMethod().split("\\.");
|
||||
Method m;
|
||||
|
||||
if (s.length == 2)
|
||||
{
|
||||
ClassFile cf2 = this.findClassWithObfuscatedName(s[0]);
|
||||
assert cf2 != null;
|
||||
|
||||
m = this.findMethodWithObfuscatedName(cf2, s[1], mh.getClientDesc());
|
||||
}
|
||||
else if (s.length == 1)
|
||||
{
|
||||
m = this.findMethodWithObfuscatedName(cf, mh.getMethod(), mh.getClientDesc());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
assert m != null;
|
||||
|
||||
String exportedName = getAnnotation(m.getAnnotations(), EXPORT);
|
||||
if (exportedName.isEmpty())
|
||||
{
|
||||
m.getAnnotations().addAnnotation(EXPORT, "value", deobfuscatedMethodName);
|
||||
++methods;
|
||||
}
|
||||
}
|
||||
|
||||
for (String deobfuscatedMethodName : ch.getCallbacks().keySet())
|
||||
{
|
||||
MethodHook mh = ch.getCallbacks().get(deobfuscatedMethodName);
|
||||
|
||||
String[] s = mh.getMethod().split("\\.");
|
||||
Method m;
|
||||
|
||||
if (s.length == 2)
|
||||
{
|
||||
ClassFile cf2 = this.findClassWithObfuscatedName(s[0]);
|
||||
assert cf2 != null;
|
||||
|
||||
m = this.findMethodWithObfuscatedName(cf2, s[1], mh.getClientDesc());
|
||||
}
|
||||
else if (s.length == 1)
|
||||
{
|
||||
m = this.findMethodWithObfuscatedName(cf, mh.getMethod(), mh.getClientDesc());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
assert m != null;
|
||||
|
||||
String exportedName = getAnnotation(m.getAnnotations(), EXPORT);
|
||||
if (exportedName.isEmpty())
|
||||
{
|
||||
m.getAnnotations().addAnnotation(EXPORT, "value", deobfuscatedMethodName);
|
||||
++callbacks;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Imported " + classes + " classes, " + fields + " fields, " + methods + " methods, " + callbacks + " callbacks");
|
||||
}
|
||||
|
||||
private ClassFile findClassWithObfuscatedName(String name)
|
||||
{
|
||||
for (ClassFile c : group.getClasses())
|
||||
{
|
||||
if (c.getName().equals(name))
|
||||
{
|
||||
return c;
|
||||
}
|
||||
|
||||
Annotations an = c.getAnnotations();
|
||||
if (getAnnotation(an, OBFUSCATED_NAME).equals(name))
|
||||
{
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Field findFieldWithObfuscatedName(ClassFile c, String name)
|
||||
{
|
||||
for (Field f : c.getFields())
|
||||
{
|
||||
Annotations an = f.getAnnotations();
|
||||
if (getAnnotation(an, OBFUSCATED_NAME).equals(name))
|
||||
{
|
||||
return f;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Method findMethodWithObfuscatedName(ClassFile c, String name, String signature)
|
||||
{
|
||||
Signature sig = new Signature(signature);
|
||||
|
||||
for (Method m : c.getMethods())
|
||||
{
|
||||
Annotations an = m.getAnnotations();
|
||||
if (getAnnotation(an, OBFUSCATED_NAME).equals(name))
|
||||
{
|
||||
Signature methodSig = getObfuscatedMethodSignature(m);
|
||||
|
||||
if (methodSig.equals(sig))
|
||||
{
|
||||
return m;
|
||||
}
|
||||
else
|
||||
{
|
||||
methodSig.equals(sig);
|
||||
getObfuscatedMethodSignature(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getAnnotation(Annotations an, Type type)
|
||||
{
|
||||
if (an == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
for (Annotation a : an.getAnnotations())
|
||||
{
|
||||
if (a.getType().equals(type))
|
||||
{
|
||||
for (Element e : a.getElements())
|
||||
{
|
||||
String str = (String) e.getValue();
|
||||
return str;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
private Signature getObfuscatedMethodSignature(Method method)
|
||||
{
|
||||
String sig = getAnnotation(method.getAnnotations(), OBFUSCATED_SIGNATURE);
|
||||
if (sig.isEmpty() == false)
|
||||
{
|
||||
return toObSignature(new Signature(sig)); // if it is annoted, use that
|
||||
}
|
||||
else
|
||||
{
|
||||
return toObSignature(method.getDescriptor());
|
||||
}
|
||||
}
|
||||
|
||||
private Type toObType(Type t)
|
||||
{
|
||||
if (t.isPrimitive())
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
if (!t.getInternalName().startsWith("class") && !t.getInternalName().equals("client"))
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
ClassFile cf = group.findClass(t.getInternalName());
|
||||
assert cf != null;
|
||||
|
||||
Annotations an = cf.getAnnotations();
|
||||
String obfuscatedName = an.find(OBFUSCATED_NAME).getElement().getString();
|
||||
return Type.getType("L" + obfuscatedName + ";", t.getDimensions());
|
||||
}
|
||||
|
||||
private Signature toObSignature(Signature s)
|
||||
{
|
||||
Signature.Builder builder = new Signature.Builder()
|
||||
.setReturnType(toObType(s.getReturnValue()));
|
||||
for (Type t : s.getArguments())
|
||||
{
|
||||
builder.addArgument(toObType(t));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.osb.inject;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ClassHook
|
||||
{
|
||||
@SerializedName("class")
|
||||
private String clazz;
|
||||
private Map<String, FieldHook> fields = new HashMap<>();
|
||||
private Map<String, MethodHook> methods = new HashMap<>();
|
||||
private Map<String, MethodHook> callbacks = new HashMap<>();
|
||||
|
||||
public String getClazz()
|
||||
{
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public Map<String, FieldHook> getFields()
|
||||
{
|
||||
return fields;
|
||||
}
|
||||
|
||||
public Map<String, MethodHook> getMethods()
|
||||
{
|
||||
return methods;
|
||||
}
|
||||
|
||||
public Map<String, MethodHook> getCallbacks()
|
||||
{
|
||||
return callbacks;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.osb.inject;
|
||||
|
||||
public class FieldHook
|
||||
{
|
||||
private String field; // obfuscated name
|
||||
private Number multiplier;
|
||||
|
||||
public String getField()
|
||||
{
|
||||
return field;
|
||||
}
|
||||
|
||||
public Number getMultiplier()
|
||||
{
|
||||
return multiplier;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.osb.inject;
|
||||
|
||||
public class MethodHook
|
||||
{
|
||||
private String method; // ob method name
|
||||
private String desc; // deob desc
|
||||
private String clientDesc; // ob desc
|
||||
|
||||
public String getMethod()
|
||||
{
|
||||
return method;
|
||||
}
|
||||
|
||||
public String getDesc()
|
||||
{
|
||||
return desc;
|
||||
}
|
||||
|
||||
public String getClientDesc()
|
||||
{
|
||||
return clientDesc;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.runeloader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.runelite.runeloader.inject.GetterInjectInstruction;
|
||||
import net.runelite.runeloader.inject.InjectionModscript;
|
||||
import net.runelite.mapping.Export;
|
||||
import net.runelite.mapping.ObfuscatedName;
|
||||
import net.runelite.runeloader.inject.Injection;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
public class CheckExports
|
||||
{
|
||||
private static final File CLIENT = new File("/Users/adam/w/rs/07/rs-client-1.0-SNAPSHOT.jar");
|
||||
|
||||
private final List<Class> classes = new ArrayList<>();
|
||||
|
||||
@Before
|
||||
public void before() throws MalformedURLException, ClassNotFoundException
|
||||
{
|
||||
ClassLoader loader = new URLClassLoader(new URL[] { CLIENT.toURL() });
|
||||
|
||||
Class c = loader.loadClass("net.runelite.rs.client.client");
|
||||
classes.add(c);
|
||||
|
||||
for (int i = 0; i < 230; ++i)
|
||||
{
|
||||
try
|
||||
{
|
||||
c = loader.loadClass("net.runelite.rs.client.class" + i);
|
||||
classes.add(c);
|
||||
}
|
||||
catch (ClassNotFoundException ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Class<?> findClassWithObfuscatedName(String name)
|
||||
{
|
||||
for (Class c : classes)
|
||||
{
|
||||
if (c.getName().equals("net.runelite.rs.client.client") && name.equals("client"))
|
||||
return c;
|
||||
|
||||
ObfuscatedName oc = (ObfuscatedName) c.getDeclaredAnnotation(ObfuscatedName.class);
|
||||
if (oc == null)
|
||||
continue;
|
||||
|
||||
if (oc.value().equals(name))
|
||||
return c;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Field findFieldWithObfuscatedName(Class c, String name)
|
||||
{
|
||||
for (Field f : c.getDeclaredFields())
|
||||
{
|
||||
ObfuscatedName oc = (ObfuscatedName) f.getDeclaredAnnotation(ObfuscatedName.class);
|
||||
if (oc == null)
|
||||
continue;
|
||||
|
||||
if (oc.value().equals(name))
|
||||
return f;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isExported(Field f)
|
||||
{
|
||||
Export export = (Export) f.getDeclaredAnnotation(Export.class);
|
||||
return export != null;
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void checkMappings() throws IOException
|
||||
{
|
||||
InjectionModscript mod = Injection.load(MappingImporter.class.getResourceAsStream(MappingImporter.RL_INJECTION));
|
||||
|
||||
for (int i = 0; i < mod.getGetterInjects().size(); ++i)
|
||||
{
|
||||
GetterInjectInstruction gii = (GetterInjectInstruction) mod.getGetterInjects().get(i);
|
||||
|
||||
Class c = this.findClassWithObfuscatedName(gii.getGetterClassName());
|
||||
Assert.assertNotNull(c);
|
||||
|
||||
Field f = this.findFieldWithObfuscatedName(c, gii.getGetterFieldName());
|
||||
Assert.assertNotNull(f);
|
||||
|
||||
Assert.assertTrue(this.isExported(f));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.runeloader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.runelite.runeloader.inject.GetterInjectInstruction;
|
||||
import net.runelite.runeloader.inject.InjectionModscript;
|
||||
import net.runelite.mapping.Export;
|
||||
import net.runelite.mapping.ObfuscatedGetter;
|
||||
import net.runelite.mapping.ObfuscatedName;
|
||||
import net.runelite.runeloader.inject.Injection;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
public class CheckMappings
|
||||
{
|
||||
private static final File CLIENT = new File("d:/rs/07/adamout.jar");
|
||||
|
||||
private final List<Class> classes = new ArrayList<>();
|
||||
|
||||
@Before
|
||||
public void before() throws MalformedURLException, ClassNotFoundException
|
||||
{
|
||||
ClassLoader loader = new URLClassLoader(new URL[] { CLIENT.toURL() });
|
||||
|
||||
Class c = loader.loadClass("client");
|
||||
classes.add(c);
|
||||
|
||||
for (int i = 0; i < 230; ++i)
|
||||
{
|
||||
try
|
||||
{
|
||||
c = loader.loadClass("class" + i);
|
||||
classes.add(c);
|
||||
}
|
||||
catch (ClassNotFoundException ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Class<?> findClassWithObfuscatedName(String name)
|
||||
{
|
||||
for (Class c : classes)
|
||||
{
|
||||
if (c.getName().equals("net.runelite.rs.client.client") && name.equals("client"))
|
||||
return c;
|
||||
|
||||
ObfuscatedName oc = (ObfuscatedName) c.getDeclaredAnnotation(ObfuscatedName.class);
|
||||
if (oc == null)
|
||||
continue;
|
||||
|
||||
if (oc.value().equals(name))
|
||||
return c;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Field findFieldWithObfuscatedName(Class c, String name)
|
||||
{
|
||||
for (Field f : c.getDeclaredFields())
|
||||
{
|
||||
ObfuscatedName oc = (ObfuscatedName) f.getDeclaredAnnotation(ObfuscatedName.class);
|
||||
if (oc == null)
|
||||
continue;
|
||||
|
||||
if (oc.value().equals(name))
|
||||
return f;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Integer getIntegerMultiplier(Field f)
|
||||
{
|
||||
ObfuscatedGetter getter = (ObfuscatedGetter) f.getDeclaredAnnotation(ObfuscatedGetter.class);
|
||||
if (getter == null)
|
||||
return null;
|
||||
return getter.intValue() == 0 ? null : getter.intValue();
|
||||
}
|
||||
|
||||
private String getExportedName(Field f)
|
||||
{
|
||||
Export e = (Export) f.getDeclaredAnnotation(Export.class);
|
||||
if (e == null)
|
||||
return null;
|
||||
return e.value();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void checkMappings() throws IOException
|
||||
{
|
||||
InjectionModscript mod = Injection.load(MappingImporter.class.getResourceAsStream(MappingImporter.RL_INJECTION));
|
||||
|
||||
for (int i = 0; i < mod.getGetterInjects().size(); ++i)
|
||||
{
|
||||
GetterInjectInstruction gii = (GetterInjectInstruction) mod.getGetterInjects().get(i);
|
||||
|
||||
Class c = this.findClassWithObfuscatedName(gii.getGetterClassName());
|
||||
Assert.assertNotNull(c);
|
||||
|
||||
Field f = this.findFieldWithObfuscatedName(c, gii.getGetterFieldName());
|
||||
Assert.assertNotNull(f);
|
||||
|
||||
String exportedName = this.getExportedName(f);
|
||||
String attrName = gii.getGetterName();
|
||||
attrName = Utils.toExportedName(attrName);
|
||||
|
||||
Integer mul = gii.getMultiplier(),
|
||||
myMul = this.getIntegerMultiplier(f);
|
||||
|
||||
// XXX Check @Export etc names
|
||||
|
||||
//Assert.assertEquals(exportedName, attrName);
|
||||
Assert.assertEquals(myMul, mul);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.runeloader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.Field;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.Annotations;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.asm.attributes.annotation.Element;
|
||||
import net.runelite.runeloader.inject.AddInterfaceInstruction;
|
||||
import net.runelite.runeloader.inject.GetterInjectInstruction;
|
||||
import net.runelite.runeloader.inject.InjectionModscript;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import net.runelite.runeloader.inject.Injection;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class MappingImporter
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(MappingImporter.class);
|
||||
|
||||
private static final File IN = new File("d:/rs/07/adamin.jar");
|
||||
private static final File OUT = new File("d:/rs/07/adamout.jar");
|
||||
|
||||
public static final String RL_INJECTION = "injection_130.json";
|
||||
|
||||
private static final Type OBFUSCATED_NAME = new Type("Lnet/runelite/mapping/ObfuscatedName;");
|
||||
private static final Type EXPORT = new Type("Lnet/runelite/mapping/Export;");
|
||||
private static final Type IMPLEMENTS = new Type("Lnet/runelite/mapping/Implements;");
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(IN);
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(group, OUT);
|
||||
}
|
||||
|
||||
private boolean hasObfuscatedName(Annotations an, String name)
|
||||
{
|
||||
if (an == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (Annotation a : an.getAnnotations())
|
||||
{
|
||||
if (a.getType().equals(OBFUSCATED_NAME))
|
||||
{
|
||||
for (Element e : a.getElements())
|
||||
{
|
||||
String str = (String) e.getValue();
|
||||
if (str.equals(name))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private ClassFile findClassWithObfuscatedName(String name)
|
||||
{
|
||||
for (ClassFile c : group.getClasses())
|
||||
{
|
||||
if (c.getName().equals(name))
|
||||
{
|
||||
return c;
|
||||
}
|
||||
|
||||
Annotations an = c.getAnnotations();
|
||||
if (this.hasObfuscatedName(an, name))
|
||||
{
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Field findFieldWithObfuscatedName(ClassFile c, String name)
|
||||
{
|
||||
for (Field f : c.getFields())
|
||||
{
|
||||
Annotations an = f.getAnnotations();
|
||||
if (this.hasObfuscatedName(an, name))
|
||||
{
|
||||
return f;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void makeMappings() throws IOException
|
||||
{
|
||||
InjectionModscript mod = Injection.load(MappingImporter.class.getResourceAsStream(RL_INJECTION));
|
||||
int fields = 0, classes = 0;
|
||||
|
||||
for (int i = 0; i < mod.getGetterInjects().size(); ++i)
|
||||
{
|
||||
GetterInjectInstruction gii = (GetterInjectInstruction) mod.getGetterInjects().get(i);
|
||||
|
||||
ClassFile cf = this.findClassWithObfuscatedName(gii.getGetterClassName());
|
||||
Assert.assertNotNull(cf);
|
||||
|
||||
Field f = this.findFieldWithObfuscatedName(cf, gii.getGetterFieldName());
|
||||
if (f == null)
|
||||
{
|
||||
// some of their fields they inject getters for they also inject,
|
||||
// so they don't all exist
|
||||
continue;
|
||||
}
|
||||
|
||||
String attrName = gii.getGetterName();
|
||||
attrName = Utils.toExportedName(attrName);
|
||||
|
||||
Annotations an = f.getAnnotations();
|
||||
|
||||
Annotation a = an.find(EXPORT);
|
||||
if (a != null)
|
||||
{
|
||||
String exportedName = a.getElement().getString();
|
||||
|
||||
if (!attrName.equals(exportedName))
|
||||
{
|
||||
logger.info("Exported field " + f + " with mismatched name. Theirs: " + attrName + ", mine: " + exportedName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
an.addAnnotation(EXPORT, "value", attrName);
|
||||
|
||||
logger.info("Exporting field " + f + " with name " + attrName);
|
||||
++fields;
|
||||
}
|
||||
}
|
||||
|
||||
for (AddInterfaceInstruction aii : mod.getAddInterfaceInjects())
|
||||
{
|
||||
ClassFile cf = this.findClassWithObfuscatedName(aii.getClientClass());
|
||||
Assert.assertNotNull(cf);
|
||||
|
||||
String iface = aii.getInterfaceClass();
|
||||
|
||||
iface = iface.replace("com/runeloader/api/bridge/os/accessor/", "");
|
||||
|
||||
Annotations an = cf.getAnnotations();
|
||||
|
||||
Annotation a = an.find(IMPLEMENTS);
|
||||
if (a != null)
|
||||
{
|
||||
String implementsName = a.getElement().getString();
|
||||
|
||||
if (!iface.equals(implementsName))
|
||||
{
|
||||
logger.info("Implements class " + cf + " with mismatched name. Theirs: " + iface + ", mine: " + implementsName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
an.addAnnotation(IMPLEMENTS, "value", iface);
|
||||
|
||||
logger.info("Exporting class " + cf.getName() + " with name " + iface);
|
||||
++classes;
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("Added {} fields, {} classes", fields, classes);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.runeloader;
|
||||
|
||||
public class Utils
|
||||
{
|
||||
public static String toExportedName(String attrName)
|
||||
{
|
||||
if (attrName.startsWith("get"))
|
||||
{
|
||||
attrName = attrName.substring(3);
|
||||
attrName = Character.toLowerCase(attrName.charAt(0)) + attrName.substring(1);
|
||||
}
|
||||
|
||||
if (attrName.equalsIgnoreCase("fps"))
|
||||
attrName = "FPS";
|
||||
|
||||
return attrName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package net.runelite.runeloader.inject;
|
||||
|
||||
public class AddFieldInstruction
|
||||
{
|
||||
public String owner;
|
||||
public String name;
|
||||
public String desc;
|
||||
public int access;
|
||||
|
||||
public AddFieldInstruction(String var1, String var2, String var3, int var4)
|
||||
{
|
||||
this.owner = var1;
|
||||
this.name = var2;
|
||||
this.desc = var3;
|
||||
this.access = var4;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package net.runelite.runeloader.inject;
|
||||
|
||||
public class AddInterfaceInstruction
|
||||
{
|
||||
private final String clientClass;
|
||||
private final String interfaceClass;
|
||||
|
||||
public AddInterfaceInstruction(String var1, String var2)
|
||||
{
|
||||
this.clientClass = var1;
|
||||
this.interfaceClass = var2;
|
||||
}
|
||||
|
||||
public String getClientClass()
|
||||
{
|
||||
return this.clientClass;
|
||||
}
|
||||
|
||||
public String getInterfaceClass()
|
||||
{
|
||||
return this.interfaceClass;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package net.runelite.runeloader.inject;
|
||||
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
public class AddMethodInstruction
|
||||
{
|
||||
private final String clientClass;
|
||||
private final String methodName;
|
||||
private final String methodDesc;
|
||||
private final AbstractInsnNode[] instructions;
|
||||
|
||||
public AddMethodInstruction(String var1, String var2, String var3, AbstractInsnNode[] var4)
|
||||
{
|
||||
this.clientClass = var1;
|
||||
this.methodName = var2;
|
||||
this.methodDesc = var3;
|
||||
this.instructions = var4;
|
||||
}
|
||||
|
||||
public boolean valid(ClassNode var1)
|
||||
{
|
||||
return var1.name.equalsIgnoreCase(this.clientClass);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package net.runelite.runeloader.inject;
|
||||
|
||||
public class GetterInjectInstruction
|
||||
{
|
||||
private final String className;
|
||||
private final String getterMethodDesc;
|
||||
private final String getterName;
|
||||
private final String getterClassName;
|
||||
private final String getterFieldName;
|
||||
private final Integer multiplier;
|
||||
private final boolean staticField;
|
||||
|
||||
public GetterInjectInstruction(String var1, String var2, String var3, String var4, String var5, Integer var6, boolean var7)
|
||||
{
|
||||
this.className = var1;
|
||||
this.getterMethodDesc = "()" + var3;
|
||||
this.getterName = var2;
|
||||
this.getterClassName = var4;
|
||||
this.getterFieldName = var5;
|
||||
this.multiplier = var6;
|
||||
this.staticField = var7;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "GetterInjectInstruction{" + "className=" + className + ", getterMethodDesc=" + getterMethodDesc + ", getterName=" + getterName + ", getterClassName=" + getterClassName + ", getterFieldName=" + getterFieldName + ", multiplier=" + multiplier + ", staticField=" + staticField + '}';
|
||||
}
|
||||
|
||||
public String getClassName()
|
||||
{
|
||||
return this.className;
|
||||
}
|
||||
|
||||
public String getGetterMethodDesc()
|
||||
{
|
||||
return this.getterMethodDesc;
|
||||
}
|
||||
|
||||
public String getGetterName()
|
||||
{
|
||||
return this.getterName;
|
||||
}
|
||||
|
||||
public String getGetterClassName()
|
||||
{
|
||||
return this.getterClassName;
|
||||
}
|
||||
|
||||
public String getGetterFieldName()
|
||||
{
|
||||
return this.getterFieldName;
|
||||
}
|
||||
|
||||
public Integer getMultiplier()
|
||||
{
|
||||
return this.multiplier;
|
||||
}
|
||||
|
||||
public boolean isStaticField()
|
||||
{
|
||||
return this.staticField;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package net.runelite.runeloader.inject;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
|
||||
public class Injection
|
||||
{
|
||||
private static final Gson decoder = (new GsonBuilder()).registerTypeAdapter(AbstractInsnNode.class, new InstructionDeserializer()).create();
|
||||
|
||||
public InjectionModscript resource;
|
||||
|
||||
public static InjectionModscript load(InputStream in)
|
||||
{
|
||||
return decoder.fromJson(new InputStreamReader(in), Injection.class).resource;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package net.runelite.runeloader.inject;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class InjectionModscript
|
||||
{
|
||||
private int revision;
|
||||
private List<GetterInjectInstruction> getterInjects = new LinkedList<>();
|
||||
private List superChangeInjects = new LinkedList();
|
||||
private List<AddInterfaceInstruction> addInterfaceInjects = new LinkedList<>();
|
||||
private List methodMods = new LinkedList();
|
||||
private List addMethods = new LinkedList();
|
||||
private List instructionReplacements = new LinkedList();
|
||||
private List newMethodMods = new LinkedList();
|
||||
private List newFields = new LinkedList();
|
||||
|
||||
public int getRevision()
|
||||
{
|
||||
return revision;
|
||||
}
|
||||
|
||||
public List<GetterInjectInstruction> getGetterInjects()
|
||||
{
|
||||
return this.getterInjects;
|
||||
}
|
||||
|
||||
public List getSuperChangeInjects()
|
||||
{
|
||||
return this.superChangeInjects;
|
||||
}
|
||||
|
||||
public List<AddInterfaceInstruction> getAddInterfaceInjects()
|
||||
{
|
||||
return this.addInterfaceInjects;
|
||||
}
|
||||
|
||||
public List getMethodMods()
|
||||
{
|
||||
return this.methodMods;
|
||||
}
|
||||
|
||||
public List getAddMethods()
|
||||
{
|
||||
return this.addMethods;
|
||||
}
|
||||
|
||||
public List getNewMethodMods()
|
||||
{
|
||||
return this.newMethodMods;
|
||||
}
|
||||
|
||||
public List getInstructionReplacements()
|
||||
{
|
||||
return this.instructionReplacements;
|
||||
}
|
||||
|
||||
public List getNewFields()
|
||||
{
|
||||
return this.newFields;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package net.runelite.runeloader.inject;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import java.lang.reflect.Type;
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.FieldInsnNode;
|
||||
import org.objectweb.asm.tree.InsnNode;
|
||||
import org.objectweb.asm.tree.IntInsnNode;
|
||||
import org.objectweb.asm.tree.LdcInsnNode;
|
||||
import org.objectweb.asm.tree.MethodInsnNode;
|
||||
import org.objectweb.asm.tree.TypeInsnNode;
|
||||
import org.objectweb.asm.tree.VarInsnNode;
|
||||
|
||||
public class InstructionDeserializer implements JsonDeserializer
|
||||
{
|
||||
@Override
|
||||
public AbstractInsnNode deserialize(JsonElement var1, Type var2, JsonDeserializationContext var3)
|
||||
{
|
||||
JsonObject var4 = (JsonObject) var1;
|
||||
int var5 = var4.get("opcode").getAsInt();
|
||||
if (var5 != 21 && var5 != 25 && var5 != 58 && var5 != 54 && var5 != 22 && var5 != 55)
|
||||
{
|
||||
String var7;
|
||||
String var8;
|
||||
String var10;
|
||||
if (var5 != 184 && var5 != 182 && var5 != 183)
|
||||
{
|
||||
if (var5 == 18)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new LdcInsnNode(Integer.valueOf(var4.get("cst").getAsInt()));
|
||||
}
|
||||
catch (Exception var9)
|
||||
{
|
||||
return new LdcInsnNode(var4.get("cst").getAsString());
|
||||
}
|
||||
}
|
||||
else if (var5 != 187 && var5 != 189)
|
||||
{
|
||||
if (var5 != 16 && var5 != 17)
|
||||
{
|
||||
if (var5 != 179 && var5 != 178 && var5 != 180 && var5 != 181)
|
||||
{
|
||||
return new InsnNode(var5);
|
||||
}
|
||||
else
|
||||
{
|
||||
var10 = var4.get("owner").getAsString();
|
||||
var7 = var4.get("name").getAsString();
|
||||
var8 = var4.get("desc").getAsString();
|
||||
return new FieldInsnNode(var5, var10, var7, var8);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new IntInsnNode(var5, var4.get("operand").getAsInt());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return new TypeInsnNode(var5, var4.get("desc").getAsString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var10 = var4.get("owner").getAsString();
|
||||
var7 = var4.get("name").getAsString();
|
||||
var8 = var4.get("desc").getAsString();
|
||||
return new MethodInsnNode(var5, var10, var7, var8);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int var6 = var4.get("var").getAsInt();
|
||||
return new VarInsnNode(var5, var6);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package net.runelite.runeloader.inject;
|
||||
|
||||
import java.util.Iterator;
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.InsnList;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
public class MethodModInstruction {
|
||||
private final int startIndex;
|
||||
private final AbstractInsnNode[] nodes;
|
||||
public final String owner;
|
||||
public final String method;
|
||||
public final String desc;
|
||||
|
||||
public MethodModInstruction(int var1, AbstractInsnNode[] var2, String var3, String var4, String var5) {
|
||||
this.startIndex = var1;
|
||||
this.nodes = var2;
|
||||
this.owner = var3;
|
||||
this.method = var4;
|
||||
this.desc = var5;
|
||||
}
|
||||
|
||||
public boolean valid(ClassNode var1) {
|
||||
return var1.name.equalsIgnoreCase(this.owner);
|
||||
}
|
||||
|
||||
public void inject(ClassNode var1) {
|
||||
Iterator var3 = var1.methods.iterator();
|
||||
|
||||
while(true) {
|
||||
MethodNode var2;
|
||||
do {
|
||||
do {
|
||||
if(!var3.hasNext()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var2 = (MethodNode)var3.next();
|
||||
} while(!var2.name.equalsIgnoreCase(this.method));
|
||||
} while(!var2.desc.equalsIgnoreCase(this.desc));
|
||||
|
||||
InsnList var4 = var2.instructions;
|
||||
|
||||
try {
|
||||
AbstractInsnNode var5 = var4.get(this.startIndex);
|
||||
AbstractInsnNode var6 = null;
|
||||
|
||||
for(int var7 = 0; var7 < this.nodes.length; ++var7) {
|
||||
if(var6 == null) {
|
||||
var4.insertBefore(var5, this.nodes[var7]);
|
||||
} else {
|
||||
var4.insert(var6, this.nodes[var7]);
|
||||
}
|
||||
|
||||
var6 = this.nodes[var7];
|
||||
}
|
||||
} catch (Exception var8) {
|
||||
System.err.println("Failed on " + this.startIndex + " @ " + this.owner + "." + this.method + " " + this.desc);
|
||||
var8.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package net.runelite.runeloader.inject;
|
||||
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
|
||||
public class ReplaceNodeInstruction {
|
||||
public final String owner;
|
||||
public final String method;
|
||||
public final String desc;
|
||||
public final int index;
|
||||
public final AbstractInsnNode replaceWith;
|
||||
|
||||
public ReplaceNodeInstruction(String var1, String var2, String var3, int var4, AbstractInsnNode var5) {
|
||||
this.owner = var1;
|
||||
this.method = var2;
|
||||
this.desc = var3;
|
||||
this.index = var4;
|
||||
this.replaceWith = var5;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package net.runelite.runeloader.inject;
|
||||
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
public class SuperChangeInstruction
|
||||
{
|
||||
private final String clientName;
|
||||
private final String superName;
|
||||
|
||||
public SuperChangeInstruction(String var1, String var2)
|
||||
{
|
||||
this.clientName = var1;
|
||||
this.superName = var2;
|
||||
}
|
||||
|
||||
public String getClientName()
|
||||
{
|
||||
return this.clientName;
|
||||
}
|
||||
|
||||
public String getSuperName()
|
||||
{
|
||||
return this.superName;
|
||||
}
|
||||
|
||||
public boolean valid(ClassNode var1)
|
||||
{
|
||||
return var1.name.equalsIgnoreCase(this.clientName);
|
||||
}
|
||||
|
||||
public void inject(ClassNode var1)
|
||||
{
|
||||
var1.superName = this.superName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package net.runelite.runeloader.inject;
|
||||
|
||||
import org.objectweb.asm.Label;
|
||||
|
||||
public class TableJumpInstruction$TableJump
|
||||
{
|
||||
public Label label;
|
||||
public final int instructionIndex;
|
||||
public final int labelArrayIndex;
|
||||
public final int opcode;
|
||||
|
||||
public TableJumpInstruction$TableJump(int var1, int var2, int var3)
|
||||
{
|
||||
this.instructionIndex = var1;
|
||||
this.opcode = var3;
|
||||
this.labelArrayIndex = var2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package net.runelite.runeloader.inject;
|
||||
|
||||
import java.util.Iterator;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.InsnList;
|
||||
import org.objectweb.asm.tree.JumpInsnNode;
|
||||
import org.objectweb.asm.tree.LabelNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
public class TableJumpInstruction
|
||||
{
|
||||
private final TableJumpInstruction$TableJump[] tableJumps;
|
||||
private final int[] labels;
|
||||
private final int start;
|
||||
private final AbstractInsnNode[] instructions;
|
||||
private final String owner;
|
||||
private final String name;
|
||||
private final String desc;
|
||||
|
||||
public TableJumpInstruction(TableJumpInstruction$TableJump[] var1, AbstractInsnNode[] var2, int[] var3, int var4, String var5, String var6, String var7)
|
||||
{
|
||||
this.tableJumps = var1;
|
||||
this.instructions = var2;
|
||||
this.labels = var3;
|
||||
this.owner = var5;
|
||||
this.name = var6;
|
||||
this.desc = var7;
|
||||
this.start = var4;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package net.runelite.runesuite;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.util.List;
|
||||
|
||||
public class HookClass
|
||||
{
|
||||
@SerializedName("class")
|
||||
String clazz;
|
||||
String name;
|
||||
int access;
|
||||
List<HookField> fields;
|
||||
List<HookMethod> methods;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package net.runelite.runesuite;
|
||||
|
||||
public class HookField
|
||||
{
|
||||
String field;
|
||||
String owner;
|
||||
String name;
|
||||
int access;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "HookField{" + "field=" + field + ", owner=" + owner + ", name=" + name + '}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.runesuite;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.Field;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.Annotations;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.asm.attributes.annotation.Element;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
import net.runelite.asm.signature.util.VirtualMethods;
|
||||
import static net.runelite.deob.DeobAnnotations.EXPORT;
|
||||
import static net.runelite.deob.DeobAnnotations.IMPLEMENTS;
|
||||
import static net.runelite.deob.DeobAnnotations.OBFUSCATED_NAME;
|
||||
import static net.runelite.deob.DeobAnnotations.OBFUSCATED_SIGNATURE;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
import net.runelite.deob.deobfuscators.Renamer;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import net.runelite.deob.util.NameMappings;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class HookImporter
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(HookImporter.class);
|
||||
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
|
||||
private List<HookClass> hooks;
|
||||
private ClassGroup group;
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
group = JarUtil.loadJar(new File(properties.getRsClient()));
|
||||
|
||||
InputStream is = getClass().getResourceAsStream("hooks.json");
|
||||
Gson gson = new Gson();
|
||||
java.lang.reflect.Type type = new TypeToken<List<HookClass>>()
|
||||
{
|
||||
}.getType();
|
||||
hooks = gson.fromJson(new InputStreamReader(is), type);
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
File out = new File("C:/Users/Lucas/Desktop/client.jar");
|
||||
JarUtil.saveJar(group, out);
|
||||
logger.info("Wrote to {}", out);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importHooks()
|
||||
{
|
||||
int classes = 0, fields = 0, methods = 0, access = 0;
|
||||
NameMappings mappings = new NameMappings();
|
||||
|
||||
for (HookClass hc : hooks)
|
||||
{
|
||||
|
||||
ClassFile cf = findClassWithObfuscatedName(hc.name);
|
||||
|
||||
assert cf != null;
|
||||
|
||||
if (cf.getAccess() != hc.access)
|
||||
{
|
||||
cf.setAccess(hc.access);
|
||||
++access;
|
||||
}
|
||||
|
||||
String implementsName = getAnnotation(cf.getAnnotations(), IMPLEMENTS);
|
||||
if (implementsName.isEmpty())
|
||||
{
|
||||
String deobfuscatedClassName = hc.clazz;
|
||||
cf.getAnnotations().addAnnotation(IMPLEMENTS, "value", deobfuscatedClassName);
|
||||
mappings.map(cf.getPoolClass(), deobfuscatedClassName);
|
||||
++classes;
|
||||
}
|
||||
|
||||
for (HookField fh : hc.fields)
|
||||
{
|
||||
ClassFile cf2 = findClassWithObfuscatedName(fh.owner);
|
||||
assert cf2 != null;
|
||||
|
||||
Field f = findFieldWithObfuscatedName(cf2, fh.name);
|
||||
if (f == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (f.getAccessFlags() != fh.access)
|
||||
{
|
||||
f.setAccessFlags(fh.access);
|
||||
++access;
|
||||
}
|
||||
|
||||
String exportedName = getAnnotation(f.getAnnotations(), EXPORT);
|
||||
if (exportedName.isEmpty())
|
||||
{
|
||||
String deobfuscatedFieldName = fh.field;
|
||||
|
||||
Field other = cf2.findField(deobfuscatedFieldName);
|
||||
if (other != null)
|
||||
{
|
||||
logger.warn("Name collision for field {}", deobfuscatedFieldName);
|
||||
continue;
|
||||
}
|
||||
|
||||
f.getAnnotations().addAnnotation(EXPORT, "value", deobfuscatedFieldName);
|
||||
mappings.map(f.getPoolField(), deobfuscatedFieldName);
|
||||
++fields;
|
||||
}
|
||||
}
|
||||
|
||||
outer:
|
||||
for (HookMethod hm : hc.methods)
|
||||
{
|
||||
|
||||
ClassFile cf2 = findClassWithObfuscatedName(hm.owner);
|
||||
assert cf2 != null;
|
||||
|
||||
Method m = findMethodWithObfuscatedName(cf2, hm.name, hm.descriptor);
|
||||
if (m == null)
|
||||
{
|
||||
logger.warn(hm.toString() + " is missing");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m.getAccessFlags() != hm.access)
|
||||
{
|
||||
m.setAccessFlags(hm.access);
|
||||
++access;
|
||||
}
|
||||
|
||||
// maybe only the base class method is exported
|
||||
List<Method> virtualMethods = VirtualMethods.getVirtualMethods(m);
|
||||
for (Method method : virtualMethods)
|
||||
{
|
||||
String exportedName = getAnnotation(method.getAnnotations(), EXPORT);
|
||||
if (!exportedName.isEmpty())
|
||||
{
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
|
||||
String deobfuscatedMethodName = hm.method;
|
||||
m.getAnnotations().addAnnotation(EXPORT, "value", deobfuscatedMethodName);
|
||||
mappings.map(m.getPoolMethod(), deobfuscatedMethodName);
|
||||
++methods;
|
||||
}
|
||||
}
|
||||
|
||||
Renamer renamer = new Renamer(mappings);
|
||||
renamer.run(group);
|
||||
|
||||
logger.info("Imported {} classes, {} fields, {} methods, {} access levels", classes, fields, methods, access);
|
||||
}
|
||||
|
||||
private ClassFile findClassWithObfuscatedName(String name)
|
||||
{
|
||||
for (ClassFile c : group.getClasses())
|
||||
{
|
||||
if (c.getName().equals(name))
|
||||
{
|
||||
return c;
|
||||
}
|
||||
|
||||
Annotations an = c.getAnnotations();
|
||||
if (getAnnotation(an, OBFUSCATED_NAME).equals(name))
|
||||
{
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Field findFieldWithObfuscatedName(ClassFile c, String name)
|
||||
{
|
||||
for (Field f : c.getFields())
|
||||
{
|
||||
Annotations an = f.getAnnotations();
|
||||
if (getAnnotation(an, OBFUSCATED_NAME).equals(name))
|
||||
{
|
||||
return f;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Method findMethodWithObfuscatedName(ClassFile c, String name, String signature)
|
||||
{
|
||||
Signature sig = new Signature(signature);
|
||||
|
||||
for (Method m : c.getMethods())
|
||||
{
|
||||
Annotations an = m.getAnnotations();
|
||||
if (m.getName().equals(name) || getAnnotation(an, OBFUSCATED_NAME).equals(name))
|
||||
{
|
||||
Signature methodSig = getObfuscatedMethodSignature(m);
|
||||
|
||||
if (methodSig.equals(sig))
|
||||
{
|
||||
return m;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getAnnotation(Annotations an, Type type)
|
||||
{
|
||||
Annotation a = an.find(type);
|
||||
if (a != null)
|
||||
{
|
||||
for (Element e : a.getElements())
|
||||
{
|
||||
String str = (String) e.getValue();
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
private Signature getObfuscatedMethodSignature(Method method)
|
||||
{
|
||||
String sig = getAnnotation(method.getAnnotations(), OBFUSCATED_SIGNATURE);
|
||||
if (sig.isEmpty() == false)
|
||||
{
|
||||
return new Signature(sig); // if it is annotated, use that
|
||||
}
|
||||
else
|
||||
{
|
||||
return method.getDescriptor();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package net.runelite.runesuite;
|
||||
|
||||
public class HookMethod
|
||||
{
|
||||
String method;
|
||||
String owner;
|
||||
String name;
|
||||
int access;
|
||||
String[] parameters;
|
||||
String descriptor;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return method +
|
||||
owner +
|
||||
name;
|
||||
}
|
||||
}
|
||||
32344
deobfuscator/src/test/java/net/runelite/runesuite/hooks.json
Normal file
32344
deobfuscator/src/test/java/net/runelite/runesuite/hooks.json
Normal file
File diff suppressed because it is too large
Load Diff
3
deobfuscator/src/test/resources/deob-test.properties
Normal file
3
deobfuscator/src/test/resources/deob-test.properties
Normal file
@@ -0,0 +1,3 @@
|
||||
rs.client=C:/Users/Lucas/Desktop/gamepack180_deob.jar
|
||||
rs.version=180
|
||||
vanilla.client=${net.runelite.rs:vanilla:jar}
|
||||
Reference in New Issue
Block a user