From 3b73358183950315f9a68ca3d6e8ecd3beff88aa Mon Sep 17 00:00:00 2001 From: Graham Date: Sun, 29 Mar 2020 12:15:38 +0100 Subject: [PATCH] Improve ClassLiteralTransformer The unsigned client has a Class.forName() method with two differences: * The NoClassDefFoundError is created with a slightly different sequence of instructions. * The arms of the if/else statement for initializing the synthetic field if it is null are swapped. This commit adds support for translating Class.forName() methods with either or both of these differences to the modern LDC form. Signed-off-by: Graham --- .../deob/transform/ClassLiteralTransformer.kt | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/deob/src/main/java/dev/openrs2/deob/transform/ClassLiteralTransformer.kt b/deob/src/main/java/dev/openrs2/deob/transform/ClassLiteralTransformer.kt index 7c8c4a13..4418a69a 100644 --- a/deob/src/main/java/dev/openrs2/deob/transform/ClassLiteralTransformer.kt +++ b/deob/src/main/java/dev/openrs2/deob/transform/ClassLiteralTransformer.kt @@ -58,9 +58,18 @@ class ClassLiteralTransformer : Transformer() { override fun transformCode(classPath: ClassPath, library: Library, clazz: ClassNode, method: MethodNode): Boolean { for (match in CLASS_LITERAL_MATCHER.match(method)) { val getstatic1 = MemberRef(match[0] as FieldInsnNode) - val putstatic = MemberRef(match[5] as FieldInsnNode) - val getstatic2 = MemberRef(match[7] as FieldInsnNode) - val invokestatic = MemberRef(match[3] as MethodInsnNode) + val putstatic: MemberRef + val getstatic2: MemberRef + val invokestatic: MemberRef + if (match[1].opcode == Opcodes.IFNONNULL) { + putstatic = MemberRef(match[5] as FieldInsnNode) + getstatic2 = MemberRef(match[7] as FieldInsnNode) + invokestatic = MemberRef(match[3] as MethodInsnNode) + } else { + putstatic = MemberRef(match[7] as FieldInsnNode) + getstatic2 = MemberRef(match[2] as FieldInsnNode) + invokestatic = MemberRef(match[5] as MethodInsnNode) + } if (getstatic1 != putstatic || putstatic != getstatic2) { continue @@ -78,10 +87,9 @@ class ClassLiteralTransformer : Transformer() { continue } - for ((i, insn) in match.withIndex()) { - if (i == 2) { - val ldc = insn as LdcInsnNode - ldc.cst = Type.getObjectType((ldc.cst as String).toInternalClassName()) + for (insn in match) { + if (insn is LdcInsnNode) { + insn.cst = Type.getObjectType((insn.cst as String).toInternalClassName()) } else { method.instructions.remove(insn) } @@ -103,10 +111,15 @@ class ClassLiteralTransformer : Transformer() { companion object { private val logger = InlineLogger() private val CLASS_FOR_NAME_MATCHER = InsnMatcher.compile( - "^ALOAD INVOKESTATIC ARETURN ASTORE NEW DUP INVOKESPECIAL ALOAD INVOKEVIRTUAL ATHROW$" + """ + ^ALOAD INVOKESTATIC ARETURN + ASTORE NEW DUP (ALOAD INVOKEVIRTUAL INVOKESPECIAL | INVOKESPECIAL ALOAD INVOKEVIRTUAL) ATHROW$ + """ ) + + private const val NULL_ARM = "LDC INVOKESTATIC DUP PUTSTATIC" private val CLASS_LITERAL_MATCHER = InsnMatcher.compile( - "GETSTATIC IFNONNULL LDC INVOKESTATIC DUP PUTSTATIC GOTO GETSTATIC" + "GETSTATIC (IFNONNULL $NULL_ARM GOTO GETSTATIC | IFNULL GETSTATIC GOTO $NULL_ARM)" ) } }