diff --git a/deobfuscator-api/src/main/java/uwu/narumi/deobfuscator/api/asm/matcher/Match.java b/deobfuscator-api/src/main/java/uwu/narumi/deobfuscator/api/asm/matcher/Match.java index 5872ecbe..cbbdc081 100644 --- a/deobfuscator-api/src/main/java/uwu/narumi/deobfuscator/api/asm/matcher/Match.java +++ b/deobfuscator-api/src/main/java/uwu/narumi/deobfuscator/api/asm/matcher/Match.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.function.Predicate; /** @@ -72,6 +73,10 @@ public MatchContext findFirstMatch(MethodContext methodContext) { return this.findAllMatches(methodContext).stream().findFirst().orElse(null); } + public Optional findAny(MethodContext methodContext) { + return this.findAllMatches(methodContext).stream().findAny(); + } + /** * @return {@link MatchContext} if matches or {@code null} if it does not match */ diff --git a/deobfuscator-api/src/main/java/uwu/narumi/deobfuscator/api/helper/AsmHelper.java b/deobfuscator-api/src/main/java/uwu/narumi/deobfuscator/api/helper/AsmHelper.java index c154c5c2..8970f092 100644 --- a/deobfuscator-api/src/main/java/uwu/narumi/deobfuscator/api/helper/AsmHelper.java +++ b/deobfuscator-api/src/main/java/uwu/narumi/deobfuscator/api/helper/AsmHelper.java @@ -141,6 +141,26 @@ public static AbstractInsnNode toPop(Value value) { return value.getSize() == 1 ? new InsnNode(POP) : new InsnNode(POP2); } + public boolean isInsnInLabelRange(MethodNode method, LabelNode startLabel, AbstractInsnNode insn) { + InsnList instructions = method.instructions; + + int startIndex = instructions.indexOf(startLabel); + if (startIndex == -1) return false; + + int insnIndex = instructions.indexOf(insn); + if (insnIndex == -1) return false; + + int endIndex = instructions.size(); + for (int i = startIndex + 1; i < instructions.size(); i++) { + if (instructions.get(i) instanceof LabelNode) { + endIndex = i; + break; + } + } + + return insnIndex > startIndex && insnIndex < endIndex; + } + /** * Update method descriptor in the current class, a superclass and interfaces * diff --git a/deobfuscator-impl/src/test/java/uwu/narumi/deobfuscator/TestDeobfuscation.java b/deobfuscator-impl/src/test/java/uwu/narumi/deobfuscator/TestDeobfuscation.java index b192baff..8dee30f3 100644 --- a/deobfuscator-impl/src/test/java/uwu/narumi/deobfuscator/TestDeobfuscation.java +++ b/deobfuscator-impl/src/test/java/uwu/narumi/deobfuscator/TestDeobfuscation.java @@ -239,5 +239,10 @@ protected void registerAll() { .transformers(ComposedGuardProtectorTransformer::new) .inputClass(InputType.CUSTOM_CLASS, "guardprotector/Class951.class") .register(); + + test("SkidFuscator 2.0.11 - Pure hash encryption") + .transformers(ComposedSkidTransformer::new) + .inputJar("skidfuscator.jar") + .register(); } } 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 new file mode 100644 index 00000000..1983ef4d --- /dev/null +++ b/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/composed/ComposedSkidTransformer.java @@ -0,0 +1,44 @@ +package uwu.narumi.deobfuscator.core.other.composed; + +import uwu.narumi.deobfuscator.api.transformer.ComposedTransformer; +import uwu.narumi.deobfuscator.core.other.composed.general.ComposedGeneralFlowTransformer; +import uwu.narumi.deobfuscator.core.other.impl.clean.peephole.*; +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.UniversalFlowTransformer; +import uwu.narumi.deobfuscator.core.other.impl.universal.UniversalNumberTransformer; + +/** + * SkidFuscator 2.0.11 Community version + * https://github.com/skidfuscatordev/skidfuscator-java-obfuscator + */ +public class ComposedSkidTransformer extends ComposedTransformer { + + public ComposedSkidTransformer() { + super( + UniversalNumberTransformer::new, + SkidNumberTransformer::new, + SkidTryCatchRemoveTransformer::new, + ComposedGeneralFlowTransformer::new, + InlineStaticFieldTransformer::new, + () -> new ComposedTransformer(true, + InlineLocalVariablesTransformer::new, /* Passthrough Hash */ + SkidFlowTransformer::new, /* Resolve SkidFuscator's Flow */ + + UniversalFlowTransformer::new, /* Solve SkidFuscator's Switches/Jumps */ + + NopCleanTransformer::new, + UnUsedLabelCleanTransformer::new, + UselessGotosCleanTransformer::new, + + () -> new ComposedTransformer(true, + PopUnUsedLocalVariablesTransformer::new, + UselessPopCleanTransformer::new + ) + ), + SkidStringTransformer::new, + SkidCleanTransformer::new + ); + } +} diff --git a/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/branchlock/BranchlockCompabilityStringTransformer.java b/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/branchlock/BranchlockCompabilityStringTransformer.java index 8cdcccaa..1dcd6df0 100644 --- a/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/branchlock/BranchlockCompabilityStringTransformer.java +++ b/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/branchlock/BranchlockCompabilityStringTransformer.java @@ -248,24 +248,4 @@ public LabelNode getLabelByKey(TableSwitchInsnNode tsi, int key) { int index = key - tsi.min; return tsi.labels.get(index); } - - public boolean isInsnInLabelRange(MethodNode method, LabelNode startLabel, AbstractInsnNode insn) { - InsnList instructions = method.instructions; - - int startIndex = instructions.indexOf(startLabel); - if (startIndex == -1) return false; - - int insnIndex = instructions.indexOf(insn); - if (insnIndex == -1) return false; - - int endIndex = instructions.size(); - for (int i = startIndex + 1; i < instructions.size(); i++) { - if (instructions.get(i) instanceof LabelNode) { - endIndex = i; - break; - } - } - - return insnIndex > startIndex && insnIndex < endIndex; - } } diff --git a/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/guardprotector/GuardProtectorFlowTransformer.java b/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/guardprotector/GuardProtectorFlowTransformer.java index e575a40f..6734f580 100644 --- a/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/guardprotector/GuardProtectorFlowTransformer.java +++ b/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/guardprotector/GuardProtectorFlowTransformer.java @@ -32,8 +32,7 @@ protected void transform() throws Exception { flowVarStore.findAllMatches(methodContext).forEach(varStore -> { FieldInsnNode fieldInsn = varStore.captures().get("stored-type").insn().asFieldInsn(); if (!hasPutStatic(classWrapper.classNode(), fieldInsn)) { -// FieldRef fieldRef = FieldRef.of(fieldInsn); //This doesn`t work. Fields are still present in classes (maybe because they are private static final) -// context().removeField(fieldRef); + classWrapper.fields().removeIf(fieldNode -> fieldNode.name.equals(fieldInsn.name) && fieldNode.desc.equals(fieldInsn.desc)); boolean ifNeJump = fieldInsn.desc.equals("Z"); int varIndex = ((VarInsnNode) varStore.captures().get("stored-var").insn()).var; toRemove.addAll(varStore.collectedInsns()); @@ -41,16 +40,7 @@ protected void transform() throws Exception { int loadedVarIndex = ((VarInsnNode) jumpEquation.captures().get("loaded-var").insn()).var; JumpInsnNode jump = jumpEquation.captures().get("stored-jump").insn().asJump(); if ((ifNeJump && jump.getOpcode() == IFNE) || (!ifNeJump && jump.getOpcode() == IFEQ) && varIndex == loadedVarIndex) { -// if (jump.label != null) { -// toRemove.add(jump.label); -// markChange(); -// methodNode.instructions.forEach(insn -> { -// if (isInsnInLabelRange(methodNode, jump.label, insn)) { -// toRemove.add(insn); -// } -// }); -// } - methodNode.instructions.insert(jump, new JumpInsnNode(GOTO, jump.label)); + //methodNode.instructions.insert(jump, new JumpInsnNode(GOTO, jump.label)); toRemove.addAll(jumpEquation.collectedInsns()); markChange(); } @@ -79,26 +69,6 @@ protected void transform() throws Exception { })); } - public boolean isInsnInLabelRange(MethodNode method, LabelNode startLabel, AbstractInsnNode insn) { - InsnList instructions = method.instructions; - - int startIndex = instructions.indexOf(startLabel); - if (startIndex == -1) return false; - - int insnIndex = instructions.indexOf(insn); - if (insnIndex == -1) return false; - - int endIndex = instructions.size(); - for (int i = startIndex + 1; i < instructions.size(); i++) { - if (instructions.get(i) instanceof LabelNode) { - endIndex = i; - break; - } - } - - return insnIndex > startIndex && insnIndex < endIndex; - } - boolean hasPutStatic(ClassNode classNode, FieldInsnNode target) { for (MethodNode method : classNode.methods) { for (AbstractInsnNode insn : method.instructions) { diff --git a/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/skidfuscator/SkidCleanTransformer.java b/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/skidfuscator/SkidCleanTransformer.java new file mode 100644 index 00000000..01a99435 --- /dev/null +++ b/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/skidfuscator/SkidCleanTransformer.java @@ -0,0 +1,124 @@ +package uwu.narumi.deobfuscator.core.other.impl.skidfuscator; + +import org.objectweb.asm.tree.AbstractInsnNode; +import org.objectweb.asm.tree.VarInsnNode; +import uwu.narumi.deobfuscator.api.asm.ClassWrapper; +import uwu.narumi.deobfuscator.api.asm.FieldRef; +import uwu.narumi.deobfuscator.api.asm.MethodContext; +import uwu.narumi.deobfuscator.api.asm.matcher.Match; +import uwu.narumi.deobfuscator.api.asm.matcher.group.SequenceMatch; +import uwu.narumi.deobfuscator.api.asm.matcher.impl.FieldMatch; +import uwu.narumi.deobfuscator.api.asm.matcher.impl.MethodMatch; +import uwu.narumi.deobfuscator.api.asm.matcher.impl.NumberMatch; +import uwu.narumi.deobfuscator.api.asm.matcher.impl.OpcodeMatch; +import uwu.narumi.deobfuscator.api.transformer.Transformer; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class SkidCleanTransformer extends Transformer { + + /** + * Useless storing vars: + * getstatic java/lang/System.out Ljava/io/PrintStream; + * astore v29 - useless + * invokestatic pack/tests/basics/accu/Digi.hwahaewjduusqug ()[B + * iload i39 + * invokestatic pack/tests/basics/accu/Digi.shmyiqcznk ([BI)Ljava/lang/String; + * astore v36 - useless + * aload v29 - useless + * aload v36 - useless + * invokevirtual java/io/PrintStream.println (Ljava/lang/String;)V + */ + Match uselessStoring = SequenceMatch.of( + Match.of(ctx -> true), + OpcodeMatch.of(ASTORE).capture("store-1"), + OpcodeMatch.of(LDC), + OpcodeMatch.of(ASTORE).capture("store-2"), + OpcodeMatch.of(ALOAD).capture("load-1"), + OpcodeMatch.of(ALOAD).capture("load-2"), + MethodMatch.create() + ); + + @Override + protected void transform() throws Exception { + /* Delete static decryption class */ + ClassWrapper decryptStaticClass = scopedClasses().stream().filter(classWrapper -> classWrapper.name().length() == 33 && (classWrapper.methods().size() == 3 || classWrapper.methods().size() == 2) && classWrapper.methods().stream().map(methodNode -> methodNode.desc).allMatch(desc -> desc.equals("(I)I"))).findFirst().get(); + context().getClassesMap().remove(decryptStaticClass.name()); + scopedClasses().forEach(classWrapper -> { + /* Clean ASCII aheagos/etc */ + findClInit(classWrapper.classNode()).ifPresent(clinit -> { + AbstractInsnNode firstInsn = clinit.instructions.getFirst(); + boolean hasASCII = false; + while (firstInsn.getNext() != null) { + if (firstInsn.isInteger() && firstInsn.getNext().getOpcode() == ANEWARRAY && firstInsn.getNext(2).isFieldInsn() && firstInsn.getNext(2).asFieldInsn().name.equalsIgnoreCase("nothing_to_see_here")) { + hasASCII = true; + break; + } + firstInsn = firstInsn.getNext(); + } + + Set toRemove = new HashSet<>(); + if (hasASCII) { + toRemove.add(firstInsn); + toRemove.add(firstInsn.getNext()); + toRemove.add(firstInsn.getNext(2)); + firstInsn = firstInsn.getNext(3); + while (firstInsn != null && firstInsn.getOpcode() == GETSTATIC && firstInsn.getNext() != null && firstInsn.getNext().isInteger() && firstInsn.getNext(2) != null && firstInsn.getNext(2).isString() && firstInsn.getNext(3) != null && firstInsn.getNext(3).getOpcode() == AASTORE) { + toRemove.add(firstInsn); + toRemove.add(firstInsn.getNext()); + toRemove.add(firstInsn.getNext(2)); + toRemove.add(firstInsn.getNext(3)); + firstInsn = firstInsn.getNext(4); + } + toRemove.forEach(clinit.instructions::remove); + classWrapper.fields().removeIf(fieldNode -> fieldNode.name.equals("nothing_to_see_here") && fieldNode.desc.equals("[Ljava/lang/String;")); + markChange(); + } + }); + + /* Clear hash-int */ + classWrapper.fields().removeIf(fieldNode -> { + boolean matchField = isAccess(fieldNode.access, ACC_PRIVATE, ACC_TRANSIENT) && fieldNode.desc.equals("I"); + if (matchField) { + classWrapper.methods().forEach(methodNode1 -> { + if (methodNode1.name.equals("")) { + SequenceMatch.of( + NumberMatch.of(), + FieldMatch.putField().fieldRef(FieldRef.of(classWrapper.classNode(), fieldNode)) + ).findAny(MethodContext.of(classWrapper, methodNode1)).ifPresent(matchContext -> { + matchContext.removeAll(); + markChange(); + }); + } + }); + } + return matchField; + }); + + /* Clear self-class-xor from flow-obfuscation */ + classWrapper.methods().removeIf(methodNode -> methodNode.name.length() == 16 && isAccess(methodNode.access, ACC_PRIVATE, ACC_STATIC) && methodNode.desc.equals("(II)I") && methodNode.instructions.size() == 4); + + classWrapper.methods().forEach(methodNode -> { + MethodContext methodContext = MethodContext.of(classWrapper, methodNode); + + uselessStoring.findAllMatches(methodContext).forEach(matchContext -> { + VarInsnNode store1 = (VarInsnNode) matchContext.captures().get("store-1").insn(); + VarInsnNode store2 = (VarInsnNode) matchContext.captures().get("store-2").insn(); + VarInsnNode load1 = (VarInsnNode) matchContext.captures().get("load-1").insn(); + VarInsnNode load2 = (VarInsnNode) matchContext.captures().get("load-2").insn(); + if (store1.var == load1.var && store2.var == load2.var) { + if (Arrays.stream(methodNode.instructions.toArray()).filter(insn -> !insn.equals(load1)).noneMatch(insn -> insn.getOpcode() == ALOAD && ((VarInsnNode)insn).var == store1.var)) { + methodNode.instructions.remove(store1); + methodNode.instructions.remove(load1); + methodNode.instructions.remove(store2); + methodNode.instructions.remove(load2); + markChange(); + } + } + }); + }); + }); + } +} 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 new file mode 100644 index 00000000..a14d0276 --- /dev/null +++ b/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/skidfuscator/SkidFlowTransformer.java @@ -0,0 +1,148 @@ +package uwu.narumi.deobfuscator.core.other.impl.skidfuscator; + +import org.objectweb.asm.tree.*; +import uwu.narumi.deobfuscator.api.asm.ClassWrapper; +import uwu.narumi.deobfuscator.api.asm.MethodContext; +import uwu.narumi.deobfuscator.api.asm.MethodRef; +import uwu.narumi.deobfuscator.api.asm.matcher.Match; +import uwu.narumi.deobfuscator.api.asm.matcher.MatchContext; +import uwu.narumi.deobfuscator.api.asm.matcher.group.SequenceMatch; +import uwu.narumi.deobfuscator.api.asm.matcher.impl.JumpMatch; +import uwu.narumi.deobfuscator.api.asm.matcher.impl.MethodMatch; +import uwu.narumi.deobfuscator.api.asm.matcher.impl.NumberMatch; +import uwu.narumi.deobfuscator.api.asm.matcher.impl.OpcodeMatch; +import uwu.narumi.deobfuscator.api.transformer.Transformer; + +import java.util.HashSet; +import java.util.Set; + +public class SkidFlowTransformer extends Transformer { + + Match staticDecryption = SequenceMatch.of( + NumberMatch.numInteger().capture("salt"), + MethodMatch.invokeStatic().desc("(I)I").and(Match.of(ctx -> ctx.insn().asMethodInsn().name.length() == 16)).capture("predicate-method") + ); + + Match selfClassXor = SequenceMatch.of( + NumberMatch.numInteger().capture("salt1"), + NumberMatch.numInteger().capture("salt2"), + MethodMatch.invokeStatic().desc("(II)I").and(Match.of(ctx -> ctx.insn().asMethodInsn().name.length() == 16)).capture("predicate-method") + ); + + Match setVarJump = SequenceMatch.of( + NumberMatch.numInteger().capture("salt1"), + OpcodeMatch.of(ISTORE).capture("var"), + JumpMatch.of().capture("jump") + ); + + + private static ClassWrapper decryptStaticClass; + private static String method1Name; + + @Override + protected void transform() throws Exception { + if (decryptStaticClass == null) decryptStaticClass = scopedClasses().stream().filter(classWrapper -> classWrapper.name().length() == 33 && (classWrapper.methods().size() == 3 || classWrapper.methods().size() == 2) && classWrapper.methods().stream().map(methodNode -> methodNode.desc).allMatch(desc -> desc.equals("(I)I"))).findFirst().get(); + if (method1Name == null) method1Name = decryptStaticClass.findMethod(methodNode -> NumberMatch.of(31).findFirstMatch(MethodContext.of(decryptStaticClass, methodNode)) != null).get().name; + scopedClasses().forEach(classWrapper -> classWrapper.methods().forEach(methodNode -> { + MethodContext methodContext = MethodContext.of(classWrapper, methodNode); + + /* Example: var4 = afglgogiwinhilog(var4, 1845606652); */ + selfClassXor.findAllMatches(methodContext).forEach(matchContext -> { + MethodInsnNode methodInsnNode = matchContext.captures().get("predicate-method").insn().asMethodInsn(); + findMethod(classWrapper.classNode(), MethodRef.of(methodInsnNode)).ifPresent(xorMethod -> { + AbstractInsnNode salt1 = matchContext.captures().get("salt1").insn(); + AbstractInsnNode salt2 = matchContext.captures().get("salt2").insn(); + methodNode.instructions.set(salt1, new LdcInsnNode(salt2.asInteger() ^ salt1.asInteger())); + methodNode.instructions.remove(methodInsnNode); + methodNode.instructions.remove(salt2); + markChange(); + }); + }); + + /** Example + * 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(); + int decrypted = method1Name.equals(methodInsnNode.name) ? m1(salt.asInteger()) : m2_m3(salt.asInteger()); + methodNode.instructions.set(salt, new LdcInsnNode(decrypted)); + methodNode.instructions.remove(methodInsnNode); + markChange(); + }); + + /* Its moving hash LDC out of context for example, when IF/ELSE ends with same LDC and InlineVariable cant push var to next instructions because it has no context */ + 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) { + methodNode.instructions.remove(varStore); + methodNode.instructions.remove(intLdc); + methodNode.instructions.insert(jump1.label, varStore); + methodNode.instructions.insert(jump1.label, intLdc); + markChange(); + } + LdcInsnNode lastLdcOfLabel = null; + AbstractInsnNode node = jumpInsnNode; + while (node != null && !(node.getNext() instanceof LabelNode)) { + if (node instanceof LdcInsnNode ldc) { + lastLdcOfLabel = ldc; + } + node = node.getNext(); + } + if (lastLdcOfLabel != null) { + LdcInsnNode finalLastLdcOfLabel = lastLdcOfLabel; + 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(); + 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)); + } + }); + } + }); + + 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); + } + } + })); + } + + private final static Set blessedLabels = new HashSet<>(); + + public int m1(int n) { + if (n != 0) { + return (n * 31 >>> 4) % n ^ n >>> 16; + } + return 0; + } + + public int m2_m3(int n) { + return (n & 0xE0000000) >> 29 | n << 3; + } +} diff --git a/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/skidfuscator/SkidNumberTransformer.java b/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/skidfuscator/SkidNumberTransformer.java new file mode 100644 index 00000000..80314900 --- /dev/null +++ b/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/skidfuscator/SkidNumberTransformer.java @@ -0,0 +1,44 @@ +package uwu.narumi.deobfuscator.core.other.impl.skidfuscator; + +import org.objectweb.asm.tree.LdcInsnNode; +import uwu.narumi.deobfuscator.api.asm.MethodContext; +import uwu.narumi.deobfuscator.api.asm.matcher.Match; +import uwu.narumi.deobfuscator.api.asm.matcher.group.SequenceMatch; +import uwu.narumi.deobfuscator.api.asm.matcher.impl.MethodMatch; +import uwu.narumi.deobfuscator.api.asm.matcher.impl.NumberMatch; +import uwu.narumi.deobfuscator.api.asm.matcher.impl.OpcodeMatch; +import uwu.narumi.deobfuscator.api.transformer.Transformer; + +import java.util.Random; + +public class SkidNumberTransformer extends Transformer { + + Match randomNextMatch = SequenceMatch.of( + OpcodeMatch.of(NEW), + OpcodeMatch.of(DUP), + NumberMatch.numLong().capture("init-random"), + MethodMatch.invokeSpecial().owner("java/util/Random").name("").desc("(J)V"), + MethodMatch.invokeVirtual().owner("java/util/Random").capture("method") + ); + + @Override + protected void transform() throws Exception { + scopedClasses().forEach(classWrapper -> classWrapper.methods().forEach(methodNode -> { + MethodContext methodContext = MethodContext.of(classWrapper, methodNode); + randomNextMatch.findAllMatches(methodContext).forEach(matchContext -> { + Random random = new Random(matchContext.captures().get("init-random").insn().asLong()); + Object object = switch (matchContext.captures().get("method").insn().asMethodInsn().name) { + case "nextInt" -> random.nextInt(); + case "nextLong" -> random.nextLong(); + case "nextBoolean" -> random.nextBoolean(); + case "nextFloat" -> random.nextFloat(); + case "nextDouble" -> random.nextDouble(); + default -> throw new IllegalStateException("Unexpected value: " + matchContext.captures().get("method").insn().asMethodInsn().name); + }; + methodNode.instructions.insert(matchContext.insn(), new LdcInsnNode(object)); + matchContext.removeAll(); + markChange(); + }); + })); + } +} diff --git a/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/skidfuscator/SkidStringTransformer.java b/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/skidfuscator/SkidStringTransformer.java new file mode 100644 index 00000000..4af88bc4 --- /dev/null +++ b/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/skidfuscator/SkidStringTransformer.java @@ -0,0 +1,274 @@ +package uwu.narumi.deobfuscator.core.other.impl.skidfuscator; + +import org.objectweb.asm.tree.LdcInsnNode; +import org.objectweb.asm.tree.MethodNode; +import uwu.narumi.deobfuscator.api.asm.MethodContext; +import uwu.narumi.deobfuscator.api.asm.MethodRef; +import uwu.narumi.deobfuscator.api.asm.matcher.Match; +import uwu.narumi.deobfuscator.api.asm.matcher.MatchContext; +import uwu.narumi.deobfuscator.api.asm.matcher.group.SequenceMatch; +import uwu.narumi.deobfuscator.api.asm.matcher.impl.FieldMatch; +import uwu.narumi.deobfuscator.api.asm.matcher.impl.MethodMatch; +import uwu.narumi.deobfuscator.api.asm.matcher.impl.NumberMatch; +import uwu.narumi.deobfuscator.api.asm.matcher.impl.OpcodeMatch; +import uwu.narumi.deobfuscator.api.transformer.Transformer; + +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.HashSet; +import java.util.Set; + +public class SkidStringTransformer extends Transformer { + + Match fieldPutStaticByteArray = SequenceMatch.of( + MethodMatch.invokeStatic().desc("()[B").capture("method"), + FieldMatch.putStatic().desc("[B").capture("field") + ); + + Match fieldPutStaticString = SequenceMatch.of( + MethodMatch.invokeStatic().desc("()[B").capture("method"), + MethodMatch.invokeStatic().owner("java/nio/ByteBuffer").name("wrap").desc("([B)Ljava/nio/ByteBuffer;"), + MethodMatch.invokeVirtual().owner("java/nio/ByteBuffer").name("asCharBuffer").desc("()Ljava/nio/CharBuffer;"), + MethodMatch.invokeVirtual().owner("java/nio/CharBuffer").name("toString").desc("()Ljava/lang/String;"), + FieldMatch.putStatic().desc("Ljava/lang/String;").capture("field") + ); + + @Override + protected void transform() throws Exception { + scopedClasses().forEach(classWrapper -> { + Set trashMethods = new HashSet<>(); + classWrapper.methods().stream().filter(methodNode -> methodNode.name.length() == 10 && methodNode.desc.endsWith("I)Ljava/lang/String;")).forEach(decryptionMethod -> { + MethodContext methodContext = MethodContext.of(classWrapper, decryptionMethod); + int methodSize = Match.of(ctx -> ctx.insn().isMathOperator()).findAllMatches(methodContext).size(); + if (methodSize == 24 || methodSize == 23) { + classWrapper.findClInit().ifPresent(clinitNode -> { + MethodContext clinitContext = MethodContext.of(classWrapper, clinitNode); + MatchContext byteBufferMatch = fieldPutStaticString.findFirstMatch(clinitContext); + MethodNode toRemove; + String decryptHash = ByteBuffer.wrap( + resolveByteArrayFromMethod( + MethodContext.of( + classWrapper, + toRemove = findMethod( + classWrapper.classNode(), + MethodRef.of( + byteBufferMatch.captures().get("method").insn().asMethodInsn() + ) + ).get() + ) + ) + ).asCharBuffer().toString(); + classWrapper.fields().removeIf(fieldNode -> fieldNode.name.equals(byteBufferMatch.captures().get("field").insn().asFieldInsn().name)); + trashMethods.add(toRemove); + byteBufferMatch.removeAll(); + classWrapper.methods().forEach(methodNode -> { + MethodContext methodContext1 = MethodContext.of(classWrapper, methodNode); + SequenceMatch.of( + MethodMatch.invokeStatic().desc("()[B").capture("byte-array"), + NumberMatch.numInteger().capture("salt"), + MethodMatch.invokeStatic().name(decryptionMethod.name) + ).findAllMatches(methodContext1).forEach(matchContext -> { + int salt = matchContext.captures().get("salt").insn().asInteger(); + MethodNode toRemove1; + byte[] stringBytes = resolveByteArrayFromMethod( + MethodContext.of( + classWrapper, + toRemove1 = findMethod( + classWrapper.classNode(), + MethodRef.of( + matchContext.captures().get("byte-array").insn().asMethodInsn() + ) + ).get() + ) + ); + trashMethods.add(toRemove1); + methodNode.instructions.insertBefore(matchContext.insn(), new LdcInsnNode(method25(stringBytes, decryptHash, salt))); + markChange(); + matchContext.removeAll(); + }); + }); + }); + } else if (methodSize == 5 || methodSize == 4) { + if (decryptionMethod.desc.equals("([B[BI)Ljava/lang/String;")) { + classWrapper.methods().forEach(methodNode -> { + MethodContext methodContext1 = MethodContext.of(classWrapper, methodNode); + SequenceMatch.of( + MethodMatch.invokeStatic().desc("()[B").capture("byte-array1"), + MethodMatch.invokeStatic().desc("()[B").capture("byte-array2"), + NumberMatch.numInteger().capture("salt"), + MethodMatch.invokeStatic().name(decryptionMethod.name) + ).findAllMatches(methodContext1).forEach(matchContext -> { + int salt = matchContext.captures().get("salt").insn().asInteger(); + MethodNode toRemove1; + byte[] stringBytes = resolveByteArrayFromMethod( + MethodContext.of( + classWrapper, + toRemove1 = findMethod( + classWrapper.classNode(), + MethodRef.of( + matchContext.captures().get("byte-array1").insn().asMethodInsn() + ) + ).get() + ) + ); + trashMethods.add(toRemove1); + MethodNode toRemove; + byte[] decryptBytes = resolveByteArrayFromMethod( + MethodContext.of( + classWrapper, + toRemove = findMethod( + classWrapper.classNode(), + MethodRef.of( + matchContext.captures().get("byte-array2").insn().asMethodInsn() + ) + ).get() + ) + ); + trashMethods.add(toRemove); + methodNode.instructions.insertBefore(matchContext.insn(), new LdcInsnNode(method5(stringBytes, decryptBytes, salt))); + markChange(); + matchContext.removeAll(); + }); + }); + } else if (decryptionMethod.desc.equals("([BI)Ljava/lang/String;")) { + classWrapper.findClInit().ifPresent(clinitNode -> { + MethodContext clinitContext = MethodContext.of(classWrapper, clinitNode); + MatchContext bytesMatch = fieldPutStaticByteArray.findFirstMatch(clinitContext); + MethodNode toRemove; + byte[] decryptBytes = resolveByteArrayFromMethod( + MethodContext.of( + classWrapper, + toRemove = findMethod( + classWrapper.classNode(), + MethodRef.of( + bytesMatch.captures().get("method").insn().asMethodInsn() + ) + ).get() + ) + ); + trashMethods.add(toRemove); + classWrapper.fields().removeIf(fieldNode -> fieldNode.name.equals(bytesMatch.captures().get("field").insn().asFieldInsn().name)); + classWrapper.methods().forEach(methodNode -> { + MethodContext methodContext1 = MethodContext.of(classWrapper, methodNode); + SequenceMatch.of( + MethodMatch.invokeStatic().desc("()[B").capture("byte-array"), + NumberMatch.numInteger().capture("salt"), + MethodMatch.invokeStatic().name(decryptionMethod.name) + ).findAllMatches(methodContext1).forEach(matchContext -> { + int salt = matchContext.captures().get("salt").insn().asInteger(); + MethodNode toRemove1; + byte[] stringBytes = resolveByteArrayFromMethod( + MethodContext.of( + classWrapper, + toRemove1 = findMethod( + classWrapper.classNode(), + MethodRef.of( + matchContext.captures().get("byte-array").insn().asMethodInsn() + ) + ).get() + ) + ); + trashMethods.add(toRemove1); + methodNode.instructions.insertBefore(matchContext.insn(), new LdcInsnNode(method5(stringBytes, decryptBytes, salt))); + markChange(); + matchContext.removeAll(); + }); + }); + bytesMatch.removeAll(); + }); + } + } + trashMethods.add(decryptionMethod); + }); + classWrapper.methods().removeAll(trashMethods); + }); + } + + public static String method5(byte[] var0, byte[] var1, int var2) { + byte[] var9 = Integer.toString(var2).getBytes(); + int var10 = 0; + + while (true) { + int var18 = var0.length; + if (var10 >= var18) { + Charset var6 = StandardCharsets.UTF_16; + return new String(var0, var6); + } + + byte var21 = var0[var10]; + int var34 = var9.length; + int var31 = var10 % var34; + byte var28 = var9[var31]; + byte var23 = (byte)(var21 ^ var28); + var0[var10] = var23; + byte var24 = var0[var10]; + int var36 = var1.length; + int var33 = var10 % var36; + byte var30 = var1[var33]; + byte var26 = (byte)(var24 ^ var30); + var0[var10] = var26; + var10++; + } + } + + public static String method25(byte[] var0, String var1, int var2) { + byte[] var8 = Integer.toString(var2).getBytes(); + int var18 = (var0[0] & 255) << 24; + int var41 = (var0[1] & 255) << 16; + int var19 = var18 | var41; + int var45 = (var0[2] & 255) << 8; + int var20 = var19 | var45; + int var48 = var0[3] & 255; + int var9 = var20 | var48; + int var25 = (var0[4] & 255) << 24; + int var55 = (var0[5] & 255) << 16; + int var26 = var25 | var55; + int var59 = (var0[6] & 255) << 8; + int var27 = var26 | var59; + int var62 = var0[7] & 255; + int var10 = var27 | var62; + String var29 = var1; + int var84 = var10 + var9; + String var30 = var29.substring(var10, var84); + Charset var64 = StandardCharsets.UTF_16BE; + byte[] var11 = var30.getBytes(var64); + int var12 = 0; + + while (true) { + int var66 = var11.length; + if (var12 >= var66) { + Charset var91 = StandardCharsets.UTF_16BE; + return new String(var11, var91); + } + + byte var85 = var11[var12]; + int var93 = var8.length; + int var92 = var12 % var93; + byte var90 = var8[var92]; + byte var87 = (byte)(var85 ^ var90); + var11[var12] = var87; + var12++; + } + } + + public byte[] resolveByteArrayFromMethod(MethodContext methodContext) { + MatchContext decryptMethod = SequenceMatch.of( + NumberMatch.numInteger(), + OpcodeMatch.of(NEWARRAY) + ).findFirstMatch(methodContext); + if (decryptMethod != null) { + byte[] bytes = new byte[decryptMethod.insn().asInteger()]; + SequenceMatch.of( + OpcodeMatch.of(DUP), + NumberMatch.numInteger().capture("array-index"), + NumberMatch.of().capture("array-value"), + OpcodeMatch.of(BASTORE) + ).findAllMatches(methodContext).forEach(matchContext -> { + bytes[matchContext.captures().get("array-index").insn().asInteger()] = matchContext.captures().get("array-value").insn().asNumber().byteValue(); + }); + return bytes; + } + return null; + } +} diff --git a/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/skidfuscator/SkidTryCatchRemoveTransformer.java b/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/skidfuscator/SkidTryCatchRemoveTransformer.java new file mode 100644 index 00000000..b2381384 --- /dev/null +++ b/deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/skidfuscator/SkidTryCatchRemoveTransformer.java @@ -0,0 +1,97 @@ +package uwu.narumi.deobfuscator.core.other.impl.skidfuscator; + +import org.objectweb.asm.tree.*; +import uwu.narumi.deobfuscator.api.asm.ClassWrapper; +import uwu.narumi.deobfuscator.api.asm.MethodContext; +import uwu.narumi.deobfuscator.api.asm.matcher.Match; +import uwu.narumi.deobfuscator.api.asm.matcher.group.AnyMatch; +import uwu.narumi.deobfuscator.api.asm.matcher.group.SequenceMatch; +import uwu.narumi.deobfuscator.api.asm.matcher.impl.JumpMatch; +import uwu.narumi.deobfuscator.api.asm.matcher.impl.MethodMatch; +import uwu.narumi.deobfuscator.api.asm.matcher.impl.OpcodeMatch; +import uwu.narumi.deobfuscator.api.transformer.Transformer; + +import java.util.HashSet; +import java.util.Set; + +public class SkidTryCatchRemoveTransformer extends Transformer { + @Override + protected void transform() throws Exception { + scopedClasses().forEach(classWrapper -> classWrapper.methods().forEach(methodNode -> resolveFakeTcb(classWrapper, methodNode))); + } + + /** + * Skid's transformer basically does some whacky stuff: + * Source: https://github.com/skidfuscatordev/skidfuscator-java-obfuscator/blob/master/dev.skidfuscator.obfuscator/src/main/java/dev/skidfuscator/obfuscator/transform/impl/flow/BasicRangeTransformer.java + * + * Original flow: Obfuscated Flow: + * + * ┌─────────┐ ┌─────────┐ + * │ Block A │ │ Block A │ + * └────┬────┘ └────┬────┘ + * │ │ + * ┌────▼────┐ ┌───────▼────────┐ + * │ Block B │ │ Random If Stmt │ + * └─────────┘ └───────┬────────┘ + * │ + * ┌─────┐◄──┴───►┌─────┐ + * │ Yes │ │ No │ + * └─────┘ └──┬──┘ + * │ + * ┌─────▼─────┐ + * │ Exception │ + * └───────────┘ + * + * ┌─────────────┐ + * │ Exception │ + * │ Catcher │ + * └──────┬──────┘ + * │ + * ┌────▼────┐ + * │ Block B │ + * └─────────┘ + */ + public void resolveFakeTcb(ClassWrapper classWrapper, MethodNode methodNode) { + MethodContext methodContext = MethodContext.of(classWrapper, methodNode); + Set tcbToRemove = new HashSet<>(); + Set toRemove = new HashSet<>(); + methodNode.tryCatchBlocks.forEach(tcb -> { + /* Checking if start block has throw null */ + SequenceMatch.of( + AnyMatch.of(OpcodeMatch.of(ILOAD), OpcodeMatch.of(LDC)).and(Match.of(ctx -> isInsnInLabelRange(methodNode, tcb.start, ctx.insn()))), + MethodMatch.invokeStatic(), + OpcodeMatch.of(LDC), + JumpMatch.of().capture("throw-label"), + OpcodeMatch.of(ACONST_NULL), + OpcodeMatch.of(ATHROW) + ).or( + SequenceMatch.of( + OpcodeMatch.of(NEW).and(Match.of(ctx -> isInsnInLabelRange(methodNode, tcb.start, ctx.insn()))), + OpcodeMatch.of(DUP), + MethodMatch.invokeSpecial(), + OpcodeMatch.of(ATHROW) + ) + ).findAny(methodContext).ifPresent(matchContext -> { + /* Clearing "else" block which throws exception */ + toRemove.addAll(matchContext.collectedInsns()); + LabelNode fakeJump; + if (matchContext.captures().containsKey("throw-label")) { + fakeJump = matchContext.captures().get("throw-label").insn().asJump().label; + toRemove.add(fakeJump); + } else { + fakeJump = tcb.handler; + } + AbstractInsnNode abstractInsnNode = fakeJump; + while (abstractInsnNode.getNext() != null && abstractInsnNode.getOpcode() != POP) { + abstractInsnNode = abstractInsnNode.getNext(); + } + toRemove.add(abstractInsnNode); + tcbToRemove.add(tcb); + methodNode.instructions.insert(tcb.start, new JumpInsnNode(GOTO, tcb.handler)); + markChange(); + }); + }); + toRemove.forEach(methodNode.instructions::remove); + methodNode.tryCatchBlocks.removeAll(tcbToRemove); + } +} diff --git a/testData/compiled/custom-jars/skidfuscator.jar b/testData/compiled/custom-jars/skidfuscator.jar new file mode 100644 index 00000000..d67314f2 Binary files /dev/null and b/testData/compiled/custom-jars/skidfuscator.jar differ diff --git a/testData/results/custom-classes/guardprotector/Class951.dec b/testData/results/custom-classes/guardprotector/Class951.dec index d5b138c9..f319b5c0 100644 --- a/testData/results/custom-classes/guardprotector/Class951.dec +++ b/testData/results/custom-classes/guardprotector/Class951.dec @@ -16,8 +16,6 @@ public class Class951 { private static final ScheduledExecutorService field2971 = Executors.newScheduledThreadPool(1); private static int field2972 = 325170080; private static long[] field2973; - private static final int field2974; - private static final int field2975; @Class295 public static synchronized void method3419(Class320 var0) { diff --git a/testData/results/custom-jars/skidfuscator/pack/Clazz.dec b/testData/results/custom-jars/skidfuscator/pack/Clazz.dec new file mode 100644 index 00000000..a3aff8d8 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/Clazz.dec @@ -0,0 +1,4 @@ +package pack; + +public class Clazz { +} diff --git a/testData/results/custom-jars/skidfuscator/pack/Main.dec b/testData/results/custom-jars/skidfuscator/pack/Main.dec new file mode 100644 index 00000000..a7597b96 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/Main.dec @@ -0,0 +1,171 @@ +package pack; + +import java.io.File; +import pack.tests.basics.accu.Digi; +import pack.tests.basics.ctrl.Ctrl; +import pack.tests.basics.inner.Test; +import pack.tests.basics.overwirte.Sub; +import pack.tests.basics.runable.Task; +import pack.tests.basics.sub.Solver; +import pack.tests.bench.Calc; +import pack.tests.reflects.annot.annot; +import pack.tests.reflects.counter.Count; +import pack.tests.reflects.field.FTest; +import pack.tests.reflects.loader.LRun; +import pack.tests.reflects.res.Accesor; +import pack.tests.reflects.retrace.Tracer; +import pack.tests.security.SecTest; + +public class Main { + public static void main(String[] var0) throws Exception { + System.out.println("Obfuscator Test Program"); + System.out.println("Author: huzpsb"); + System.out.println("Version: 1.0r"); + System.out.println("Link: https://github.com/huzpsb/JavaObfuscatorTest"); + String var3 = "IK"; + File var9 = new File(var3); + if (!var9.exists()) { + var9.createNewFile(); + System.out.println(); + System.out.println("[HINT]"); + System.out.println("Only compatibility and efficiency are tested here!"); + System.out.println("For most users, pass all of the basics means the obfuscator is good enough."); + System.out.println("The Test #2 is for SpringBoot and Android like environment."); + System.out.println("Choose wisely among strength, compatibility, efficiency, size, and price."); + System.out.println("[HINT]"); + System.out.println(); + } + + System.out.println("-------------Test #1: Basics-------------"); + System.out.print("Test 1.1: Inheritance "); + + try { + Sub var24 = new Sub(); + var24.run(1168994165); + } catch (Throwable var78) { + System.out.println("ERROR"); + } + + System.out.print("Test 1.2: Cross "); + + try { + Sub var26 = new Sub(); + var26.run(1168994165); + } catch (Throwable var77) { + System.out.println("ERROR"); + } + + System.out.print("Test 1.3: Throw "); + + try { + Ctrl var30 = new Ctrl(); + var30.run(1787797814); + } catch (Throwable var76) { + System.out.println("ERROR"); + } + + System.out.print("Test 1.4: Accuracy "); + + try { + Digi var32 = new Digi(); + var32.run(892901271); + } catch (Throwable var75) { + System.out.println("ERROR"); + } + + System.out.print("Test 1.5: SubClass "); + + try { + new Solver(); + } catch (Throwable var74) { + System.out.println("ERROR"); + } + + System.out.print("Test 1.6: Pool "); + + try { + Task var36 = new Task(); + var36.run(727450531); + } catch (Throwable var73) { + System.out.println("ERROR"); + } + + System.out.print("Test 1.7: InnerClass "); + + try { + Test var40 = new Test(); + var40.run(1419176946); + } catch (Throwable var72) { + System.out.println("ERROR"); + } + + System.out.println("-------------Test #2: Reflects-------------"); + System.out.print("Test 2.1: Counter "); + + try { + Count var45 = new Count(); + var45.run(337410739); + } catch (Throwable var71) { + System.out.println("ERROR"); + } + + System.out.print("Test 2.2: Chinese 通过LMAO\b\b\b\b \n"); + System.out.print("Test 2.3: Resource "); + + try { + Accesor var48 = new Accesor(); + var48.run(604197675); + } catch (Throwable var70) { + System.out.println("ERROR"); + } + + System.out.print("Test 2.4: Field "); + + try { + FTest var52 = new FTest(); + var52.run(1876691223); + } catch (Throwable var69) { + System.out.println("ERROR"); + } + + System.out.print("Test 2.5: Loader "); + + try { + LRun var56 = new LRun(); + var56.run(2088116254); + } catch (Throwable var68) { + System.out.println("ERROR"); + } + + System.out.print("Test 2.6: ReTrace "); + + try { + Tracer var58 = new Tracer(); + var58.run(466761206); + } catch (Throwable var67) { + System.out.println("ERROR"); + } + + System.out.print("Test 2.7: Annotation "); + + try { + annot var60 = new annot(); + var60.run(2055899077); + } catch (Throwable var66) { + System.out.println("ERROR"); + } + + System.out.print("Test 2.8: Sec "); + + try { + SecTest var64 = new SecTest(); + var64.run(2025340204); + } catch (Throwable var65) { + System.out.println("ERROR"); + } + + System.out.println("-------------Test #3: Efficiency-------------"); + Calc.runAll(1330028127); + System.out.println("-------------Tests r Finished-------------"); + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/basics/accu/Digi.dec b/testData/results/custom-jars/skidfuscator/pack/tests/basics/accu/Digi.dec new file mode 100644 index 00000000..47727d0c --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/basics/accu/Digi.dec @@ -0,0 +1,22 @@ +package pack.tests.basics.accu; + +public class Digi { + public void run(int var1) { + double var7 = 0.0; + int var9 = 0; + + do { + var7 += 1.0E-18; + } while (++var9 <= 100 && (float)var7 != 2.0E-17F); + + if (var9 == 20) { + System.out.println("PASS"); + } else { + System.out.println("FAIL"); + } + } + + private static byte[] kqlfjamyycsynra() { + return new byte[]{-125, -75, 14, 106, 0, 98, 92, 21, 1, 51}; + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/basics/cross/Abst1.dec b/testData/results/custom-jars/skidfuscator/pack/tests/basics/cross/Abst1.dec new file mode 100644 index 00000000..500d7951 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/basics/cross/Abst1.dec @@ -0,0 +1,9 @@ +package pack.tests.basics.cross; + +public abstract class Abst1 { + public abstract int add(int var1, int var2, int var3); + + public int mul(int var1, int var2, int var3) { + return var1 * var2; + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/basics/cross/Inte.dec b/testData/results/custom-jars/skidfuscator/pack/tests/basics/cross/Inte.dec new file mode 100644 index 00000000..da16cc4b --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/basics/cross/Inte.dec @@ -0,0 +1,5 @@ +package pack.tests.basics.cross; + +public interface Inte { + int mul(int var1, int var2); +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/basics/cross/Top.dec b/testData/results/custom-jars/skidfuscator/pack/tests/basics/cross/Top.dec new file mode 100644 index 00000000..e1c9186f --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/basics/cross/Top.dec @@ -0,0 +1,16 @@ +package pack.tests.basics.cross; + +public class Top extends Abst1 implements Inte { + public void run() { + if (this.add(1, 2, 332349609) == 3 && this.mul(2, 3, 1586508627) == 6) { + System.out.println("PASS"); + } else { + System.out.println("FAIL"); + } + } + + @Override + public int add(int var1, int var2, int var3) { + return var1 + var2; + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/basics/ctrl/Ctrl.dec b/testData/results/custom-jars/skidfuscator/pack/tests/basics/ctrl/Ctrl.dec new file mode 100644 index 00000000..528cc7d3 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/basics/ctrl/Ctrl.dec @@ -0,0 +1,40 @@ +package pack.tests.basics.ctrl; + +import java.io.PrintStream; + +public class Ctrl { + private String ret = "FAIL"; + + public void runt(int var1) { + if (!"a".equals("b")) { + UnsupportedOperationException var5 = new UnsupportedOperationException(); + throw var5; + } + } + + public void runf(int var1) { + try { + this.runt(1192047436); + } catch (RuntimeException var12) { + String var10 = "PASS"; + this.ret = var10; + } + + try { + this.runt(1192047436); + String var3 = "FAIL"; + this.ret = var3; + } catch (Exception var11) { + return; + } + + throw new IllegalAccessException("Error in hash"); + } + + public void run(int var1) { + this.runf(1311545484); + PrintStream var4 = System.out; + String var5 = this.ret; + var4.println(var5); + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/basics/inner/Exec.dec b/testData/results/custom-jars/skidfuscator/pack/tests/basics/inner/Exec.dec new file mode 100644 index 00000000..a9c8ef78 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/basics/inner/Exec.dec @@ -0,0 +1,27 @@ +package pack.tests.basics.inner; + +public class Exec { + public int fuss = 1; + + public void addF(int var1) { + int var5 = this.fuss + 2; + this.fuss = var5; + } + + public class Inner { + int i; + + public Inner(int var2, int var3) { + this.i = var2; + } + + public void doAdd(int var1) { + Exec.this.addF(985687609); + Exec var6 = Exec.this; + int var7 = var6.fuss; + int var9 = this.i; + int var8 = var7 + var9; + var6.fuss = var8; + } + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/basics/inner/Test.dec b/testData/results/custom-jars/skidfuscator/pack/tests/basics/inner/Test.dec new file mode 100644 index 00000000..1d939e90 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/basics/inner/Test.dec @@ -0,0 +1,16 @@ +package pack.tests.basics.inner; + +public class Test { + public void run(int var1) { + Exec var2 = new Exec(); + Exec.Inner var7 = var2.new Inner(3, 1527845619); + var7.doAdd(790770962); + Exec.Inner var9 = var2.new Inner(100, 1527845619); + var9.doAdd(790770962); + if (var2.fuss == 108) { + System.out.println("PASS"); + } else { + System.out.println("ERROR"); + } + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/basics/overwirte/Face.dec b/testData/results/custom-jars/skidfuscator/pack/tests/basics/overwirte/Face.dec new file mode 100644 index 00000000..e7c36d04 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/basics/overwirte/Face.dec @@ -0,0 +1,5 @@ +package pack.tests.basics.overwirte; + +public interface Face { + String face(int var1, int var2); +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/basics/overwirte/Sub.dec b/testData/results/custom-jars/skidfuscator/pack/tests/basics/overwirte/Sub.dec new file mode 100644 index 00000000..114b7389 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/basics/overwirte/Sub.dec @@ -0,0 +1,17 @@ +package pack.tests.basics.overwirte; + +import java.io.PrintStream; + +public class Sub extends Super { + @Override + public void run(int var1) { + PrintStream var6 = System.out; + String var8 = this.face(1, 643068137); + var6.println(var8); + } + + @Override + public String face(int var1, int var2) { + return var1 == 1 ? "PASS" : "FAIL"; + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/basics/overwirte/Super.dec b/testData/results/custom-jars/skidfuscator/pack/tests/basics/overwirte/Super.dec new file mode 100644 index 00000000..b18e38f8 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/basics/overwirte/Super.dec @@ -0,0 +1,7 @@ +package pack.tests.basics.overwirte; + +public abstract class Super implements Face { + public void run(int var1) { + System.out.println("FAIL"); + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/basics/runable/Exec.dec b/testData/results/custom-jars/skidfuscator/pack/tests/basics/runable/Exec.dec new file mode 100644 index 00000000..cb81761f --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/basics/runable/Exec.dec @@ -0,0 +1,21 @@ +package pack.tests.basics.runable; + +public class Exec { + public static int i = 1; + private int d; + + public Exec(int var1, int var2) { + this.d = var1; + } + + void doAdd() { + try { + Thread.sleep(200L); + } catch (Exception var9) { + } + + int var6 = i; + int var8 = this.d; + i = var6 + var8; + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/basics/runable/Pool.dec b/testData/results/custom-jars/skidfuscator/pack/tests/basics/runable/Pool.dec new file mode 100644 index 00000000..3b2fb942 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/basics/runable/Pool.dec @@ -0,0 +1,16 @@ +package pack.tests.basics.runable; + +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +public class Pool { + public static ThreadPoolExecutor tpe; + + static { + TimeUnit var5 = TimeUnit.SECONDS; + LinkedBlockingQueue var6 = new LinkedBlockingQueue(1); + ThreadPoolExecutor var0 = new ThreadPoolExecutor(0, 1, 1L, var5, var6); + tpe = var0; + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/basics/runable/Task.dec b/testData/results/custom-jars/skidfuscator/pack/tests/basics/runable/Task.dec new file mode 100644 index 00000000..7da263db --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/basics/runable/Task.dec @@ -0,0 +1,106 @@ +package pack.tests.basics.runable; + +public class Task { + public void run(int param1) throws Exception { + // $VF: Couldn't be decompiled + // Please report this to the Vineflower issue tracker, at https://github.com/Vineflower/vineflower/issues with a copy of the class file (if you have the rights to distribute it!) + // java.lang.RuntimeException: parsing failure! + // at org.jetbrains.java.decompiler.modules.decompiler.decompose.DomHelper.parseGraph(DomHelper.java:211) + // at org.jetbrains.java.decompiler.main.rels.MethodProcessor.codeToJava(MethodProcessor.java:166) + // + // Bytecode: + // 00: new pack/tests/basics/runable/Exec + // 03: astore 2 + // 04: aload 2 + // 05: bipush 2 + // 06: ldc 1800938360 + // 08: invokespecial pack/tests/basics/runable/Exec. (II)V + // 0b: aload 2 + // 0c: astore 4 + // 0e: new pack/tests/basics/runable/Exec + // 11: astore 8 + // 13: aload 8 + // 15: bipush 3 + // 16: ldc 1800938360 + // 18: invokespecial pack/tests/basics/runable/Exec. (II)V + // 1b: aload 8 + // 1d: astore 5 + // 1f: new pack/tests/basics/runable/Exec + // 22: astore 9 + // 24: aload 9 + // 26: bipush 100 + // 28: ldc 1800938360 + // 2a: invokespecial pack/tests/basics/runable/Exec. (II)V + // 2d: aload 9 + // 2f: astore 6 + // 31: getstatic pack/tests/basics/runable/Pool.tpe Ljava/util/concurrent/ThreadPoolExecutor; + // 34: astore 10 + // 36: aload 5 + // 38: astore 30 + // 3a: aload 30 + // 3c: invokevirtual java/lang/Object.getClass ()Ljava/lang/Class; + // 3f: pop + // 40: aload 30 + // 42: invokedynamic run (Lpack/tests/basics/runable/Exec;)Ljava/lang/Runnable; bsm=java/lang/invoke/LambdaMetafactory.metafactory (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; args=[ ()V, pack/tests/basics/runable/Exec.doAdd ()V, ()V ] + // 47: astore 31 + // 49: aload 10 + // 4b: aload 31 + // 4d: invokevirtual java/util/concurrent/ThreadPoolExecutor.submit (Ljava/lang/Runnable;)Ljava/util/concurrent/Future; + // 50: pop + // 51: ldc2_w 50 + // 54: invokestatic java/lang/Thread.sleep (J)V + // 57: goto a1 + // 5a: pop + // 5b: getstatic pack/tests/basics/runable/Pool.tpe Ljava/util/concurrent/ThreadPoolExecutor; + // 5e: astore 15 + // 60: aload 4 + // 62: invokedynamic run (Lpack/tests/basics/runable/Exec;)Ljava/lang/Runnable; bsm=java/lang/invoke/LambdaMetafactory.metafactory (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; args=[ ()V, pack/tests/basics/runable/Task.lambda$run$0 (Lpack/tests/basics/runable/Exec;)V, ()V ] + // 67: astore 33 + // 69: aload 15 + // 6b: aload 33 + // 6d: invokevirtual java/util/concurrent/ThreadPoolExecutor.submit (Ljava/lang/Runnable;)Ljava/util/concurrent/Future; + // 70: pop + // 71: ldc2_w 50 + // 74: invokestatic java/lang/Thread.sleep (J)V + // 77: goto 9e + // 7a: pop + // 7b: getstatic pack/tests/basics/runable/Pool.tpe Ljava/util/concurrent/ThreadPoolExecutor; + // 7e: astore 20 + // 80: aload 6 + // 82: astore 34 + // 84: aload 34 + // 86: invokevirtual java/lang/Object.getClass ()Ljava/lang/Class; + // 89: pop + // 8a: aload 34 + // 8c: invokedynamic run (Lpack/tests/basics/runable/Exec;)Ljava/lang/Runnable; bsm=java/lang/invoke/LambdaMetafactory.metafactory (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; args=[ ()V, pack/tests/basics/runable/Exec.doAdd ()V, ()V ] + // 91: astore 35 + // 93: aload 20 + // 95: aload 35 + // 97: invokevirtual java/util/concurrent/ThreadPoolExecutor.submit (Ljava/lang/Runnable;)Ljava/util/concurrent/Future; + // 9a: pop + // 9b: goto a7 + // 9e: goto 7b + // a1: goto 5b + // a4: goto 5a + // a7: goto b4 + // aa: pop + // ab: getstatic pack/tests/basics/runable/Exec.i I + // ae: bipush 10 + // b0: iadd + // b1: putstatic pack/tests/basics/runable/Exec.i I + // b4: ldc2_w 300 + // b7: invokestatic java/lang/Thread.sleep (J)V + // ba: getstatic pack/tests/basics/runable/Exec.i I + // bd: bipush 30 + // bf: if_icmpne cd + // c2: getstatic java/lang/System.out Ljava/io/PrintStream; + // c5: ldc "PASS" + // c7: invokevirtual java/io/PrintStream.println (Ljava/lang/String;)V + // ca: goto d5 + // cd: getstatic java/lang/System.out Ljava/io/PrintStream; + // d0: ldc "FAIL" + // d2: invokevirtual java/io/PrintStream.println (Ljava/lang/String;)V + // d5: return + // d6: goto 7a + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/basics/sub/SolAdd.dec b/testData/results/custom-jars/skidfuscator/pack/tests/basics/sub/SolAdd.dec new file mode 100644 index 00000000..0a40227d --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/basics/sub/SolAdd.dec @@ -0,0 +1,8 @@ +package pack.tests.basics.sub; + +public class SolAdd { + public static int get(int var0) { + med var1 = new med(1, 2, 1753962384); + return var1.result; + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/basics/sub/Solver.dec b/testData/results/custom-jars/skidfuscator/pack/tests/basics/sub/Solver.dec new file mode 100644 index 00000000..65269381 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/basics/sub/Solver.dec @@ -0,0 +1,11 @@ +package pack.tests.basics.sub; + +public class Solver { + public Solver() { + if (SolAdd.get(1227979901) == 3) { + System.out.println("PASS"); + } else { + System.out.println("FAIL"); + } + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/basics/sub/flo.dec b/testData/results/custom-jars/skidfuscator/pack/tests/basics/sub/flo.dec new file mode 100644 index 00000000..879bfef8 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/basics/sub/flo.dec @@ -0,0 +1,7 @@ +package pack.tests.basics.sub; + +class flo { + int solve(int var1, int var2, int var3) { + return var1 + var2; + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/basics/sub/med.dec b/testData/results/custom-jars/skidfuscator/pack/tests/basics/sub/med.dec new file mode 100644 index 00000000..3dd485b1 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/basics/sub/med.dec @@ -0,0 +1,11 @@ +package pack.tests.basics.sub; + +class med { + int result; + + med(int var1, int var2, int var3) { + flo var5 = new flo(); + int var8 = var5.solve(var1, var2, 638043422); + this.result = var8; + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/bench/Calc.dec b/testData/results/custom-jars/skidfuscator/pack/tests/bench/Calc.dec new file mode 100644 index 00000000..9d9ae81d --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/bench/Calc.dec @@ -0,0 +1,60 @@ +package pack.tests.bench; + +import java.io.PrintStream; + +public class Calc { + public static int count = 0; + + public static void runAll(int var0) { + long var6 = System.currentTimeMillis(); + + for (int var8 = 0; var8 < 10000; var8++) { + call(100, 1301919330); + runAdd(1390077608); + runStr(1564474936); + } + + PrintStream var11 = System.out; + StringBuilder var15 = new StringBuilder(); + String var21 = "Calc: "; + StringBuilder var16 = var15.append(var21); + long var22 = System.currentTimeMillis(); + long var24 = var22 - var6; + String var19 = var16.append(var24).append("ms").toString(); + var11.println(var19); + if (count != 30000) { + String var27 = "[ERROR]: Errors occurred in calc!"; + RuntimeException var13 = new RuntimeException(var27); + throw var13; + } + } + + private static void call(int var0, int var1) { + if (var0 == 0) { + count++; + } else { + call(var0 - 1, 1301919330); + } + } + + private static void runAdd(int var0) { + double var6 = 0.0; + + while (var6 < 100.1) { + var6 += 0.99; + } + + count++; + } + + private static void runStr(int var0) { + String var3 = ""; + + while (var3.length() < 101) { + StringBuilder var8 = new StringBuilder(); + var3 = var8.append(var3).append("ax").toString(); + } + + count++; + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/reflects/annot/anno.dec b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/annot/anno.dec new file mode 100644 index 00000000..4149deff --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/annot/anno.dec @@ -0,0 +1,11 @@ +package pack.tests.reflects.annot; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface anno { + String val() default "yes"; + + String val2() default "yes"; +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/reflects/annot/annoe.dec b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/annot/annoe.dec new file mode 100644 index 00000000..378cd289 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/annot/annoe.dec @@ -0,0 +1,34 @@ +package pack.tests.reflects.annot; + +import java.io.PrintStream; +import java.lang.reflect.Field; + +public class annoe { + @anno( + val = "PASS" + ) + private static final String fail = "WHAT"; + + @anno + public void dox() throws Exception { + String var3 = "FAIL"; + + for (Field var7 : annoe.class.getDeclaredFields()) { + var7.setAccessible(true); + anno var8 = var7.getAnnotation(anno.class); + if (var8 != null) { + var3 = var8.val(); + } + } + + PrintStream var15 = System.out; + var15.println(var3); + } + + @anno( + val = "no" + ) + public void dov() { + System.out.println("FAIL"); + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/reflects/annot/annot.dec b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/annot/annot.dec new file mode 100644 index 00000000..baaeece5 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/annot/annot.dec @@ -0,0 +1,19 @@ +package pack.tests.reflects.annot; + +import java.lang.reflect.Method; + +public class annot { + public void run(int var1) throws Exception { + annoe var2 = new annoe(); + annoe var4 = var2; + + for (Method var8 : annoe.class.getDeclaredMethods()) { + var8.setAccessible(true); + anno var9 = var8.getAnnotation(anno.class); + if (var9 != null && var9.val().equals("yes")) { + Object[] var34 = new Object[0]; + var8.invoke(var4, var34); + } + } + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/reflects/counter/Count.dec b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/counter/Count.dec new file mode 100644 index 00000000..e2e645d3 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/counter/Count.dec @@ -0,0 +1,14 @@ +package pack.tests.reflects.counter; + +public class Count { + public void run(int var1) throws Throwable { + if (Countee.class.getFields().length == 1 + && Countee.class.getDeclaredFields().length == 4 + && Countee.class.getMethods().length > 4 + && Countee.class.getDeclaredMethods().length == 4) { + System.out.println("PASS"); + } else { + System.out.println("FAIL"); + } + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/reflects/counter/Countee.dec b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/counter/Countee.dec new file mode 100644 index 00000000..f8806a75 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/counter/Countee.dec @@ -0,0 +1,20 @@ +package pack.tests.reflects.counter; + +public class Countee { + public int cpuli = 0; + protected int cprot = 0; + int cpackp = 1; + private int cpriv = 0; + + public void mpuli() { + } + + public void mprot() { + } + + public void mpackp() { + } + + public void mpriv() { + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/reflects/field/FObject.dec b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/field/FObject.dec new file mode 100644 index 00000000..31c568d2 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/field/FObject.dec @@ -0,0 +1,94 @@ +package pack.tests.reflects.field; + +public class FObject { + private int i; + + private FObject(int var1) { + this.i = var1; + } + + private void add() { + int var4 = this.i + 3; + this.i = var4; + } + + private static byte[] gnmdizzzuakykcp() { + return new byte[]{ + 75, + 69, + 68, + 109, + 32, + 34, + 65, + 13, + 108, + 25, + 57, + 69, + 59, + 81, + 87, + 122, + 49, + 17, + 46, + 45, + 85, + 91, + 51, + 45, + 76, + 97, + 91, + 81, + 11, + 52, + 45, + 91, + 64, + 4, + 76, + 112, + 94, + 12, + 21, + 44, + 8, + 4, + 120, + 57, + 58, + 102, + 26, + 64, + 126, + 126, + 49, + 60, + 69, + 18, + 24, + 34, + 81, + 58, + 2, + 105, + 1, + 95, + 24, + 106, + 65, + 21, + 74, + 83, + 44, + 59, + 104, + 82, + 17, + 39, + 3 + }; + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/reflects/field/FTest.dec b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/field/FTest.dec new file mode 100644 index 00000000..20979c29 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/field/FTest.dec @@ -0,0 +1,44 @@ +package pack.tests.reflects.field; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +public class FTest { + public void run(int var1) throws Exception { + Class[] var36 = new Class[1]; + Class var5 = int.class; + var36[0] = var5; + Constructor var6 = FObject.class.getDeclaredConstructor(var36); + if (var6.isAccessible()) { + System.out.println("FAIL"); + } else { + var6.setAccessible(true); + Object[] var40 = new Object[1]; + Integer var57 = 1; + var40[0] = var57; + FObject var7 = (FObject)var6.newInstance(var40); + String var41 = "add"; + Method var8 = FObject.class.getDeclaredMethod(var41, null); + if (var8.isAccessible()) { + System.out.println("FAIL"); + } else { + var8.setAccessible(true); + Object[] var54 = new Object[0]; + var8.invoke(var7, var54); + String var45 = "i"; + Field var9 = FObject.class.getDeclaredField(var45); + if (var9.isAccessible()) { + System.out.println("FAIL"); + } else { + var9.setAccessible(true); + if (var9.getInt(var7) != 4) { + System.out.println("FAIL"); + } else { + System.out.println("PASS"); + } + } + } + } + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/reflects/loader/LRun.dec b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/loader/LRun.dec new file mode 100644 index 00000000..bd8bb6a2 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/loader/LRun.dec @@ -0,0 +1,16 @@ +package pack.tests.reflects.loader; + +import java.lang.reflect.Method; + +public class LRun { + public void run(int var1) throws Exception { + Loader var2 = new Loader(); + Class var5 = var2.findClass("pack.tests.reflects.loader.LTest"); + Object var6 = var5.newInstance(); + String var15 = "run"; + Class[] var17 = new Class[0]; + Method var12 = var5.getMethod(var15, var17); + Object[] var19 = new Object[0]; + var12.invoke(var6, var19); + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/reflects/loader/LTest.dec b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/loader/LTest.dec new file mode 100644 index 00000000..f13f4eeb --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/loader/LTest.dec @@ -0,0 +1,31 @@ +package pack.tests.reflects.loader; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; + +public class LTest { + public static byte[] readAllBytes(InputStream var0, int var1) throws IOException { + ByteArrayOutputStream var2 = new ByteArrayOutputStream(); + ByteArrayOutputStream var5 = var2; + byte[] var6 = new byte[1024]; + + while (true) { + int var11 = var0.read(var6); + if (var11 == -1) { + return var5.toByteArray(); + } + + var5.write(var6, 0, var11); + } + } + + public void run() throws Exception { + PrintStream var1 = System.out; + String var4 = "TEST"; + byte[] var6 = readAllBytes(LTest.class.getResourceAsStream(var4), 1160298099); + String var2 = new String(var6); + var1.println(var2); + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/reflects/loader/Loader.dec b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/loader/Loader.dec new file mode 100644 index 00000000..b5e3e309 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/loader/Loader.dec @@ -0,0 +1,77 @@ +package pack.tests.reflects.loader; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +public class Loader extends ClassLoader { + public static byte[] readAllBytes(InputStream param0, int param1) { + // $VF: Couldn't be decompiled + // Please report this to the Vineflower issue tracker, at https://github.com/Vineflower/vineflower/issues with a copy of the class file (if you have the rights to distribute it!) + // java.lang.RuntimeException: parsing failure! + // at org.jetbrains.java.decompiler.modules.decompiler.decompose.DomHelper.parseGraph(DomHelper.java:211) + // at org.jetbrains.java.decompiler.main.rels.MethodProcessor.codeToJava(MethodProcessor.java:166) + // + // Bytecode: + // 00: new java/io/ByteArrayOutputStream + // 03: astore 2 + // 04: aload 2 + // 05: invokespecial java/io/ByteArrayOutputStream. ()V + // 08: aload 2 + // 09: astore 5 + // 0b: sipush 1024 + // 0e: newarray 8 + // 10: astore 6 + // 12: aload 0 + // 13: astore 10 + // 15: aload 6 + // 17: astore 17 + // 19: aload 10 + // 1b: aload 17 + // 1d: invokevirtual java/io/InputStream.read ([B)I + // 20: istore 11 + // 22: iload 11 + // 24: istore 7 + // 26: iload 11 + // 28: bipush -1 + // 29: if_icmpeq 52 + // 2c: aload 5 + // 2e: astore 16 + // 30: aload 6 + // 32: astore 19 + // 34: iload 7 + // 36: istore 4 + // 38: aload 16 + // 3a: aload 19 + // 3c: bipush 0 + // 3d: iload 4 + // 3f: invokevirtual java/io/ByteArrayOutputStream.write ([BII)V + // 42: goto 4f + // 45: aload 5 + // 47: invokevirtual java/io/ByteArrayOutputStream.toByteArray ()[B + // 4a: astore 13 + // 4c: aload 13 + // 4e: areturn + // 4f: goto 12 + // 52: goto 45 + // 55: pop + // 56: aconst_null + // 57: areturn + } + + @Override + public InputStream getResourceAsStream(String var1) { + if (var1.contains("TEST")) { + byte[] var10 = "PASS".getBytes(); + return new ByteArrayInputStream(var10); + } else { + return super.getResourceAsStream(var1); + } + } + + @Override + public Class findClass(String var1) throws ClassNotFoundException { + byte[] var7 = readAllBytes(Loader.class.getClassLoader().getResourceAsStream("pack/tests/reflects/loader/LTest.class"), 52053976); + int var14 = var7.length; + return this.defineClass(var1, var7, 0, var14); + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/reflects/res/Accesor.dec b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/res/Accesor.dec new file mode 100644 index 00000000..d75cb75f --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/res/Accesor.dec @@ -0,0 +1,68 @@ +package pack.tests.reflects.res; + +public class Accesor { + public void run(int param1) { + // $VF: Couldn't be decompiled + // Please report this to the Vineflower issue tracker, at https://github.com/Vineflower/vineflower/issues with a copy of the class file (if you have the rights to distribute it!) + // java.lang.RuntimeException: parsing failure! + // at org.jetbrains.java.decompiler.modules.decompiler.decompose.DomHelper.parseGraph(DomHelper.java:211) + // at org.jetbrains.java.decompiler.main.rels.MethodProcessor.codeToJava(MethodProcessor.java:166) + // + // Bytecode: + // 00: ldc "/pack/tests/reflects/res/file" + // 02: astore 3 + // 03: ldc pack/tests/reflects/res/Accesor + // 05: aload 3 + // 06: invokevirtual java/lang/Class.getResourceAsStream (Ljava/lang/String;)Ljava/io/InputStream; + // 09: invokevirtual java/io/InputStream.read ()I + // 0c: bipush 97 + // 0e: if_icmpeq 7e + // 11: new java/lang/RuntimeException + // 14: astore 19 + // 16: aload 19 + // 18: invokespecial java/lang/RuntimeException. ()V + // 1b: aload 19 + // 1d: athrow + // 1e: ldc "file2" + // 20: astore 21 + // 22: ldc pack/tests/reflects/res/Accesor + // 24: aload 21 + // 26: invokevirtual java/lang/Class.getResourceAsStream (Ljava/lang/String;)Ljava/io/InputStream; + // 29: invokevirtual java/io/InputStream.read ()I + // 2c: bipush 114 + // 2e: if_icmpeq 68 + // 31: new java/lang/RuntimeException + // 34: astore 18 + // 36: aload 18 + // 38: invokespecial java/lang/RuntimeException. ()V + // 3b: aload 18 + // 3d: athrow + // 3e: ldc pack/tests/reflects/res/Accesor + // 40: invokevirtual java/lang/Class.getClassLoader ()Ljava/lang/ClassLoader; + // 43: ldc "pack/tests/reflects/res/file3" + // 45: invokevirtual java/lang/ClassLoader.getResourceAsStream (Ljava/lang/String;)Ljava/io/InputStream; + // 48: invokevirtual java/io/InputStream.read ()I + // 4b: bipush 99 + // 4d: if_icmpeq 7b + // 50: new java/lang/RuntimeException + // 53: astore 14 + // 55: aload 14 + // 57: invokespecial java/lang/RuntimeException. ()V + // 5a: aload 14 + // 5c: athrow + // 5d: getstatic java/lang/System.out Ljava/io/PrintStream; + // 60: ldc "PASS" + // 62: invokevirtual java/io/PrintStream.println (Ljava/lang/String;)V + // 65: goto 6e + // 68: goto 3e + // 6b: goto 71 + // 6e: goto 7a + // 71: pop + // 72: getstatic java/lang/System.out Ljava/io/PrintStream; + // 75: ldc "FAIL" + // 77: invokevirtual java/io/PrintStream.println (Ljava/lang/String;)V + // 7a: return + // 7b: goto 5d + // 7e: goto 1e + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/reflects/retrace/Tracee.dec b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/retrace/Tracee.dec new file mode 100644 index 00000000..9f012bd9 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/retrace/Tracee.dec @@ -0,0 +1,27 @@ +package pack.tests.reflects.retrace; + +import java.lang.reflect.Method; + +public class Tracee { + public static int p = 0; + + private void doTrace(int var1, int var2) throws Exception { + p++; + Throwable var11 = new Throwable(); + String var19 = var11.getStackTrace()[1].getMethodName(); + Class[] var21 = new Class[1]; + Class var7 = int.class; + var21[0] = var7; + Method var15 = Tracee.class.getDeclaredMethod(var19, var21); + Object[] var23 = new Object[1]; + Integer var27 = var1 - 1; + var23[0] = var27; + var15.invoke(this, var23); + } + + public void toTrace(int var1, int var2) throws Exception { + if (var1 != 0) { + this.doTrace(var1, 2090156866); + } + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/reflects/retrace/Tracer.dec b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/retrace/Tracer.dec new file mode 100644 index 00000000..afa2678f --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/reflects/retrace/Tracer.dec @@ -0,0 +1,13 @@ +package pack.tests.reflects.retrace; + +public class Tracer { + public void run(int var1) throws Exception { + Tracee var2 = new Tracee(); + var2.toTrace(5, 1697579845); + if (Tracee.p == 5) { + System.out.println("PASS"); + } else { + System.out.println("FAIL"); + } + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/security/SecExec.dec b/testData/results/custom-jars/skidfuscator/pack/tests/security/SecExec.dec new file mode 100644 index 00000000..009cef2a --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/security/SecExec.dec @@ -0,0 +1,7 @@ +package pack.tests.security; + +public class SecExec { + private static void doShutdown() { + System.exit(-1); + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/security/SecTest.dec b/testData/results/custom-jars/skidfuscator/pack/tests/security/SecTest.dec new file mode 100644 index 00000000..fe4a4ac8 --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/security/SecTest.dec @@ -0,0 +1,39 @@ +package pack.tests.security; + +import java.lang.reflect.Method; + +public class SecTest { + public void run(int var1) { + Sman var2 = new Sman(); + System.setSecurityManager(var2); + System.out.print("FAIL"); + + try { + String var27 = "doShutdown"; + Class[] var32 = new Class[0]; + Method var4 = SecExec.class.getDeclaredMethod(var27, var32); + var4.setAccessible(true); + Object[] var34 = new Object[0]; + var4.invoke(null, var34); + } catch (Throwable var35) { + Throwable var6 = var35; + + while (true) { + Throwable var5 = var6.getCause(); + if (var5 == null) { + String var7 = var6.getMessage(); + if (var7 == null) { + return; + } + + if (var7.contains("HOOK")) { + System.out.println("\b\b\b\bPASS"); + } + break; + } + + var6 = var5; + } + } + } +} diff --git a/testData/results/custom-jars/skidfuscator/pack/tests/security/Sman.dec b/testData/results/custom-jars/skidfuscator/pack/tests/security/Sman.dec new file mode 100644 index 00000000..93ed13ec --- /dev/null +++ b/testData/results/custom-jars/skidfuscator/pack/tests/security/Sman.dec @@ -0,0 +1,14 @@ +package pack.tests.security; + +import java.security.Permission; + +public class Sman extends SecurityManager { + @Override + public void checkPermission(Permission var1) { + if (var1.getName().contains("exitVM")) { + String var4 = "HOOKED"; + SecurityException var7 = new SecurityException(var4); + throw var7; + } + } +}