Skip to content

Commit b5164ab

Browse files
committed
Much optimizations :kappa:, shitty multithreading (WIP) + some core improvements
1 parent 5709527 commit b5164ab

16 files changed

+460
-44
lines changed

dev.skidfuscator.obfuscator/pom.xml

+6
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@
6565
<version>1.18.16</version>
6666
<scope>provided</scope>
6767
</dependency>
68+
<dependency>
69+
<groupId>me.tongfei</groupId>
70+
<artifactId>progressbar</artifactId>
71+
<version>0.9.2</version>
72+
</dependency>
73+
6874
</dependencies>
6975

7076
</project>

dev.skidfuscator.obfuscator/src/main/java/dev/skidfuscator/obf/SkidMethodRenderer.java

+78-44
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22

33
import com.google.common.collect.Streams;
44
import dev.skidfuscator.obf.init.SkidSession;
5+
import dev.skidfuscator.obf.skidasm.NoNoSkidMethod;
6+
import dev.skidfuscator.obf.skidasm.v2.SStorage;
57
import dev.skidfuscator.obf.transform.impl.fixer.ExceptionFixerPass;
68
import dev.skidfuscator.obf.transform.impl.fixer.SwitchFixerPass;
79
import dev.skidfuscator.obf.transform.impl.flow.*;
10+
import dev.skidfuscator.obf.utils.ProgressUtil;
811
import dev.skidfuscator.obf.utils.TimedLogger;
912
import dev.skidfuscator.obf.yggdrasil.caller.CallerType;
1013
import dev.skidfuscator.obf.transform.impl.flow.gen3.SeedFlowPass;
@@ -13,6 +16,7 @@
1316
import dev.skidfuscator.obf.skidasm.SkidInvocation;
1417
import dev.skidfuscator.obf.skidasm.SkidMethod;
1518
import dev.skidfuscator.obf.utils.OpcodeUtil;
19+
import me.tongfei.progressbar.ProgressBar;
1620
import org.apache.log4j.LogManager;
1721
import org.mapleir.asm.ClassNode;
1822
import org.mapleir.asm.MethodNode;
@@ -25,6 +29,7 @@
2529

