use of org.objectweb.asm.tree.InvokeDynamicInsnNode in project bytecode-viewer by Konloch.
the class AllatoriStringDecrypter method scanMethodNode.
public void scanMethodNode(ClassNode classNode, MethodNode methodNode) throws Exception {
InsnList iList = methodNode.instructions;
log("Scanning method " + methodNode.name + " of " + classNode.name);
LdcInsnNode laststringldconstack = null;
for (AbstractInsnNode i : iList.toArray()) {
if (i instanceof LdcInsnNode) {
LdcInsnNode ldcI = (LdcInsnNode) i;
if (ldcI.cst instanceof String)
laststringldconstack = ldcI;
continue;
} else if (i instanceof MethodInsnNode) {
MethodInsnNode methodI = (MethodInsnNode) i;
// Decryption is always a static call - 0xb8 - invokestatic
if (laststringldconstack != null && methodI.getOpcode() == 0xb8) {
String decrypterClassName = methodI.owner;
String decrypterMethodName = methodI.name;
// Decrypter is always a static method of other class's inner class
if (decrypterClassName.contains("$")) {
byte[] decrypterFileContents = activeContainer.getFileContents(decrypterClassName + ".class");
// We have to create new node for editing
// Also, one decrypter method could be used for multiple methods in code, what gives us only part of string decrypted
ClassNode decrypterClassNode = ASMUtil.bytesToNode(decrypterFileContents);
MethodNode decryptermethodnode = ASMUtil.getMethodByName(decrypterClassNode, decrypterMethodName);
if (decryptermethodnode != null) {
String keyString = (getConstantPoolSize(classNode.name) + classNode.name + methodNode.name + getConstantPoolSize(classNode.name));
int newHashCode = keyString.hashCode();
scanDecrypter(decryptermethodnode, newHashCode);
try {
System.out.println("Loading " + decrypterClassName);
Class<?> decrypterClassList = BCV.loadClassIntoClassLoader(decrypterClassNode);
String decrypted = invokeDecrypter(decrypterClassList, decrypterMethodName, (String) laststringldconstack.cst);
if (decrypted != null) {
log("Succesfully invoked decrypter method: " + decrypted);
laststringldconstack.cst = decrypted;
iList.remove(methodI);
}
} catch (IndexOutOfBoundsException | ClassNotFoundException | IOException e) {
e.printStackTrace();
log("Could not load decrypter class: " + decrypterClassName);
}
} else {
log("Could not find decrypter method (" + decrypterMethodName + ") of class " + decrypterClassName);
}
}
}
} else if (i instanceof InvokeDynamicInsnNode) {
InvokeDynamicInsnNode methodi = (InvokeDynamicInsnNode) i;
if (methodi.getOpcode() == 0xba) {
// TODO: Safe-reflection deobfuscator here
// Allatori replaces invokeinterface and invokestatic with invokedynamic
// log(methodi.bsm.getOwner()+" dot "+methodi.bsm.getName());
// iList.set(methodi, new MethodInsnNode(0xb8, methodi.bsm.getOwner(), methodi.bsm.getName(), methodi.bsm.getDesc(), false));
}
}
laststringldconstack = null;
}
}
Aggregations