Injector, deob, mixins

This commit is contained in:
Lucas
2019-06-08 09:33:50 +02:00
parent 276ff1995d
commit 49afdf7dc7
599 changed files with 84012 additions and 1821 deletions

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

View File

@@ -0,0 +1,123 @@
/*
* 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.injector;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.stream.Collectors;
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.Code;
import net.runelite.asm.attributes.code.instructions.InvokeStatic;
import net.runelite.asm.signature.Signature;
import static net.runelite.injector.Inject.RL_API_PACKAGE_BASE;
import static net.runelite.injector.InjectHookMethod.HOOKS;
import net.runelite.mapping.ObfuscatedName;
import net.runelite.mapping.ObfuscatedSignature;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
abstract class Obfuscated
{
public int foo(Obfuscated o, int i)
{
if (i > 0)
{
return i;
}
else
{
return -i;
}
}
}
@ObfuscatedName("Obfuscated")
class Actor
{
@ObfuscatedName("foo")
@ObfuscatedSignature(
signature = "(LObfuscated;I)I"
)
public int bar(Actor actor, int i)
{
throw new IllegalStateException();
}
}
public class InjectHookMethodTest
{
@Test
public void testProcess() throws IOException, InjectionException
{
InputStream in = getClass().getResourceAsStream("Actor.class");
ClassFile cf = ClassUtil.loadClass(in);
cf.setName("Actor");
cf.findMethod("bar").setDescriptor(new Signature("(LActor;I)I"));
ClassGroup deobfuscated = new ClassGroup();
deobfuscated.addClass(cf);
in = getClass().getResourceAsStream("Obfuscated.class");
ClassFile obcf = ClassUtil.loadClass(in);
obcf.setName("Obfuscated");
obcf.findMethod("foo").setDescriptor(new Signature("(LObfuscated;I)I"));
ClassGroup obfuscated = new ClassGroup();
obfuscated.addClass(obcf);
Method method = cf.findMethod("bar");
assert method != null;
Inject inject = new Inject(deobfuscated, obfuscated);
InjectHookMethod injectHookMethod = new InjectHookMethod(inject);
injectHookMethod.process(method);
method = obcf.findMethod("foo");
assert method != null;
Code code = method.getCode();
List<InvokeStatic> invokeIns = code.getInstructions().getInstructions().stream()
.filter(i -> i instanceof InvokeStatic)
.map(i -> (InvokeStatic) i)
.filter(i -> i.getMethod().getClazz().getName().equals(HOOKS))
.collect(Collectors.toList());
assertTrue(!invokeIns.isEmpty());
assertEquals(2, invokeIns.size());
InvokeStatic invokeStatic = invokeIns.get(0);
Signature signature = invokeStatic.getMethod().getType();
assertEquals(3, signature.size()); // this + patamers
Type arg = signature.getTypeOfArg(1);
assertEquals(RL_API_PACKAGE_BASE.replace('.', '/') + "Actor", arg.getInternalName());
}
}

View File

@@ -0,0 +1,116 @@
/*
* 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.Field;
import net.runelite.asm.Method;
import net.runelite.asm.Type;
import net.runelite.asm.attributes.Code;
import net.runelite.asm.attributes.code.Instruction;
import static net.runelite.asm.attributes.code.InstructionType.CHECKCAST;
import net.runelite.asm.attributes.code.Instructions;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class InjectSetterTest
{
interface APIClass
{
void setTest(int i);
void setTestObject(Object str);
}
@Test
public void testInjectSetterInt() throws NoSuchMethodException
{
Inject inject = mock(Inject.class);
when(inject.findImportMethodOnApi(any(Class.class), anyString(), any(Boolean.class)))
.thenReturn(APIClass.class.getDeclaredMethod("setTest", int.class));
when(inject.createLoadForTypeIndex(any(Instructions.class), any(Type.class), anyInt()))
.thenReturn(mock(Instruction.class));
InjectSetter instance = new InjectSetter(inject);
ClassFile targetClass = new ClassFile();
targetClass.setName("test");
Field field = new Field(targetClass, "test", Type.INT);
targetClass.addField(field);
instance.injectSetter(targetClass, APIClass.class, field, "test", null);
Method injectedMethod = targetClass.findMethod("setTest");
assertNotNull(injectedMethod);
Code code = injectedMethod.getCode();
Instructions instructions = code.getInstructions();
assertFalse(instructions.getInstructions().stream()
.filter(i -> i.getType() == CHECKCAST)
.findAny()
.isPresent());
}
@Test
public void testInjectSetterObject() throws NoSuchMethodException
{
Inject inject = mock(Inject.class);
when(inject.findImportMethodOnApi(any(Class.class), anyString(), any(Boolean.class)))
.thenReturn(APIClass.class.getDeclaredMethod("setTestObject", Object.class));
when(inject.createLoadForTypeIndex(any(Instructions.class), any(Type.class), anyInt()))
.thenReturn(mock(Instruction.class));
InjectSetter instance = new InjectSetter(inject);
ClassFile targetClass = new ClassFile();
targetClass.setName("test");
Field field = new Field(targetClass, "testObject", Type.STRING);
targetClass.addField(field);
instance.injectSetter(targetClass, APIClass.class, field, "testObject", null);
Method injectedMethod = targetClass.findMethod("setTestObject");
assertNotNull(injectedMethod);
Code code = injectedMethod.getCode();
Instructions instructions = code.getInstructions();
assertTrue(instructions.getInstructions().stream()
.filter(i -> i.getType() == CHECKCAST)
.findAny()
.isPresent());
}
}

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.injector;
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 InjectTest
{
@Rule
public DeobTestProperties properties = new DeobTestProperties();
@Rule
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
private ClassGroup deob, vanilla;
@Before
public void before() throws IOException
{
deob = JarUtil.loadJar(new File(properties.getRsClient()));
vanilla = JarUtil.loadJar(new File(properties.getVanillaClient()));
}
@After
public void after() throws IOException
{
JarUtil.saveJar(vanilla, folder.newFile());
}
@Test
@Ignore
public void testRun() throws InjectionException
{
Inject instance = new Inject(deob, vanilla);
instance.run();
InjectorValidator iv = new InjectorValidator(vanilla);
iv.validate();
}
}

View File

@@ -0,0 +1,268 @@
/*
* 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.injector;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.runelite.api.mixins.Copy;
import net.runelite.api.mixins.Replace;
import net.runelite.api.mixins.Shadow;
import net.runelite.asm.ClassFile;
import net.runelite.asm.ClassGroup;
import net.runelite.asm.ClassUtil;
import net.runelite.asm.Field;
import net.runelite.asm.Method;
import static net.runelite.asm.Type.INT;
import net.runelite.asm.attributes.code.instructions.GetStatic;
import net.runelite.asm.attributes.code.instructions.InvokeVirtual;
import net.runelite.asm.attributes.code.instructions.LDC;
import net.runelite.asm.signature.Signature;
import net.runelite.mapping.ObfuscatedName;
import net.runelite.mapping.ObfuscatedSignature;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
import static org.objectweb.asm.Opcodes.ACC_STATIC;
@ObfuscatedName("net/runelite/injector/VanillaTarget")
class DeobTarget
{
@ObfuscatedName("ob_foo3")
@ObfuscatedSignature(
signature = "(I)V",
garbageValue = "123"
)
private void foo3()
{
// De-obfuscated foo3
System.out.println("foo3");
}
@ObfuscatedName("ob_foo4")
private static int foo4;
}
class VanillaTarget
{
private void ob_foo3(int garbageValue)
{
// Obfuscated foo3
if (garbageValue != 123)
{
return;
}
System.out.println("foo3");
}
private static int ob_foo4;
}
abstract class Source
{
@net.runelite.api.mixins.Inject
private static int foo;
@net.runelite.api.mixins.Inject
private void foo2()
{
}
@Copy("foo3")
abstract void foo3();
@Replace("foo3")
private void rl$foo3()
{
System.out.println("replaced");
System.out.println(foo4);
foo3();
}
@Shadow("foo4")
private static int foo4;
}
// Test shadowing the "foo" field injected by Source
abstract class Source2
{
@Shadow("foo")
private static int foo;
@net.runelite.api.mixins.Inject
private void foo5()
{
System.out.println(foo);
}
}
public class MixinInjectorTest
{
@Test
public void testInject() throws Exception
{
InputStream deobIn = getClass().getResourceAsStream("DeobTarget.class");
ClassFile deobTarget = ClassUtil.loadClass(deobIn);
ClassGroup deob = new ClassGroup();
deob.addClass(deobTarget);
InputStream vanillaIn = getClass().getResourceAsStream("VanillaTarget.class");
ClassFile vanillaTarget = ClassUtil.loadClass(vanillaIn);
ClassGroup vanilla = new ClassGroup();
vanilla.addClass(vanillaTarget);
Map<Class<?>, List<ClassFile>> mixinClasses = new HashMap<>();
mixinClasses.put(Source.class, Collections.singletonList(vanillaTarget));
mixinClasses.put(Source2.class, Collections.singletonList(vanillaTarget));
Inject inject = new Inject(deob, vanilla);
new MixinInjector(inject).inject(mixinClasses);
// Check if "foo" has been injected
Field foo = vanillaTarget.findField("foo");
assertNotNull(foo);
assertEquals(INT, foo.getType());
assertEquals(ACC_PUBLIC | ACC_STATIC, foo.getAccessFlags());
// Check if "foo2()V" has been injected
Method foo2 = vanillaTarget.findMethod("foo2");
assertNotNull(foo2);
assertEquals(new Signature("()V"), foo2.getDescriptor());
assertEquals(ACC_PUBLIC, foo2.getAccessFlags());
// Check if "ob_foo3(I)V" was copied
Method foo3 = vanillaTarget.findMethod("copy$foo3");
assertNotNull(foo3);
assertEquals(new Signature("(I)V"), foo3.getDescriptor());
assertEquals(ACC_PUBLIC, foo3.getAccessFlags());
// Check if "ob_foo3(I)V" was replaced
Method ob_foo3 = vanillaTarget.findMethod("ob_foo3");
assertNotNull(ob_foo3);
assertEquals(new Signature("(I)V"), ob_foo3.getDescriptor());
assertEquals(ob_foo3
.getCode()
.getInstructions()
.getInstructions()
.stream()
.filter(i -> i instanceof LDC && ((LDC) i).getConstant().equals("replaced"))
.count(), 1);
// Check that the "foo4" field access in the new code body was mapped correctly
assertEquals(ob_foo3
.getCode()
.getInstructions()
.getInstructions()
.stream()
.filter(i ->
{
if (!(i instanceof GetStatic))
{
return false;
}
net.runelite.asm.pool.Field field = ((GetStatic) i).getField();
if (!field.getClazz().getName().equals("net/runelite/injector/VanillaTarget"))
{
return false;
}
if (!field.getName().equals("ob_foo4"))
{
return false;
}
return true;
})
.count(), 1);
// Check that the "foo3()" call in the new code body was mapped to the copy
assertEquals(ob_foo3
.getCode()
.getInstructions()
.getInstructions()
.stream()
.filter(i ->
{
if (!(i instanceof InvokeVirtual))
{
return false;
}
net.runelite.asm.pool.Method method = ((InvokeVirtual) i).getMethod();
if (!method.getClazz().getName().equals("net/runelite/injector/VanillaTarget"))
{
return false;
}
if (!method.getName().equals("copy$foo3"))
{
return false;
}
return true;
})
.count(), 1);
// Check if "foo5()V" was injected
Method foo5 = vanillaTarget.findMethod("foo5");
assertNotNull(foo5);
assertEquals(new Signature("()V"), foo5.getDescriptor());
assertEquals(ACC_PUBLIC, foo5.getAccessFlags());
// Check that the shadow "foo" field access was mapped correctly
assertEquals(foo5
.getCode()
.getInstructions()
.getInstructions()
.stream()
.filter(i ->
{
if (!(i instanceof GetStatic))
{
return false;
}
net.runelite.asm.pool.Field field = ((GetStatic) i).getField();
if (!field.getClazz().getName().equals("net/runelite/injector/VanillaTarget"))
{
return false;
}
if (!field.getName().equals("foo"))
{
return false;
}
return true;
})
.count(), 1);
}
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
* 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.raw;
import net.runelite.asm.ClassFile;
import net.runelite.asm.ClassGroup;
import net.runelite.asm.ClassUtil;
import net.runelite.injector.Inject;
import org.junit.Test;
public class DrawAfterWidgetsTest
{
@Test
public void testInjectDrawWidgetsRev160() throws Exception
{
// Rev 160 does not have the drawWidgets call inlined
ClassFile deobClient = ClassUtil.loadClass(getClass().getResourceAsStream("/drawafterwidgets/Client_deob160.class"));
ClassFile deobRasterizer = ClassUtil.loadClass(getClass().getResourceAsStream("/drawafterwidgets/Rasterizer2D_deob160.class"));
ClassGroup deob = new ClassGroup();
deob.addClass(deobClient);
deob.addClass(deobRasterizer);
ClassFile obClient = ClassUtil.loadClass(getClass().getResourceAsStream("/drawafterwidgets/Client_ob160.class"));
ClassFile obRasterizer = ClassUtil.loadClass(getClass().getResourceAsStream("/drawafterwidgets/Rasterizer2D_ob160.class"));
ClassGroup vanilla = new ClassGroup();
vanilla.addClass(obClient);
vanilla.addClass(obRasterizer);
Inject inject = new Inject(deob, vanilla);
new DrawAfterWidgets(inject).inject();
}
@Test
public void testInjectDrawWidgetsRev153() throws Exception
{
// Rev 153 has the drawWidgets call inlined
ClassFile deobClient = ClassUtil.loadClass(getClass().getResourceAsStream("/drawafterwidgets/Client_deob153.class"));
ClassFile deobRasterizer = ClassUtil.loadClass(getClass().getResourceAsStream("/drawafterwidgets/Rasterizer2D_deob153.class"));
ClassGroup deob = new ClassGroup();
deob.addClass(deobClient);
deob.addClass(deobRasterizer);
ClassFile obClient = ClassUtil.loadClass(getClass().getResourceAsStream("/drawafterwidgets/Client_ob153.class"));
ClassFile obRasterizer = ClassUtil.loadClass(getClass().getResourceAsStream("/drawafterwidgets/Rasterizer2D_ob153.class"));
ClassGroup vanilla = new ClassGroup();
vanilla.addClass(obClient);
vanilla.addClass(obRasterizer);
Inject inject = new Inject(deob, vanilla);
new DrawAfterWidgets(inject).inject();
}
}