Merge pull request #527 from Lucwousin/git_mag_van_mij_de_kanker_krijgen

Injector
This commit is contained in:
Tyler Bochard
2019-06-08 17:09:32 -04:00
committed by GitHub
217 changed files with 41738 additions and 654 deletions

View File

@@ -38,9 +38,9 @@ import net.runelite.cache.models.VertexNormal;
public class ItemSpriteFactory
{
public static final BufferedImage createSprite(ItemProvider itemProvider, ModelProvider modelProvider,
SpriteProvider spriteProvider, TextureProvider textureProvider,
int itemId, int quantity, int border, int shadowColor,
boolean noted) throws IOException
SpriteProvider spriteProvider, TextureProvider textureProvider,
int itemId, int quantity, int border, int shadowColor,
boolean noted) throws IOException
{
Sprite spritePixels = createSpritePixels(itemProvider, modelProvider, spriteProvider, textureProvider,
itemId, quantity, border, shadowColor, noted);
@@ -48,9 +48,9 @@ public class ItemSpriteFactory
}
private static final Sprite createSpritePixels(ItemProvider itemProvider, ModelProvider modelProvider,
SpriteProvider spriteProvider, TextureProvider textureProvider,
int itemId, int quantity, int border, int shadowColor,
boolean noted) throws IOException
SpriteProvider spriteProvider, TextureProvider textureProvider,
int itemId, int quantity, int border, int shadowColor,
boolean noted) throws IOException
{
ItemDefinition item = itemProvider.provide(itemId);

View File

@@ -29,7 +29,7 @@
<parent>
<groupId>net.runelite</groupId>
<artifactId>runelite-parent</artifactId>
<version>1.5.27-SNAPSHOT</version>
<version>1.5.27-SNAPSHOT</version>
</parent>
<artifactId>deobfuscator</artifactId>
@@ -60,7 +60,6 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.8.0-beta4</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
@@ -79,8 +78,8 @@
</dependency>
<dependency>
<groupId>net.runelite</groupId>
<artifactId>runescape-client</artifactId>
<groupId>net.runelite.rs</groupId>
<artifactId>rs-client</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>

View File

@@ -88,7 +88,6 @@ import net.runelite.asm.attributes.code.instructions.IALoad;
import net.runelite.asm.attributes.code.instructions.IAStore;
import net.runelite.asm.attributes.code.instructions.IAdd;
import net.runelite.asm.attributes.code.instructions.IAnd;
import net.runelite.asm.attributes.code.instructions.IConstZero;
import net.runelite.asm.attributes.code.instructions.IDiv;
import net.runelite.asm.attributes.code.instructions.IInc;
import net.runelite.asm.attributes.code.instructions.ILoad;
@@ -168,7 +167,6 @@ public enum InstructionType
{
NOP(0x00, "nop", NOP.class),
ACONST_NULL(0x01, "aconst_null", AConstNull.class),
ICONST_0(0x03, "iconst_0", IConstZero.class),
BIPUSH(0x10, "bipush", BiPush.class),
SIPUSH(0x11, "sipush", SiPush.class),
LDC(-1, "ldc", LDC.class),

View File

@@ -255,7 +255,7 @@ public class PutField extends Instruction implements SetFieldInstruction
Instruction i = value.getPushed().getInstruction();
// sometimes ConstantValue field attributes and inlined into the constructor,
// which are all constants, so we ignore those mapping here
// which are all constants, so we ignore those mappings here
if (thisIc.getFrame().getMethod().getName().equals("<init>"))
{
if (i instanceof PushConstantInstruction || i instanceof AConstNull)

View File

@@ -34,7 +34,6 @@ import net.runelite.asm.Method;
import net.runelite.asm.Type;
import net.runelite.asm.attributes.Annotations;
import net.runelite.asm.execution.Execution;
import net.runelite.deob.deobfuscators.transformers.GetPathTransformer;
import net.runelite.deob.deobfuscators.CastNull;
import net.runelite.deob.deobfuscators.constparam.ConstantParameter;
import net.runelite.deob.deobfuscators.EnumDeobfuscator;
@@ -57,6 +56,7 @@ import net.runelite.deob.deobfuscators.cfg.ControlFlowDeobfuscator;
import net.runelite.deob.deobfuscators.exprargorder.ExprArgOrder;
import net.runelite.deob.deobfuscators.menuaction.MenuActionDeobfuscator;
import net.runelite.deob.deobfuscators.transformers.ClientErrorTransformer;
import net.runelite.deob.deobfuscators.transformers.GetPathTransformer;
import net.runelite.deob.deobfuscators.transformers.MaxMemoryTransformer;
import net.runelite.deob.deobfuscators.transformers.OpcodesTransformer;
import net.runelite.deob.deobfuscators.transformers.ReflectionTransformer;

View File

@@ -86,7 +86,7 @@ public class ConstructorMapper
}
/**
* Map constructors based on the class mapping of the given mapping
* Map constructors based on the class mappings of the given mapping
*/
public void mapConstructors()
{

View File

@@ -30,7 +30,7 @@ import net.runelite.asm.Method;
public class ExecutionMapper
{
// method1 maps to one of methods2, find out based on mapping
// method1 maps to one of methods2, find out based on mappings
private Method method1;
private Collection<Method> methods2;

View File

@@ -61,7 +61,7 @@ public class Mapper
finalm.reduce();
// map unexecuted methods (their mapping have not yet been merged)
// map unexecuted methods (their mappings have not yet been merged)
while (mapUnexecutedMethods(finalm));
finalm.buildClasses();
@@ -149,7 +149,7 @@ public class Mapper
private void mapMemberMethods(ParallelExecutorMapping mapping)
{
// pass #2 at method mapping, can use class file mapping learned
// pass #2 at method mapping, can use class file mappings learned
for (ClassFile cf : source.getClasses())
{
@@ -201,7 +201,7 @@ public class Mapper
/**
* execute and map already mapped methods that have not yet been "executed",
* and apply their mapping
* and apply their mappings
* @param mapping
* @return
*/

View File

@@ -202,8 +202,8 @@ public class ParallelExecutorMapping
/**
* makes the map one to one based on the weight of each mapping. If a
* mapping is mapped from the same object multiple places, the highest
* is used, and the other mapping are not considered when deducing the
* mapping of the other objects.
* is used, and the other mappings are not considered when deducing the
* mappings of the other objects.
*/
public void reduce()
{

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Adam <Adam@sigterm.info>
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -22,31 +22,23 @@
* (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.api.events;
import lombok.Data;
import net.runelite.api.Actor;
package net.runelite.asm;
/**
* An event where the graphic of an {@link Actor} has changed.
* <p>
* The graphic the player has changed to can be obtained using
* {@link //Actor#getGraphic()}.
* <p>
* Examples of when this event may trigger include:
* <ul>
* <li>Casting a magic spell</li>
* <li>Using a fairy ring</li>
* <li>Breaking a teleport tab</li>
* </ul>
*
* @see net.runelite.api.GraphicID
*/
@Data
public class GraphicChanged
import java.io.IOException;
import java.io.InputStream;
import net.runelite.asm.visitors.ClassFileVisitor;
import org.objectweb.asm.ClassReader;
public class ClassUtil
{
/**
* The actor that has had their graphic changed.
*/
private Actor actor;
}
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();
}
}

View File

@@ -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());
}
}

View File

@@ -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();
}

View File

@@ -0,0 +1,37 @@
/*
* 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()
{
}
}

View File

@@ -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());
}
}

View File

@@ -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;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -22,42 +22,45 @@
* (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.Type;
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.Variables;
import org.junit.Assert;
import org.junit.Test;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class IConstZero extends Instruction
/**
*
* @author Adam
*/
public class LCmpTest
{
public IConstZero(Instructions instructions, InstructionType type)
@Test
public void testIsSame()
{
super(instructions, type);
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);
}
public IConstZero(Instructions instructions)
{
super(instructions, InstructionType.ICONST_0);
}
@Override
public InstructionContext execute(Frame frame)
{
InstructionContext ins = new InstructionContext(this, frame);
Stack stack = frame.getStack();
StackContext ctx = new StackContext(ins, Type.INT, new Value(0));
stack.push(ctx);
ins.push(ctx);
return ins;
}
}

View File

@@ -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();
}
}

