Skip to content

Commit a3c1248

Browse files
committed
Fixes bug in which invocation expressions did not iterate their arguments
1 parent 5cc4297 commit a3c1248

File tree

6 files changed

+89
-73
lines changed

6 files changed

+89
-73
lines changed

maple-ir/org.mapleir.ir/src/main/java/org/mapleir/ir/cfg/builder/GenerationPass.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -314,14 +314,6 @@ protected void process(LabelNode label) {
314314
}
315315
}
316316

317-
/* Custom frame generation attempt */
318-
final ExpressionPool expressionPool = new ExpressionPool(new Type[builder.graph.getLocals().getMaxLocals()]);
319-
for (int i = 0; i < builder.graph.getLocals().getMaxLocals(); i++) {
320-
expressionPool.getRenderedTypes()[i] = builder.graph.getLocals().get(i).getType();
321-
}
322-
currentBlock.setPool(expressionPool);
323-
/* End of custom frame generation */
324-
325317
// TODO: check if it should have an immediate.
326318
BasicBlock im = block.cfg.getImmediate(block);
327319
if (im != null/* && !queue.contains(im)*/) {
@@ -1391,6 +1383,11 @@ protected CopyVarStmt copy(VarExpr v, Expr e, BasicBlock b) {
13911383
protected VarExpr _var_expr(int index, Type type, boolean isStack) {
13921384
Local l = builder.graph.getLocals().get(index, isStack);
13931385
l.setType(type);
1386+
1387+
if (type == Type.DOUBLE_TYPE || type == Type.LONG_TYPE) {
1388+
builder.graph.getLocals().get(index + 1, isStack);
1389+
}
1390+
13941391
builder.locals.add(l);
13951392
return builder.factory
13961393
.var_expr()

maple-ir/org.mapleir.ir/src/main/java/org/mapleir/ir/code/ExpressionPool.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,21 @@ public ExpressionPool(Type[] renderedTypes) {
1010
this.renderedTypes = renderedTypes;
1111
}
1212

13+
public void set(final int index, final Type type) {
14+
assert index < renderedTypes.length : "Provided index is larger than allocated array! " +
15+
"(" + index + " / " + renderedTypes.length + ")";
16+
17+
final boolean weirdtype = type == Type.LONG_TYPE || type == Type.DOUBLE_TYPE;
18+
19+
assert !weirdtype || index + 1 < renderedTypes.length : "Provided expanded index is larger than allocated pool size!";
20+
21+
renderedTypes[index] = type;
22+
23+
if (weirdtype) {
24+
renderedTypes[index] = Type.VOID_TYPE;
25+
}
26+
}
27+
1328
public Type[] getRenderedTypes() {
1429
return renderedTypes;
1530
}

obfuscator/src/main/java/dev/skidfuscator/obfuscator/creator/SkidCache.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import dev.skidfuscator.obfuscator.skidasm.cfg.SkidControlFlowGraph;
55
import org.mapleir.asm.MethodNode;
66
import org.mapleir.context.IRCache;
7-
import org.mapleir.ir.cfg.ControlFlowGraph;
87

98
public class SkidCache extends IRCache {
109
public SkidCache(final Skidfuscator skidfuscator) {

obfuscator/src/main/java/dev/skidfuscator/obfuscator/creator/SkidFlowGraphDumper.java

Lines changed: 64 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,14 @@
1212
import org.mapleir.flowgraph.edges.UnconditionalJumpEdge;
1313
import org.mapleir.ir.cfg.BasicBlock;
1414
import org.mapleir.ir.cfg.ControlFlowGraph;
15+
import org.mapleir.ir.code.ExpressionPool;
1516
import org.mapleir.ir.code.Stmt;
1617
import org.mapleir.ir.code.stmt.NopStmt;
1718
import org.mapleir.ir.code.stmt.UnconditionalJumpStmt;
19+
import org.mapleir.ir.code.stmt.copy.CopyVarStmt;
1820
import org.mapleir.ir.codegen.BytecodeFrontend;
21+
import org.mapleir.ir.locals.Local;
22+
import org.mapleir.ir.utils.CFGUtils;
1923
import org.mapleir.stdlib.collections.graph.*;
2024
import org.mapleir.stdlib.collections.graph.algorithms.SimpleDfs;
2125
import org.mapleir.stdlib.collections.graph.algorithms.TarjanSCC;
@@ -68,6 +72,9 @@ public void dump() {
6872
// Sanity check linearization
6973
verifyOrdering();
7074

75+
// Compute frames
76+
computeFrames();
77+
7178
// Dump code
7279
for (BasicBlock b : order) {
7380
m.node.visitLabel(getLabel(b));
@@ -89,6 +96,63 @@ public void dump() {
8996
m.node.visitEnd();
9097
}
9198

99+
private void computeFrames() {
100+
if (cfg.getEntries().size() != 1)
101+
throw new IllegalStateException("CFG doesn't have exactly 1 entry");
102+
BasicBlock entry = cfg.getEntries().iterator().next();
103+
104+
// Bundle based iteration
105+
final Set<BasicBlock> visited = new HashSet<>();
106+
final Stack<BasicBlock> stack = new Stack<>();
107+
108+
stack.add(entry);
109+
110+
ExpressionPool frame = new ExpressionPool(new Type[cfg.getLocals().getMaxLocals() + 3]);
111+
Arrays.fill(frame.getRenderedTypes(), Type.VOID_TYPE);
112+
113+
if (cfg.getMethodNode().isStatic()) {
114+
frame.set(0, Type.getType("L" + cfg.getMethodNode().owner.getName() + ";"));
115+
}
116+
117+
entry.setPool(frame);
118+
119+
while (!stack.isEmpty()) {
120+
/* Visit the top of the stack */
121+
final BasicBlock popped = stack.pop();
122+
visited.add(popped);
123+
124+
/* Iterate all the set statements to update the frame */
125+
final ExpressionPool expressionPool = popped.getPool().copy();
126+
127+
popped.stream()
128+
.filter(CopyVarStmt.class::isInstance)
129+
.map(CopyVarStmt.class::cast)
130+
.forEach(stmt -> {
131+
expressionPool.set(stmt.getIndex(), stmt.getType());
132+
});
133+
134+
/* Add all the successor nodes */
135+
cfg.getSuccessors(popped)
136+
.filter(e -> !visited.contains(e))
137+
.forEach(e -> {
138+
/* Set the expected received pool */
139+
e.setPool(expressionPool);
140+
141+
/* Add it to the stack to be iterated again */
142+
stack.add(e);
143+
});
144+
}
145+
146+
for (BasicBlock vertex : cfg.vertices()) {
147+
if (vertex.getPool() == null) {
148+
System.out.println("Frame >>> FAILED TO COMPUTE");
149+
} else {
150+
System.out.println("Frame >>> " + Arrays.toString(vertex.getPool().getRenderedTypes()));
151+
}
152+
System.out.println(CFGUtils.printBlock(vertex));
153+
}
154+
}
155+
92156
private void fixRanges() {
93157
/*
94158
* Short term fix to prevent TryCatchNode-s from being optimized
@@ -305,69 +369,9 @@ private void dumpRange(ExceptionRange<BasicBlock> er) {
305369
}
306370

307371
classNodes.add(classNode);
308-
309-
/*final List<ClassNode> parents = skidfuscator
310-
.getClassSource()
311-
.getClassTree()
312-
.getAllParents(classNode);
313-
314-
if (stack.isEmpty()) {
315-
316-
stack.addAll(Lists.reverse(parents));
317-
} else {
318-
final Stack<ClassNode> toIterate = new Stack<>();
319-
toIterate.add(classNode);
320-
toIterate.addAll(Lists.reverse(parents));
321-
322-
runner: {
323-
while (!stack.isEmpty()) {
324-
325-
for (ClassNode node : toIterate) {
326-
if (node.getName().equals(stack.peek().getName()))
327-
break runner;
328-
}
329-
330-
stack.pop();
331-
}
332-
333-
throw new IllegalStateException("Could not find common exception type between "
334-
+ Arrays.toString(er.getTypes().toArray()));
335-
}
336-
}*/
337372
}
338373

339374
/* Simple DFS naive common ancestor algorithm */
340-
/*final ClassNode seedClassNodeForIteration = classNodes.iterator().next();
341-
final Stack<ClassNode> hierarchy = new Stack<>();
342-
hierarchy.addAll(Lists.reverse(
343-
skidfuscator
344-
.getClassSource()
345-
.getClassTree()
346-
.getAllParents(seedClassNodeForIteration)
347-
)
348-
);
349-
hierarchy.add(seedClassNodeForIteration);
350-
351-
while (true) {
352-
final Set<ClassNode> children = new HashSet<>(
353-
skidfuscator.getClassSource()
354-
.getClassTree()
355-
.getAllChildren(hierarchy.peek())
356-
);
357-
358-
if (children.containsAll(classNodes)) {
359-
break;
360-
}
361-
362-
System.err.println("Failed for " + hierarchy.peek().getName());
363-
System.err.println("Looking for: " + Arrays.toString(classNodes.stream().map(ClassNode::getName).toArray()));
364-
for (ClassNode child : children) {
365-
System.err.println(" -> " + child.getName());
366-
}
367-
368-
hierarchy.pop();
369-
}*/
370-
371375
final Collection<ClassNode> commonAncestors = skidfuscator
372376
.getClassSource()
373377
.getClassTree()

obfuscator/src/main/java/dev/skidfuscator/obfuscator/predicate/renderer/impl/IntegerBlockPredicateRenderer.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ void handle(final PostMethodTransformEvent event) {
588588
exception,
589589
ConditionalJumpStmt.ComparisonType.NE
590590
);
591-
cfg.addEdge(new ConditionalJumpEdge<>(entryPoint, exception, Opcodes.GOTO));
591+
cfg.addEdge(new ConditionalJumpEdge<>(entryPoint, exception, Opcodes.IFNE));
592592
entryPoint.add(1, jumpStmt);
593593
}
594594

@@ -601,7 +601,7 @@ void handle(final PostMethodTransformEvent event) {
601601
exception,
602602
ConditionalJumpStmt.ComparisonType.NE
603603
);
604-
cfg.addEdge(new ConditionalJumpEdge<>(entryPoint, exception, Opcodes.GOTO));
604+
cfg.addEdge(new ConditionalJumpEdge<>(entryPoint, exception, Opcodes.IFNE));
605605
entryPoint.add(0, jumpStmt);
606606
}
607607

@@ -722,7 +722,7 @@ void handle(final PostMethodTransformEvent event) {
722722

723723
// Replace successor
724724
stmt.setTrueSuccessor(basicBlock);
725-
basicBlock.cfg.addEdge(new ConditionalJumpEdge<>(block, basicBlock, stmt.getOpcode()));
725+
basicBlock.cfg.addEdge(new ConditionalJumpEdge<>(block, basicBlock, Opcodes.IF_ICMPEQ));
726726

727727
if (DEBUG) {
728728
final Local local1 = basicBlock.cfg.getLocals().get(block.cfg.getLocals().getMaxLocals() + 2);

obfuscator/src/main/java/dev/skidfuscator/obfuscator/transform/impl/flow/BasicConditionTransformer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.mapleir.ir.code.stmt.UnconditionalJumpStmt;
3030
import org.mapleir.ir.code.stmt.copy.CopyVarStmt;
3131
import org.mapleir.ir.locals.Local;
32+
import org.objectweb.asm.Opcodes;
3233
import org.objectweb.asm.Type;
3334

3435
import java.util.*;
@@ -103,7 +104,7 @@ void handle(final RunMethodTransformEvent event) {
103104
cfg.addEdge(new ConditionalJumpEdge<>(
104105
basicBlock,
105106
target,
106-
conditionalJumpStmt.getOpcode()
107+
Opcodes.IFEQ
107108
));
108109

109110
// Replace the edge

0 commit comments

Comments
 (0)