use of net.runelite.asm.attributes.annotation.Annotation in project runelite by runelite.
the class ConstantParameter method annotateObfuscatedSignature.
private void annotateObfuscatedSignature(ConstantMethodParameter parameter) {
for (Method m : parameter.methods) {
Object value = parameter.values.get(0);
Annotations annotations = m.getAnnotations();
Annotation obfuscatedSignature = annotations.find(DeobAnnotations.OBFUSCATED_SIGNATURE);
if (obfuscatedSignature != null && obfuscatedSignature.getElements().size() == 2) {
// already annotated
continue;
}
if (obfuscatedSignature == null) {
obfuscatedSignature = annotations.addAnnotation(DeobAnnotations.OBFUSCATED_SIGNATURE, "signature", m.getDescriptor().toString());
}
// Add garbage value
Element element = new Element(obfuscatedSignature);
element.setName("garbageValue");
element.setValue(value.toString());
obfuscatedSignature.addElement(element);
}
}
use of net.runelite.asm.attributes.annotation.Annotation in project runelite by runelite.
the class AnnotationTest method testAnnotation.
@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());
}
use of net.runelite.asm.attributes.annotation.Annotation in project runelite by runelite.
the class AnnotationCopier method copy.
private void copy(Annotations an, Annotations an2) {
for (Annotation a : an2.getAnnotations()) {
if (isType(a.getType())) {
an2.removeAnnotation(a);
}
}
for (Annotation a : an.getAnnotations()) {
if (!isType(a.getType()))
continue;
Annotation a2 = new Annotation(an2);
a2.setType(a.getType());
for (Element element : a.getElements()) {
Element element2 = new Element(a2);
element2.setName(element.getName());
element2.setValue(element.getValue());
a2.addElement(element2);
}
an2.addAnnotation(a2);
}
}
use of net.runelite.asm.attributes.annotation.Annotation in project runelite by runelite.
the class Inject method getMethodSignature.
public Signature getMethodSignature(Method m) {
Signature signature = m.getDescriptor();
Annotation obfSignature = m.getAnnotations().find(DeobAnnotations.OBFUSCATED_SIGNATURE);
if (obfSignature != null) {
// Annotation exists. Signature was updated by us during deobfuscation
signature = DeobAnnotations.getObfuscatedSignature(m);
}
return signature;
}
use of net.runelite.asm.attributes.annotation.Annotation in project runelite by runelite.
the class Inject method run.
public void run() throws InjectionException {
Map<ClassFile, java.lang.Class> implemented = new HashMap<>();
// check below works
for (ClassFile cf : deobfuscated.getClasses()) {
Annotations an = cf.getAnnotations();
if (an == null || an.size() == 0) {
continue;
}
String obfuscatedName = DeobAnnotations.getObfuscatedName(an);
if (obfuscatedName == null) {
obfuscatedName = cf.getName();
}
ClassFile other = vanilla.findClass(obfuscatedName);
assert other != null : "unable to find vanilla class from obfuscated name: " + obfuscatedName;
java.lang.Class implementingClass = injectInterface(cf, other);
// it can not implement an interface but still have exported static fields, which are
// moved to client
implemented.put(cf, implementingClass);
}
// requires interfaces to be injected
mixinInjector.inject();
construct.inject(implemented);
for (ClassFile cf : deobfuscated.getClasses()) {
java.lang.Class implementingClass = implemented.get(cf);
Annotations an = cf.getAnnotations();
if (an == null || an.size() == 0) {
continue;
}
String obfuscatedName = DeobAnnotations.getObfuscatedName(an);
if (obfuscatedName == null) {
obfuscatedName = cf.getName();
}
ClassFile other = vanilla.findClass(obfuscatedName);
assert other != null : "unable to find vanilla class from obfuscated name: " + obfuscatedName;
for (Field f : cf.getFields()) {
an = f.getAnnotations();
if (an == null || an.find(DeobAnnotations.EXPORT) == null) {
// not an exported field
continue;
}
Annotation exportAnnotation = an.find(DeobAnnotations.EXPORT);
String exportedName = exportAnnotation.getElement().getString();
obfuscatedName = DeobAnnotations.getObfuscatedName(an);
Annotation getterAnnotation = an.find(DeobAnnotations.OBFUSCATED_GETTER);
Number getter = null;
if (getterAnnotation != null) {
getter = (Number) getterAnnotation.getElement().getValue();
}
// the ob jar is the same as the vanilla so this field must exist in this class.
Type obType = getFieldType(f);
Field otherf = other.findField(obfuscatedName, obType);
assert otherf != null;
assert f.isStatic() == otherf.isStatic();
// target class for getter
ClassFile targetClass = f.isStatic() ? vanilla.findClass("client") : other;
// target api class for getter
java.lang.Class targetApiClass = f.isStatic() ? CLIENT_CLASS : implementingClass;
if (targetApiClass == null) {
assert !f.isStatic();
// non static field exported on non exported interface
logger.debug("Non static exported field {} on non exported interface", exportedName);
continue;
}
java.lang.reflect.Method apiMethod = findImportMethodOnApi(targetApiClass, exportedName, true);
if (apiMethod != null) {
Number setter = null;
if (getter != null) {
// inverse getter to get the setter
setter = DMath.modInverse(getter);
}
setters.injectSetter(targetClass, targetApiClass, otherf, exportedName, setter);
}
apiMethod = findImportMethodOnApi(targetApiClass, exportedName, false);
if (apiMethod == null) {
logger.debug("Unable to find import method on api class {} with imported name {}, not injecting getter", targetApiClass, exportedName);
continue;
}
// check that otherf is converable to apiMethod's
// return type
Type fieldType = otherf.getType();
Type returnType = classToType(apiMethod.getReturnType());
if (!validateTypeIsConvertibleTo(fieldType, returnType)) {
throw new InjectionException("Type " + fieldType + " is not convertable to " + returnType + " for getter " + apiMethod);
}
getters.injectGetter(targetClass, apiMethod, otherf, getter);
}
for (Method m : cf.getMethods()) {
hookMethod.process(m);
invokes.process(m, other, implementingClass);
}
}
logger.info("Injected {} getters, {} settters, {} invokers", getters.getInjectedGetters(), setters.getInjectedSetters(), invokes.getInjectedInvokers());
drawAfterWidgets.inject();
scriptVM.inject();
}
Aggregations