View File

@@ -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")));
}
}

View File

@@ -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));
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}
}

View File

@@ -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());
}
}

View File

@@ -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());
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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());
}
}

View File

@@ -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());
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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"));
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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());
}
}

View File

@@ -0,0 +1,254 @@
/*
* 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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -0,0 +1,389 @@
/*
* 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.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 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());
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -0,0 +1,74 @@
/*
* 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.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);
}
}

View File

@@ -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();
}
}

View File

@@ -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]);
}
}

View File

@@ -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");
}
}
}

View File

@@ -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!");
}
}

View File

@@ -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
{
}

View File

@@ -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
{
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -0,0 +1,61 @@
/*
* 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;
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();
}
}

View File

@@ -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);
}
}

View 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();
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,139 @@
/*
* 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.mapping.Export;
import net.runelite.mapping.ObfuscatedName;
import net.runelite.runeloader.inject.GetterInjectInstruction;
import net.runelite.runeloader.inject.Injection;
import net.runelite.runeloader.inject.InjectionModscript;
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 = f.getDeclaredAnnotation(ObfuscatedName.class);
if (oc == null)
{
continue;
}
if (oc.value().equals(name))
{
return f;
}
}
return null;
}
private boolean isExported(Field f)
{
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 = 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));
}
}
}

View File

@@ -0,0 +1,164 @@
/*
* 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.mapping.Export;
import net.runelite.mapping.ObfuscatedGetter;
import net.runelite.mapping.ObfuscatedName;
import net.runelite.runeloader.inject.GetterInjectInstruction;
import net.runelite.runeloader.inject.Injection;
import net.runelite.runeloader.inject.InjectionModscript;
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 = f.getDeclaredAnnotation(ObfuscatedName.class);
if (oc == null)
{
continue;
}
if (oc.value().equals(name))
{
return f;
}
}
return null;
}
private Integer getIntegerMultiplier(Field f)
{
ObfuscatedGetter getter = f.getDeclaredAnnotation(ObfuscatedGetter.class);
if (getter == null)
{
return null;
}
return getter.intValue() == 0 ? null : getter.intValue();
}
private String getExportedName(Field f)
{
Export e = 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 = 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);
}
}
}

View File

@@ -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.deob.util.JarUtil;
import net.runelite.runeloader.inject.AddInterfaceInstruction;
import net.runelite.runeloader.inject.GetterInjectInstruction;
import net.runelite.runeloader.inject.Injection;
import net.runelite.runeloader.inject.InjectionModscript;
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 = 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);
}
}

View File

@@ -0,0 +1,45 @@
/*
* 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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,79 @@
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();
}
}
}
}

View File

@@ -0,0 +1,21 @@
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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,25 @@
package net.runelite.runeloader.inject;
import org.objectweb.asm.tree.AbstractInsnNode;
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;
}
}

View File

@@ -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;
}

View File

@@ -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 + '}';
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
rs.client=C:/Users/Lucas/Desktop/gamepack180_deob.jar
rs.version=180
vanilla.client=${net.runelite.rs:vanilla:jar}

View File

@@ -71,9 +71,9 @@
</dependency>
<dependency>
<groupId>com.runeswag</groupId>
<groupId>net.runelite</groupId>
<artifactId>deobfuscator</artifactId>
<version>1.0-SNAPSHOT</version>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>

View File

@@ -466,7 +466,7 @@ public class Inject
return null;
}
Field toObField(Field field)
public Field toObField(Field field)
{
String obfuscatedClassName = DeobAnnotations.getObfuscatedName(field.getClassFile().getAnnotations());
String obfuscatedFieldName = DeobAnnotations.getObfuscatedName(field.getAnnotations()); // obfuscated name of field
@@ -524,7 +524,7 @@ public class Inject
return Type.getType("L" + finalType.getName().replace('.', '/') + ";", type.getDimensions());
}
Type apiTypeToDeobfuscatedType(Type type) throws InjectionException
Type apiTypeToDeobfuscatedType(Type type)
{
if (type.isPrimitive())
{

View File

@@ -48,7 +48,7 @@ public class InjectMojo extends AbstractMojo
@Parameter(defaultValue = "${project.build.outputDirectory}")
private File outputDirectory;
@Parameter(defaultValue = "./runescape-client/target/runescape-client-1.5.27-SNAPSHOT.jar", readonly = true, required = true)
@Parameter(defaultValue = "./rs-client/target/rs-client-${project.version}.jar", readonly = true, required = true)
private String rsClientPath;
@Parameter(defaultValue = "${net.runelite.rs:vanilla:jar}", readonly = true, required = true)

View File

@@ -48,6 +48,7 @@ import net.runelite.asm.attributes.code.instruction.types.LVTInstruction;
import net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction;
import net.runelite.asm.attributes.code.instruction.types.ReturnInstruction;
import net.runelite.asm.attributes.code.instructions.ALoad;
import net.runelite.asm.attributes.code.instructions.ANewArray;
import net.runelite.asm.attributes.code.instructions.CheckCast;
import net.runelite.asm.attributes.code.instructions.GetField;
import net.runelite.asm.attributes.code.instructions.ILoad;
@@ -229,10 +230,10 @@ public class MixinInjector
cf.addField(copy);
if (injectedFields.containsKey(field.getName()))
if (injectedFields.containsKey(field.getName()) && !field.getName().equals(ASSERTION_FIELD))
{
java.util.logging.Logger.getAnonymousLogger().severe("Duplicate field : "+ field.getName());
//throw new InjectionException("Injected field names must be globally unique");
java.util.logging.Logger.getAnonymousLogger().severe("Duplicate field : " + field.getName());
throw new InjectionException("Injected field names must be globally unique");
}
injectedFields.put(field.getName(), copy);
@@ -333,7 +334,7 @@ public class MixinInjector
private void injectMethods(ClassFile mixinCf, ClassFile cf, Map<net.runelite.asm.pool.Field, Field> shadowFields)
throws InjectionException
{
// Keeps mapping between methods annotated with @Copy -> the copied method within the vanilla pack
// Keeps mappings between methods annotated with @Copy -> the copied method within the vanilla pack
Map<net.runelite.asm.pool.Method, CopiedMethod> copiedMethods = new HashMap<>();
// Handle the copy mixins first, so all other mixins know of the copies
@@ -654,6 +655,21 @@ public class MixinInjector
{
Instruction i = iterator.next();
if (i instanceof ANewArray)
{
Type type = ((ANewArray) i).getType_();
ClassFile deobCf = inject.getDeobfuscated().findClass(type.toString().replace("Lnet/runelite/rs/api/RS", "").replace(";", ""));
if (deobCf != null)
{
ClassFile obReturnTypeClass = inject.toObClass(deobCf);
Type newType = new Type("L" + obReturnTypeClass.getName() + ";");
((ANewArray) i).setType(newType);
logger.info("Replaced {} type {} with type {}", i, type, newType);
}
}
if (i instanceof InvokeInstruction)
{
InvokeInstruction ii = (InvokeInstruction) i;

View File

@@ -1,12 +1,14 @@
package net.runelite.injector.raw;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import net.runelite.asm.ClassFile;
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.ILoad;
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
import net.runelite.asm.attributes.code.instructions.LDC;
import net.runelite.asm.pool.Class;
import net.runelite.asm.signature.Signature;
import net.runelite.deob.DeobAnnotations;
@@ -37,34 +39,85 @@ public class ClearColorBuffer
private void injectColorBufferHooks() throws InjectionException
{
Method obmethod = findStaticMethod("drawEntities");
net.runelite.asm.pool.Method fillRectangle = findStaticMethod("Rasterizer2D_fillRectangle").getPoolMethod();
Instructions ins = obmethod.getCode().getInstructions();
replace(ins, fillRectangle);
}
private void replace(Instructions ins, net.runelite.asm.pool.Method meth)
{
List<Instruction> insList = new ArrayList<>();
for (Instruction i : ins.getInstructions())
int count = 0;
int replaced = 0;
for (ClassFile cf : inject.getVanilla().getClasses())
{
if (i instanceof InvokeStatic)
for (Method m : cf.getMethods())
{
if (((InvokeStatic) i).getMethod().equals(meth))
if (!m.isStatic())
{
int index = ins.getInstructions().indexOf(i);
log.info("Found drawRectangle at index {}", index);
continue;
}
insList.add(i);
Code c = m.getCode();
if (c == null)
{
continue;
}
Instructions ins = c.getInstructions();
ListIterator<Instruction> it = ins.getInstructions().listIterator();
for (; it.hasNext(); )
{
Instruction i = it.next();
if (!(i instanceof InvokeStatic))
{
continue;
}
if (((InvokeStatic) i).getMethod().equals(fillRectangle))
{
int indexToReturnTo = it.nextIndex();
count++;
it.previous();
Instruction current = it.previous();
if (current instanceof LDC && ((LDC) current).getConstantAsInt() == 0)
{
int varIdx = 0;
for (; ;)
{
current = it.previous();
if (current instanceof ILoad && ((ILoad) current).getVariableIndex() == 3 - varIdx)
{
varIdx++;
log.debug(varIdx + " we can count yay");
continue;
}
break;
}
if (varIdx == 4)
{
for (; !(current instanceof InvokeStatic); )
{
current = it.next();
}
assert it.nextIndex() == indexToReturnTo;
it.set(new InvokeStatic(ins, clearBuffer));
replaced++;
log.debug("Found drawRectangle at {}. Found: {}, replaced {}", m.getName(), count, replaced);
}
else
{
log.debug("Welp, guess this wasn't it chief " + m);
}
}
while (it.nextIndex() != indexToReturnTo)
{
it.next();
}
}
}
}
}
for (Instruction i : insList)
{
Instruction invoke = new InvokeStatic(ins, clearBuffer);
ins.replace(i, invoke);
}
}
private Method findStaticMethod(String name) throws InjectionException

View File

@@ -166,7 +166,7 @@ public class DrawAfterWidgets
{
// If we get here, we're either in the wrong method
// or Jagex has removed the "if (535573958 * kl != -1)"
logger.debug("Could not find the label for jumping to the " + noClip + " call in " + m);
// logger.debug("Could not find the label for jumping to the " + noClip + " call in " + m);
continue;
}

View File

@@ -0,0 +1,193 @@
/*
package net.runelite.injector.raw;
import com.google.common.base.Strings;
import java.util.HashSet;
import java.util.Set;
import net.runelite.asm.ClassFile;
import net.runelite.asm.Method;
import net.runelite.asm.Type;
import net.runelite.asm.attributes.Annotations;
import net.runelite.asm.attributes.Code;
import net.runelite.asm.attributes.annotation.Annotation;
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.instruction.types.ComparisonInstruction;
import net.runelite.asm.attributes.code.instruction.types.JumpingInstruction;
import net.runelite.asm.attributes.code.instruction.types.ReturnInstruction;
import net.runelite.asm.attributes.code.instructions.GetStatic;
import net.runelite.asm.attributes.code.instructions.IfACmpEq;
import net.runelite.asm.attributes.code.instructions.IfACmpNe;
import net.runelite.asm.attributes.code.instructions.IfEq;
import net.runelite.asm.attributes.code.instructions.IfNe;
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
import net.runelite.asm.execution.Execution;
import net.runelite.asm.execution.InstructionContext;
import net.runelite.asm.pool.Class;
import net.runelite.asm.pool.Field;
import net.runelite.asm.signature.Signature;
import net.runelite.deob.DeobAnnotations;
import net.runelite.injector.Inject;
import net.runelite.injector.InjectionException;
public class DrawMenu
{
private final Inject inject;
private static final Field isMenuOpen = new Field(
new Class("Client"),
"isMenuOpen",
Type.BOOLEAN
);
private static final net.runelite.asm.pool.Method hook = new net.runelite.asm.pool.Method(
new Class("net.runelite.client.callback.Hooks"),
"drawMenu",
new Signature("()Z")
);
public DrawMenu(Inject inject)
{
this.inject =inject;
}
public void inject() throws InjectionException
{
Method drawLoggedIn = findDeobThing("drawLoggedIn", "Client", false);
Instructions ins = drawLoggedIn.getCode().getInstructions();
int menuOpenIdx = -1;
Field field = toObField(isMenuOpen).getPoolField();
for (Instruction i : ins.getInstructions())
{
if (!(i instanceof GetStatic))
{
continue;
}
if (((GetStatic) i).getField().equals(field))
{
menuOpenIdx = ins.getInstructions().indexOf(i);
}
}
if (menuOpenIdx == -1)
{
throw new InjectionException("Couldn't find the isMenuOpen check!");
}
// This is where the IFEQ or IFNE will be
final Instruction jump = ins.getInstructions().get(menuOpenIdx + 1);
// We want to inject if it's false so
if (jump instanceof IfEq)
{
// Not this one, but we gotta find out where the paths will intersect
Set<Label> labels = getLabels(jump);
}
}
private Set<Label> getLabels(Instruction i)
{
Set<Label> labels = new HashSet<>();
Execution ex = new Execution(inject.getVanilla());
ex.addMethod(i.getInstructions().getCode().getMethod());
ex.noInvoke = true;
ex.addExecutionVisitor((InstructionContext ic) ->
{
Instruction in = ic.getInstruction();
Instructions ins = in.getInstructions();
Code code = ins.getCode();
Method method = code.getMethod();
//ic.
});
}
private Set<Label> findLabels(Instructions ins, int idx)
{
Set<Label> labels = new HashSet<>();
Instruction i = null;
while (labels.size() < 10 || !(i instanceof ReturnInstruction))
{
i = ins.getInstructions().get(idx);
if (i instanceof JumpingInstruction)
{
Label cur = ((JumpingInstruction) i).getJumps().get(0);
labels.add((Label) cur);
idx = ins.getInstructions().indexOf(cur) + 1;
}
}
return labels;
}
private Method findDeobThing(String name, String hint, boolean isStatic) throws InjectionException
{
if (!Strings.isNullOrEmpty(hint))
{
ClassFile hintCf = inject.getDeobfuscated().findClass(hint);
if (hintCf != null)
{
for (Method m : hintCf.getMethods())
{
if (isStatic != m.isStatic())
{
continue;
}
if (!m.getName().equals(name))
{
continue;
}
Annotations an = m.getAnnotations();
if (an == null || an.find(DeobAnnotations.EXPORT) == null)
{
continue; // not an exported field
}
String obfuscatedName = DeobAnnotations.getObfuscatedName(an);
return inject.toObClass(hintCf).findMethod(obfuscatedName);
}
}
}
for (ClassFile cf : inject.getDeobfuscated().getClasses())
{
for (Method m : cf.getMethods())
{
if (isStatic != m.isStatic())
{
continue;
}
Annotations an = m.getAnnotations();
if (an == null || an.find(DeobAnnotations.EXPORT) == null)
{
continue; // not an exported field
}
String obfuscatedName = DeobAnnotations.getObfuscatedName(an);
return inject.toObClass(cf).findMethod(obfuscatedName);
}
}
throw new InjectionException("Method not found!");
}
private net.runelite.asm.Field toObField(Field field) throws InjectionException
{
ClassFile cf = inject.getDeobfuscated().findClass(field.getClazz().getName());
for (net.runelite.asm.Field f : cf.getFields())
{
if (f.getPoolField().equals(field))
{
return inject.toObField(f);
}
}
throw new InjectionException("Field not found!");
}
}
*/

