use of net.runelite.asm.pool.Class in project runelite by runelite.
the class DupDeobfuscatorTest method test2.
// 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 = { // this
new AConstNull(ins), // this this
new Dup(ins), new GetField(ins, new Field(new Class("test"), "field", Type.INT)), // this this I I
new LDC(ins, 830083863), // this this I
new IMul(ins), new LDC(ins, 830083863), new IAdd(ins), new Dup_X1(ins), new LDC(ins, 636900519), // pops dup
new IMul(ins), 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);
}
use of net.runelite.asm.pool.Class 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();
}
use of net.runelite.asm.pool.Class in project runelite by runelite.
the class Inject method injectInterface.
private java.lang.Class injectInterface(ClassFile cf, ClassFile other) {
Annotations an = cf.getAnnotations();
if (an == null) {
return null;
}
Annotation a = an.find(DeobAnnotations.IMPLEMENTS);
if (a == null) {
return null;
}
String ifaceName = API_PACKAGE_BASE + a.getElement().getString();
java.lang.Class<?> apiClass;
try {
apiClass = java.lang.Class.forName(ifaceName);
} catch (ClassNotFoundException ex) {
logger.trace("Class {} implements nonexistent interface {}, skipping interface injection", cf.getName(), ifaceName);
return null;
}
// to internal name
String ifaceNameInternal = ifaceName.replace('.', '/');
Class clazz = new Class(ifaceNameInternal);
Interfaces interfaces = other.getInterfaces();
interfaces.addInterface(clazz);
return apiClass;
}
use of net.runelite.asm.pool.Class in project runelite by runelite.
the class Exceptions method renameClass.
public void renameClass(ClassFile cf, String name) {
for (Class c : new ArrayList<>(classes)) {
if (c.getName().equals(cf.getName())) {
int idx = classes.indexOf(c);
classes.remove(idx);
classes.add(idx, new Class(name));
}
}
}
use of net.runelite.asm.pool.Class in project runelite by runelite.
the class GetField method getMyField.
@Override
public net.runelite.asm.Field getMyField() {
Class clazz = field.getClazz();
ClassFile cf = this.getInstructions().getCode().getMethod().getClassFile().getGroup().findClass(clazz.getName());
if (cf == null) {
return null;
}
net.runelite.asm.Field f2 = cf.findFieldDeep(field.getName(), field.getType());
return f2;
}
Aggregations