From 5bf228d9355decd70d2917cf8539b8add7a6735a Mon Sep 17 00:00:00 2001 From: EpicPlayerA10 Date: Wed, 25 Sep 2024 23:22:01 +0200 Subject: [PATCH] use findAllMatches wherever was possible --- .../ZelixLongEncryptionMPCTransformer.java | 109 +++++++++--------- .../impl/zkm/ZelixParametersTransformer.java | 29 ++--- 2 files changed, 62 insertions(+), 76 deletions(-) diff --git a/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/zkm/ZelixLongEncryptionMPCTransformer.java b/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/zkm/ZelixLongEncryptionMPCTransformer.java index fabded68..70420741 100644 --- a/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/zkm/ZelixLongEncryptionMPCTransformer.java +++ b/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/zkm/ZelixLongEncryptionMPCTransformer.java @@ -147,68 +147,63 @@ private void decryptEncryptedLongs(Context context, ClassWrapper classWrapper) { MethodContext methodContext = MethodContext.framed(classWrapper, clinit); - for (AbstractInsnNode insn : clinit.instructions) { - InsnContext insnContext = methodContext.newInsnContext(insn); - if (insnContext.frame() == null) return; - - MatchContext result = DECRYPT_LONG_MATCHER.matchResult(insnContext); - if (result != null) { - // Get instructions from storage - MethodInsnNode createDecrypterInsn = (MethodInsnNode) result.captures().get("create-decrypter-method").insn(); - MatchContext decryptContext = result.captures().get("decrypt-method"); - MethodInsnNode decryptInsn = (MethodInsnNode) decryptContext.insn(); - - // Some keys - long key1 = result.captures().get("key-1").insn().asLong(); - long key2 = result.captures().get("key-2").insn().asLong(); - long decryptKey = result.captures().get("decrypt-key").insn().asLong(); + // Find all encrypted longs + DECRYPT_LONG_MATCHER.findAllMatches(methodContext).forEach(matchContext -> { + // Get instructions from storage + MethodInsnNode createDecrypterInsn = (MethodInsnNode) matchContext.captures().get("create-decrypter-method").insn(); + MatchContext decryptContext = matchContext.captures().get("decrypt-method"); + MethodInsnNode decryptInsn = (MethodInsnNode) decryptContext.insn(); + + // Some keys + long key1 = matchContext.captures().get("key-1").insn().asLong(); + long key2 = matchContext.captures().get("key-2").insn().asLong(); + long decryptKey = matchContext.captures().get("decrypt-key").insn().asLong(); + + ClassWrapper longDecrypterCreatorClass = context.getClasses().get(createDecrypterInsn.owner); + + try { + // Create decrypter + InstanceClass clazz = sandBox.getHelper().loadClass(longDecrypterCreatorClass.canonicalName()); + ObjectValue longDecrypterInstance = sandBox.getInvocationUtil().invokeReference( + clazz.getMethod(createDecrypterInsn.name, createDecrypterInsn.desc), + Argument.int64(key1), // Key 1 + Argument.int64(key2), // Key 2 + Argument.reference(sandBox.getMemoryManager().nullValue()) // Lookup class + ); + InstanceClass longDecrypterClass = (InstanceClass) sandBox.getMemoryManager().readClass(longDecrypterInstance); - ClassWrapper longDecrypterCreatorClass = context.getClasses().get(createDecrypterInsn.owner); + //String instanceStringified = sandBox.vm().getOperations().toString(longDecrypterInstance); + //System.out.println(classWrapper.name() + " -> " + instanceStringified); - try { - // Create decrypter - InstanceClass clazz = sandBox.getHelper().loadClass(longDecrypterCreatorClass.canonicalName()); - ObjectValue longDecrypterInstance = sandBox.getInvocationUtil().invokeReference( - clazz.getMethod(createDecrypterInsn.name, createDecrypterInsn.desc), - Argument.int64(key1), // Key 1 - Argument.int64(key2), // Key 2 - Argument.reference(sandBox.getMemoryManager().nullValue()) // Lookup class - ); - InstanceClass longDecrypterClass = (InstanceClass) sandBox.getMemoryManager().readClass(longDecrypterInstance); - - //String instanceStringified = sandBox.vm().getOperations().toString(longDecrypterInstance); - //System.out.println(classWrapper.name() + " -> " + instanceStringified); - - if (isFallbackDecrypter(longDecrypterClass)) { - LOGGER.error("Detected that '{}' class is decrypted out of order. Decrypted number will have wrong value.", classWrapper.name()); - LOGGER.error("The author used 'classInitializationOrderStatement' (https://www.zelix.com/klassmaster/docs/classInitializationOrderStatement.html) " + - "during jar obfuscation to specify class initialization order manually. " + - "You need to pass to ZelixLongEncryptionMPCTransformer a class initialization order. The easiest way wille be doing a static analysis " + - "and find where the mentioned class is used." - ); - } - - // Decrypt long value - long value = sandBox.getInvocationUtil().invokeLong( - longDecrypterClass.getMethod(decryptInsn.name, decryptInsn.desc), - Argument.reference(longDecrypterInstance), - Argument.int64(decryptKey) + if (isFallbackDecrypter(longDecrypterClass)) { + LOGGER.error("Detected that '{}' class is decrypted out of order. Decrypted number will have wrong value.", classWrapper.name()); + LOGGER.error("The author used 'classInitializationOrderStatement' (https://www.zelix.com/klassmaster/docs/classInitializationOrderStatement.html) " + + "during jar obfuscation to specify class initialization order manually. " + + "You need to pass to ZelixLongEncryptionMPCTransformer a class initialization order. The easiest way wille be doing a static analysis " + + "and find where the mentioned class is used." ); - - // Remove all instructions that creates decrypter - decryptContext.removeAll(); - - // Set field to decrypted long value! - insnContext.methodNode().instructions.insertBefore(insnContext.insn(), AsmHelper.numberInsn(value)); - markChange(); - } catch (VMException ex) { - sandBox.logVMException(ex); - throw new RuntimeException(ex); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); } + + // Decrypt long value + long value = sandBox.getInvocationUtil().invokeLong( + longDecrypterClass.getMethod(decryptInsn.name, decryptInsn.desc), + Argument.reference(longDecrypterInstance), + Argument.int64(decryptKey) + ); + + // Remove all instructions that create decrypter + decryptContext.removeAll(); + + // Set field to decrypted long value! + matchContext.insnContext().methodNode().instructions.insertBefore(matchContext.insn(), AsmHelper.numberInsn(value)); + markChange(); + } catch (VMException ex) { + sandBox.logVMException(ex); + throw new RuntimeException(ex); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); } - } + }); processedClasses.add(classWrapper.name()); } diff --git a/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/zkm/ZelixParametersTransformer.java b/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/zkm/ZelixParametersTransformer.java index 5dd1e015..eeefd634 100644 --- a/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/zkm/ZelixParametersTransformer.java +++ b/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/zkm/ZelixParametersTransformer.java @@ -25,6 +25,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; /** * Decomposes object array param ({@code foo(Object[] args)}) into a readable params like: {@code foo(String arg1, int arg2)}. @@ -122,12 +123,7 @@ private List decomposeObjectArrayToTypes(MethodContext methodContext, Map< int nextVarIndex = MethodHelper.getFirstParameterIdx(methodContext.methodNode()); // Find all casts from that Object array - for (AbstractInsnNode insn : methodContext.methodNode().instructions.toArray()) { - InsnContext insnContext = methodContext.newInsnContext(insn); - - MatchContext matchContext = OBJECT_ARRAY_VAR_USAGE.matchResult(insnContext); - if (matchContext == null) continue; - + for (MatchContext matchContext : OBJECT_ARRAY_VAR_USAGE.findAllMatches(methodContext)) { // Found argument! VarInsnNode varStore = (VarInsnNode) matchContext.captures().get("var-store").insn(); TypeInsnNode typeInsn = (TypeInsnNode) matchContext.captures().get("cast").insn(); @@ -169,22 +165,17 @@ private List decomposeObjectArrayToTypes(MethodContext methodContext, Map< */ private boolean removeObjectArrayAccess(MethodContext methodContext) { // Remove all object array accesses - for (AbstractInsnNode insn : methodContext.methodNode().instructions.toArray()) { - InsnContext insnContext = methodContext.newInsnContext(insn); - - MatchContext matchContext = OBJECT_ARRAY_POP.matchResult(insnContext); - if (matchContext == null) continue; + Optional optMatch = OBJECT_ARRAY_POP.findAllMatches(methodContext).stream().findFirst(); + if (optMatch.isEmpty()) return false; + MatchContext matchContext = optMatch.get(); - AbstractInsnNode loadArrayInsn = matchContext.captures().get("load-array").insn(); + AbstractInsnNode loadArrayInsn = matchContext.captures().get("load-array").insn(); - // Remove those instructions - methodContext.methodNode().instructions.remove(loadArrayInsn); // ALOAD - methodContext.methodNode().instructions.remove(insn); // POP - - return true; - } + // Remove those instructions + methodContext.methodNode().instructions.remove(loadArrayInsn); // ALOAD + methodContext.methodNode().instructions.remove(matchContext.insn()); // POP - return false; + return true; } /**