View File

@@ -11,6 +11,8 @@ 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.instruction.types.LVTInstruction;
import net.runelite.asm.attributes.code.instructions.ALoad;
import net.runelite.asm.attributes.code.instructions.ArrayStore;
import net.runelite.asm.attributes.code.instructions.GetField;
import net.runelite.asm.attributes.code.instructions.GetStatic;
@@ -44,6 +46,8 @@ public class RasterizerHook
private static final String r3d_vert = "Rasterizer3D_vertAlpha";
private static final String r3d_horiz = "Rasterizer3D_horizAlpha";
private static final String r3d_field = "Rasterizer3D_alpha";
private static final String sprite_alpha1 = "Sprite_alpha1";
private static final String sprite_alpha2 = "Sprite_alpha2";
private static final String font = "AbstractFont_placeGlyph";
private static final String rast3D = "Rasterizer3D_iDontKnow";
@@ -71,15 +75,14 @@ public class RasterizerHook
public void inject() throws InjectionException
{
runDrawAlpha();
logger.info("Injected {} drawAlpha's", count);
assert count == 35 : "Either too many or not enough drawAlpha's were injected";
count = 0;
runVars();
{
// throw new InjectionException("Not all variable alpha thingshits were found");
}
run();
}
@@ -92,6 +95,8 @@ public class RasterizerHook
runAlpha(line_alpha, 1, 4);
runAlpha(line_alpha2, 1, 4);
runAlpha(more_alpha, 1, 5);
runAlpha(sprite_alpha1, 1, 9, 0);
runAlpha(sprite_alpha2, 1, 12, 0);
}
private void runR3DAlpha(String methodName, int req, String fieldName) throws InjectionException
@@ -135,16 +140,27 @@ public class RasterizerHook
}
private void runAlpha(String methodName, int req, int extraArg) throws InjectionException
{
runAlpha(methodName, req, extraArg, -1);
}
private void runAlpha(String methodName, int req, int extraArg, int varIndex) throws InjectionException
{
final net.runelite.asm.pool.Field pixels = findDeobField("Rasterizer2D_pixels").getPoolField();
Method meth = findStaticMethod(methodName);
Instructions ins = meth.getCode().getInstructions();
if (meth == null)
{
throw new InjectionException(methodName + " couldnt be found");
}
Code code = meth.getCode();
Instructions ins = code.getInstructions();
int added = 0;
List<Integer> indices = new ArrayList<>();
for (Instruction i : ins.getInstructions())
{
if (!(i instanceof IALoad) && !(i instanceof GetField))
if (!(i instanceof IALoad) && !(i instanceof GetField) && !(i instanceof ALoad))
{
continue;
}
@@ -155,10 +171,15 @@ public class RasterizerHook
{
indices.add(ins.getInstructions().indexOf(i));
}
continue;
}
indices.add(ins.getInstructions().indexOf(i));
else if ((i instanceof ALoad) && varIndex >= 0 && ((LVTInstruction) i).getVariableIndex() == varIndex)
{
indices.add(ins.getInstructions().indexOf(i));
}
else if (varIndex == -1)
{
indices.add(ins.getInstructions().indexOf(i));
}
}
if (indices.isEmpty())
@@ -273,7 +294,7 @@ public class RasterizerHook
Instructions ins = i.getInstructions();
Code code = ins.getCode();
Method method = code.getMethod();
logger.debug(i.toString());
//logger.debug(i.toString());
if (!(i instanceof IAStore))
{

View File

@@ -0,0 +1,63 @@
/*
* 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.injector;
import net.runelite.asm.ClassFile;
import net.runelite.asm.Method;
import net.runelite.asm.signature.Signature;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.mockito.Matchers;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class InjectConstructTest
{
interface APIClass
{
APIClass create();
}
@Test
public void testInjectConstruct() throws Exception
{
ClassFile targetClass = new ClassFile();
targetClass.setName("test");
ClassFile vanillaClass = new ClassFile();
vanillaClass.setName("ab");
Method constructor = new Method(vanillaClass, "<init>", new Signature("()V"));
vanillaClass.addMethod(constructor);
Inject inject = mock(Inject.class);
when(inject.findVanillaForInterface(Matchers.any(Class.class)))
.thenReturn(vanillaClass);
InjectConstruct injectConstruct = new InjectConstruct(inject);
injectConstruct.injectConstruct(targetClass, APIClass.class.getDeclaredMethod("create"));
assertNotNull(targetClass.findMethod("create"));
}
}

Some files were not shown because too many files have changed in this diff Show More