diff --git a/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/composed/ComposedSkidTransformer.java b/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/composed/ComposedSkidTransformer.java index 1983ef4d..a8456917 100644 --- a/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/composed/ComposedSkidTransformer.java +++ b/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/composed/ComposedSkidTransformer.java @@ -6,6 +6,7 @@ import uwu.narumi.deobfuscator.core.other.impl.pool.InlineLocalVariablesTransformer; import uwu.narumi.deobfuscator.core.other.impl.pool.InlineStaticFieldTransformer; import uwu.narumi.deobfuscator.core.other.impl.skidfuscator.*; +import uwu.narumi.deobfuscator.core.other.impl.universal.StringBuilderTransformer; import uwu.narumi.deobfuscator.core.other.impl.universal.UniversalFlowTransformer; import uwu.narumi.deobfuscator.core.other.impl.universal.UniversalNumberTransformer; @@ -38,7 +39,8 @@ public ComposedSkidTransformer() { ) ), SkidStringTransformer::new, - SkidCleanTransformer::new + SkidCleanTransformer::new, + StringBuilderTransformer::new /* Sometimes SkidFuscator replaces concat's with StringBuilder for "optimization" */ ); } } diff --git a/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/skidfuscator/SkidFlowTransformer.java b/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/skidfuscator/SkidFlowTransformer.java index a14d0276..1b8b709f 100644 --- a/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/skidfuscator/SkidFlowTransformer.java +++ b/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/skidfuscator/SkidFlowTransformer.java @@ -60,9 +60,9 @@ protected void transform() throws Exception { }); /** Example - * ldc 952006311 - * invokestatic ikjlkypytwnvkuzi/erfobcthglyygbhq.jwmyqfvhltjhsidh (I)I - * */ + * ldc 952006311 + * invokestatic ikjlkypytwnvkuzi/erfobcthglyygbhq.jwmyqfvhltjhsidh (I)I + * */ staticDecryption.findAllMatches(methodContext).forEach(matchContext -> { MethodInsnNode methodInsnNode = matchContext.captures().get("predicate-method").insn().asMethodInsn(); AbstractInsnNode salt = matchContext.captures().get("salt").insn(); @@ -76,10 +76,12 @@ protected void transform() throws Exception { JumpMatch.of().capture("jump").findAllMatches(methodContext).forEach(matchContext -> { JumpInsnNode jumpInsnNode = matchContext.captures().get("jump").insn().asJump(); if (jumpInsnNode.label.getNext() instanceof LdcInsnNode intLdc && jumpInsnNode.label.getNext(2) instanceof VarInsnNode varStore && jumpInsnNode.label.getNext(3) instanceof JumpInsnNode jump1) { + if (blessedJumpLabels.contains(jump1.label)) return; methodNode.instructions.remove(varStore); methodNode.instructions.remove(intLdc); methodNode.instructions.insert(jump1.label, varStore); methodNode.instructions.insert(jump1.label, intLdc); + blessedJumpLabels.add(jump1.label); markChange(); } LdcInsnNode lastLdcOfLabel = null; @@ -95,45 +97,49 @@ protected void transform() throws Exception { setVarJump.findAllMatches(methodContext).forEach(matchContext1 -> { if (finalLastLdcOfLabel.cst instanceof Integer && matchContext1.captures().get("salt1").insn().asInteger() == (int) finalLastLdcOfLabel.cst) { VarInsnNode var = (VarInsnNode) matchContext1.captures().get("var").insn(); + LabelNode blessedLabel = matchContext1.captures().get("jump").insn().asJump().label; + if (blessedJumpLabels.contains(blessedLabel)) return; methodNode.instructions.insert(matchContext1.captures().get("jump").insn().asJump().label, new VarInsnNode(ISTORE, var.var)); methodNode.instructions.insert(matchContext1.captures().get("jump").insn().asJump().label, new LdcInsnNode(finalLastLdcOfLabel.cst)); + blessedJumpLabels.add(blessedLabel); } }); } }); if (!isChanged()) { - MatchContext matchContext = SequenceMatch.of(NumberMatch.numInteger().capture("hash"), OpcodeMatch.of(ISTORE).capture("param"), Match.of(ctx -> ctx.insn() instanceof LabelNode).capture("label")).doNotSkipLabels().findFirstMatch(methodContext); - if (matchContext != null) { - int salt = matchContext.captures().get("hash").insn().asInteger(); - int param = ((VarInsnNode)matchContext.captures().get("param").insn()).var; - LabelNode label = (LabelNode) matchContext.captures().get("label").insn(); - if (label.getNext() instanceof JumpInsnNode jumpInsnNode) label = jumpInsnNode.label; - if (blessedLabels.contains(label)) return; - LabelNode finalLabel = label; - methodNode.tryCatchBlocks.forEach(tcb -> { - if (finalLabel.equals(tcb.start) || finalLabel.equals(tcb.handler) || finalLabel.equals(tcb.end)) { - methodNode.instructions.insert(tcb.start, new VarInsnNode(ISTORE, param)); - methodNode.instructions.insert(tcb.start, new LdcInsnNode(salt)); - methodNode.instructions.insert(tcb.handler, new VarInsnNode(ISTORE, param)); - methodNode.instructions.insert(tcb.handler, new LdcInsnNode(salt)); - methodNode.instructions.insert(tcb.end, new VarInsnNode(ISTORE, param)); - methodNode.instructions.insert(tcb.end, new LdcInsnNode(salt)); - blessedLabels.add(tcb.start); - blessedLabels.add(tcb.handler); - blessedLabels.add(tcb.end); - } - }); - methodNode.instructions.insert(label, new VarInsnNode(ISTORE, param)); - methodNode.instructions.insert(label, new LdcInsnNode(salt)); - markChange(); - blessedLabels.add(label); - } + MatchContext matchContext = SequenceMatch.of(NumberMatch.numInteger().capture("hash"), OpcodeMatch.of(ISTORE).capture("param"), Match.of(ctx -> ctx.insn() instanceof LabelNode).capture("label")).doNotSkipLabels().findFirstMatch(methodContext); + if (matchContext != null) { + int salt = matchContext.captures().get("hash").insn().asInteger(); + int param = ((VarInsnNode)matchContext.captures().get("param").insn()).var; + LabelNode label = (LabelNode) matchContext.captures().get("label").insn(); + if (label.getNext() instanceof JumpInsnNode jumpInsnNode) label = jumpInsnNode.label; + if (blessedLabels.contains(label)) return; + LabelNode finalLabel = label; + methodNode.tryCatchBlocks.forEach(tcb -> { + if (finalLabel.equals(tcb.start) || finalLabel.equals(tcb.handler) || finalLabel.equals(tcb.end)) { + methodNode.instructions.insert(tcb.start, new VarInsnNode(ISTORE, param)); + methodNode.instructions.insert(tcb.start, new LdcInsnNode(salt)); + methodNode.instructions.insert(tcb.handler, new VarInsnNode(ISTORE, param)); + methodNode.instructions.insert(tcb.handler, new LdcInsnNode(salt)); + methodNode.instructions.insert(tcb.end, new VarInsnNode(ISTORE, param)); + methodNode.instructions.insert(tcb.end, new LdcInsnNode(salt)); + blessedLabels.add(tcb.start); + blessedLabels.add(tcb.handler); + blessedLabels.add(tcb.end); + } + }); + methodNode.instructions.insert(label, new VarInsnNode(ISTORE, param)); + methodNode.instructions.insert(label, new LdcInsnNode(salt)); + markChange(); + blessedLabels.add(label); + } } })); } private final static Set blessedLabels = new HashSet<>(); + private final static Set blessedJumpLabels = new HashSet<>(); public int m1(int n) { if (n != 0) { @@ -145,4 +151,4 @@ public int m1(int n) { public int m2_m3(int n) { return (n & 0xE0000000) >> 29 | n << 3; } -} +} \ No newline at end of file