2630
public class SkidMethodRenderer {
2731
private final Set<MethodNode> methodNodes = new HashSet<>();
32+
private final SStorage storage = new SStorage();
2833
private final Map<MethodNode, SkidMethod> skidMethodMap = new HashMap<>();
2934
private final TimedLogger logger = new TimedLogger(LogManager.getLogger(this.getClass()));
3035

@@ -36,52 +41,67 @@ public void render(final SkidSession skidSession) {
3641
.filter(e -> skidSession.getClassSource().isApplicationClass(e.getName()))
3742
.collect(Collectors.toList());
3843

39-
for (ClassNode classNode : nodeList) {
40-
methodNodes.addAll(classNode.getMethods());
41-
}
44+
nodeList.parallelStream().forEach(e -> methodNodes.addAll(e.getMethods()));
4245
logger.log("Finished initial load");
46+
storage.cache(skidSession);
4347
logger.post("Beginning method load...");
4448

45-
methodNodes.stream().parallel().forEach(methodNode -> {
46-
final Set<MethodNode> hierarchy = skidSession.getCxt().getInvocationResolver()
47-
.getHierarchyMethodChain(methodNode.owner, methodNode.getName(), methodNode.getDesc(), true);
49+
try (ProgressBar bar = ProgressUtil.progress(methodNodes.size())){
50+
methodNodes.stream().parallel().forEach(methodNode -> {
51+
final Set<MethodNode> hierarchy = skidSession.getCxt().getInvocationResolver()
52+
.getHierarchyMethodChain(methodNode.owner, methodNode.getName(), methodNode.getDesc(), true);
4853

49-
hierarchy.add(methodNode);
54+
hierarchy.add(methodNode);
5055

51-
if (hierarchy.isEmpty()) {
52-
System.out.println("/!\\ Method " + methodNode.getDisplayName() + " is empty!");
53-
return;
54-
}
56+
if (hierarchy.isEmpty()) {
57+
System.out.println("/!\\ Method " + methodNode.getDisplayName() + " is empty!");
58+
bar.step();
59+
return;
60+
}
61+
62+
SkidMethod method = null;
5563

56-
SkidMethod method = null;
64+
for (MethodNode node : hierarchy) {
65+
if (skidMethodMap.containsKey(node)) {
66+
method = skidMethodMap.get(node);
67+
break;
68+
}
69+
if (node.node.instructions.size() > 6000) {
70+
bar.step();
5771

58-
for (MethodNode node : hierarchy) {
59-
if (skidMethodMap.containsKey(node)) {
60-
method = skidMethodMap.get(node);
61-
break;
72+
for (MethodNode methodNode1 : hierarchy) {
73+
skidMethodMap.put(methodNode1, new NoNoSkidMethod());
74+
}
75+
76+
return;
77+
}
6278
}
63-
}
6479

65-
if (method == null) {
66-
final boolean contains = methodNodes.containsAll(hierarchy);
67-
final CallerType type;
68-
if (!contains || OpcodeUtil.isSynthetic(methodNode)) {
69-
type = CallerType.LIBRARY;
70-
} else {
71-
final boolean entry = methodNode.getName().equals("<init>") || hierarchy.stream().anyMatch(e -> skidSession.getEntryPoints().contains(e));
80+
if (method == null) {
81+
final boolean contains = methodNodes.containsAll(hierarchy);
82+
final CallerType type;
83+
if (!contains || OpcodeUtil.isSynthetic(methodNode)) {
84+
type = CallerType.LIBRARY;
85+
} else {
86+
final boolean entry = methodNode.getName().equals("<init>") || hierarchy.stream().anyMatch(e -> skidSession.getEntryPoints().contains(e));
7287

73-
type = entry ? CallerType.ENTRY : CallerType.APPLICATION;
88+
type = entry ? CallerType.ENTRY : CallerType.APPLICATION;
89+
}
90+
91+
method = new SkidMethod(new HashSet<>(hierarchy), type, new HashSet<>());
7492
}
7593

76-
method = new SkidMethod(new HashSet<>(hierarchy), type, new HashSet<>());
77-
}
94+
skidMethodMap.put(methodNode, method);
95+
bar.step();
96+
});
97+
}
7898

79-
skidMethodMap.put(methodNode, method);
80-
});
8199

82100
logger.log("Finished loading " + skidMethodMap.size() + " methods");
83101
logger.post("Beginning method mapping...");
84-
for (MethodNode method : methodNodes) {
102+
103+
try (ProgressBar bar = ProgressUtil.progress(methodNodes.size())) {
104+
methodNodes.parallelStream().forEach(method -> {
85105
final ControlFlowGraph cfg = skidSession.getCxt().getIRCache().getFor(method);
86106
cfg.allExprStream()
87107
.filter(e -> e instanceof InvocationExpr)
@@ -111,11 +131,17 @@ public void render(final SkidSession skidSession) {
111131
}
112132

113133
});
134+
bar.step();
135+
});
114136
}
115137

116138
logger.log("Finished mapping " + skidMethodMap.size() + " methods");
117139
logger.post("[*] Gen3 bootstrapping... Beginning seeding...");
118-
final List<SkidMethod> skidMethods = skidMethodMap.values().stream().distinct().collect(Collectors.toList());
140+
final List<SkidMethod> skidMethods = skidMethodMap.values()
141+
.stream()
142+
.filter(e -> !(e instanceof NoNoSkidMethod))
143+
.distinct()
144+
.collect(Collectors.toList());
119145

120146
/*skidMethods.forEach(e -> {
121147
System.out.println("(Repository) Added group of size " + e.getMethodNodes().size() + " of name " + e.getModal().getName());
@@ -155,8 +181,8 @@ public void render(final SkidSession skidSession) {
155181
});
156182

157183
// Fix retarded exceptions
158-
skidMethods.forEach(e -> e.renderPrivate(skidSession));
159-
skidMethods.forEach(e -> {
184+
skidMethods.parallelStream().forEach(e -> e.renderPrivate(skidSession));
185+
skidMethods.parallelStream().forEach(e -> {
160186
for (SkidGraph methodNode : e.getMethodNodes()) {
161187
if (methodNode.getNode().isAbstract())
162188
continue;
@@ -175,20 +201,28 @@ public void render(final SkidSession skidSession) {
175201
+ "]");
176202
}
177203

178-
skidMethods.forEach(e -> {
179-
for (SkidGraph methodNode : e.getMethodNodes()) {
180-
if (methodNode.getNode().isAbstract())
181-
continue;
182-
final ControlFlowGraph cfg = skidSession.getCxt().getIRCache().get(methodNode.getNode());
183-
if (cfg == null)
184-
continue;
185-
methodNode.postlinearize(cfg);
186-
}
187-
});
204+
logger.log("[*] Linearizing GEN3...");
205+
206+
try (ProgressBar progressBar = ProgressUtil.progress(skidMethods.size())){
207+
skidMethods.parallelStream().forEach(e -> {
208+
e.getMethodNodes().stream().parallel().forEach(methodNode -> {
209+
if (methodNode.getNode().isAbstract())
210+
return;
211+
final ControlFlowGraph cfg = skidSession.getCxt().getIRCache().get(methodNode.getNode());
212+
if (cfg == null)
213+
return;
214+
methodNode.postlinearize(cfg);
215+
});
216+
217+
progressBar.step();
218+
});
219+
220+
}
221+
188222

189223

190224

191-
skidMethods.forEach(e -> e.renderPublic(skidSession));
225+
skidMethods.parallelStream().forEach(e -> e.renderPublic(skidSession));
192226
logger.log("[*] Finished Gen3 flow obfuscation");
193227

194228
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package dev.skidfuscator.obf.skidasm;
2+
3+
import dev.skidfuscator.obf.yggdrasil.caller.CallerType;
4+
import org.mapleir.asm.MethodNode;
5+
6+
import java.util.HashSet;
7+
import java.util.Set;
8+
9+
public class NoNoSkidMethod extends SkidMethod{
10+
public NoNoSkidMethod() {
11+
super(new HashSet<>(), null, null);
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package dev.skidfuscator.obf.skidasm;
2+
3+
import lombok.Data;
4+
import org.mapleir.asm.ClassNode;
5+
6+
import java.util.List;
7+
8+
@Data
9+
public class SkidGroup {
10+
private final List<SkidClass> graphs;
11+
private boolean isInherited;
12+
13+
public SkidGroup(List<SkidClass> graphs, boolean isInherited) {
14+
this.graphs = graphs;
15+
this.isInherited = isInherited;
16+
}
17+
}

dev.skidfuscator.obfuscator/src/main/java/dev/skidfuscator/obf/skidasm/SkidInvocation.java

+18
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,22 @@
99
public class SkidInvocation {
1010
private final SkidMethod methodNode;
1111
private final InvocationExpr invocationExpr;
12+
13+
@Override
14+
public boolean equals(Object o) {
15+
if (this == o) return true;
16+
if (o == null || getClass() != o.getClass()) return false;
17+
18+
SkidInvocation that = (SkidInvocation) o;
19+
20+
if (methodNode != null ? !methodNode.equals(that.methodNode) : that.methodNode != null) return false;
21+
return invocationExpr != null ? invocationExpr.equals(that.invocationExpr) : that.invocationExpr == null;
22+
}
23+
24+
@Override
25+
public int hashCode() {
26+
int result = methodNode != null ? methodNode.hashCode() : 0;
27+
result = 31 * result + (invocationExpr != null ? invocationExpr.hashCode() : 0);
28+
return result;
29+
}
1230
}

dev.skidfuscator.obfuscator/src/main/java/dev/skidfuscator/obf/skidasm/SkidMethod.java

+3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ public SkidMethod(Set<MethodNode> methodNodes, CallerType callerType, Set<SkidIn
3232
this.methodNodes = methodNodes.stream().map(e -> new SkidGraph(e, this)).collect(Collectors.toList());
3333
this.callerType = callerType;
3434
this.invocationModal = invocationModal;
35+
36+
if (methodNodes.isEmpty())
37+
return;
3538
this.modal = this.methodNodes.get(0).getNode();
3639
this.parameter = new Parameter(modal.getDesc());
3740
this.classStatic = OpcodeUtil.isStatic(modal);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package dev.skidfuscator.obf.skidasm.v2;
2+
3+
import dev.skidfuscator.obf.init.SkidSession;
4+
5+
public interface Renderable {
6+
void render(final SkidSession session);
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package dev.skidfuscator.obf.skidasm.v2;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
public class SApplication {
7+
private final Map<String, SClass> classes = new HashMap<>();
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package dev.skidfuscator.obf.skidasm.v2;
2+
3+
import dev.skidfuscator.obf.init.SkidSession;
4+
import lombok.Data;
5+
import org.mapleir.ir.cfg.BasicBlock;
6+
import org.mapleir.ir.cfg.ControlFlowGraph;
7+
8+
@Data
9+
public class SBlock implements Renderable {
10+
private final BasicBlock block;
11+
private final int seed;
12+
13+
public SBlock(BasicBlock block, int seed) {
14+
this.block = block;
15+
this.seed = seed;
16+
}
17+
18+
@Override
19+
public void render(SkidSession session) {
20+
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package dev.skidfuscator.obf.skidasm.v2;
2+
3+
import dev.skidfuscator.obf.init.SkidSession;
4+
import lombok.Data;
5+
import org.mapleir.asm.ClassNode;
6+
import org.mapleir.asm.MethodNode;
7+
8+
import java.util.ArrayList;
9+
import java.util.HashMap;
10+
import java.util.List;
11+
import java.util.Map;
12+
13+
@Data
14+
public class SClass implements Renderable {
15+
private final ClassNode parent;
16+
private final List<SClass> classes;
17+
private final List<SMethodGroup> methodGroups;
18+
19+
public SClass(ClassNode parent, List<SClass> classes, List<SMethodGroup> methodGroups) {
20+
this.parent = parent;
21+
this.classes = classes;
22+
this.methodGroups = methodGroups;
23+
}
24+
25+
@Override
26+
public void render(SkidSession session) {
27+
for (SMethodGroup methodGroup : methodGroups) {
28+
methodGroup.render(session);
29+
}
30+
}
31+
32+
public static void create(final SkidSession session, final ClassNode node) {
33+
final List<ClassNode> heredity = new ArrayList<>(session.getClassSource().getClassTree().getAllBranches(node));
34+
final Map<MethodNode, List<MethodNode>> methodHeredity = new HashMap<>();
35+
36+
for (MethodNode method : node.getMethods()) {
37+
final List<MethodNode> h = new ArrayList<>(session.getCxt().getInvocationResolver()
38+
.getHierarchyMethodChain(node, method.getName(), method.getDesc(), true));
39+
40+
methodHeredity.put(method, h);
41+
}
42+
}
43+
44+
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package dev.skidfuscator.obf.skidasm.v2;
2+
3+
import dev.skidfuscator.obf.init.SkidSession;
4+
import org.mapleir.asm.ClassNode;
5+
6+
import java.util.List;
7+
8+
public class SClassGroup implements Renderable {
9+
private final List<SClass> classes;
10+
11+
public SClassGroup(List<SClass> methods) {
12+
this.classes = methods;
13+
}
14+
15+
@Override
16+
public void render(SkidSession session) {
17+
for (SClass method : classes) {
18+
method.render(session);
19+
}
20+
}
21+
22+
public static void create(final SkidSession session, final ClassNode sample) {}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package dev.skidfuscator.obf.skidasm.v2;
2+
3+
import lombok.Data;
4+
import org.mapleir.ir.code.expr.invoke.InvocationExpr;
5+
6+
@Data
7+
public class SInvocation {
8+
private final InvocationExpr expr;
9+
10+
public SInvocation(InvocationExpr expr) {
11+
this.expr = expr;
12+
}
13+
}

0 commit comments

Comments
 (0)