|
2 | 2 |
|
3 | 3 | import org.objectweb.asm.Opcodes; |
4 | 4 | import org.objectweb.asm.tree.AbstractInsnNode; |
| 5 | +import org.objectweb.asm.tree.ClassNode; |
5 | 6 | import org.objectweb.asm.tree.InvokeDynamicInsnNode; |
6 | 7 | import org.objectweb.asm.tree.LdcInsnNode; |
7 | 8 | import org.objectweb.asm.tree.LookupSwitchInsnNode; |
@@ -42,6 +43,8 @@ protected void transform() throws Exception { |
42 | 43 | // Decrypt the method invocation |
43 | 44 | AbstractInsnNode decryptedInsn = decryptMethodInvocation(xorKey, encryptedData, decryptionInfo); |
44 | 45 | methodNode.instructions.set(invokeDynamicInsn, decryptedInsn); |
| 46 | + |
| 47 | + markChange(); |
45 | 48 | } |
46 | 49 | } |
47 | 50 | }); |
@@ -95,7 +98,7 @@ private DecryptionInfo extractDecryptionInformation(InvokeDynamicInsnNode invoke |
95 | 98 | * @param decryptionInfo Decryption information |
96 | 99 | * @return Decrypted method invocation instruction |
97 | 100 | */ |
98 | | - private static AbstractInsnNode decryptMethodInvocation(String xorKey, String encryptedData, DecryptionInfo decryptionInfo) { |
| 101 | + private AbstractInsnNode decryptMethodInvocation(String xorKey, String encryptedData, DecryptionInfo decryptionInfo) { |
99 | 102 | char[] xorKeyArr = xorKey.toCharArray(); |
100 | 103 |
|
101 | 104 | // Decrypt the data using XOR cipher |
@@ -133,7 +136,21 @@ private static AbstractInsnNode decryptMethodInvocation(String xorKey, String en |
133 | 136 | } |
134 | 137 |
|
135 | 138 | int opcode = decryptionInfo.invocationTypes().get(methodType); |
136 | | - return new MethodInsnNode(opcode, opcode == INVOKESPECIAL ? specialClass : ownerClass, methodName, methodDesc, false); |
| 139 | + |
| 140 | + // Handle special case where we cannot determine if it is INVOKEVIRTUAL or INVOKEINTERFACE |
| 141 | + if (opcode == INVOKEVIRTUAL) { |
| 142 | + ClassNode classInfo = context().getFullClassProvider().getClassInfo(ownerClass); |
| 143 | + if (classInfo != null) { |
| 144 | + // Check if class is an interface |
| 145 | + if (isAccess(classInfo.access, ACC_INTERFACE)) { |
| 146 | + opcode = INVOKEINTERFACE; |
| 147 | + } |
| 148 | + } else { |
| 149 | + LOGGER.warn("Could not find class {} for class/interface type detection. If you want a runnable jar then add the required lib.", ownerClass); |
| 150 | + } |
| 151 | + } |
| 152 | + |
| 153 | + return new MethodInsnNode(opcode, opcode == INVOKESPECIAL ? specialClass : ownerClass, methodName, methodDesc, opcode == INVOKEINTERFACE); |
137 | 154 | } |
138 | 155 |
|
139 | 156 | /** |
|
0 commit comments