Skip to content

Linearization perfected + Number obfuscation #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.google.common.collect.Streams;
import dev.skidfuscator.obf.init.SkidSession;
import dev.skidfuscator.obf.maple.FakeConditionalJumpStmt;
import dev.skidfuscator.obf.skidasm.NoNoSkidMethod;
import dev.skidfuscator.obf.skidasm.v2.SStorage;
import dev.skidfuscator.obf.transform.impl.ProjectPass;
Expand Down Expand Up @@ -49,10 +50,7 @@ public void render(final SkidSession skidSession) {
projectPass.pass(skidSession);
}

logger.log("[*] Passing fun passes...");
for (ProjectPass projectPass : projectPasses) {
projectPass.pass(skidSession);
}


final List<ClassNode> nodeList = Streams.stream(skidSession.getClassSource().iterate())
.parallel()
Expand Down Expand Up @@ -180,11 +178,13 @@ public void render(final SkidSession skidSession) {
logger.log("[*] Finished initial seed of " + skidMethods.size() + " methods");
logger.post("[*] Gen3 Flow... Beginning obfuscation...");
final FlowPass[] flowPasses = new FlowPass[]{
//new NumberMutatorPass(),
//new SwitchMutatorPass(),
//new ConditionMutatorPass(),
//new FakeExceptionJumpFlowPass(),
//new FakeJumpFlowPass(),
new NumberMutatorPass(),
new SwitchMutatorPass(),
//new FakeTryCatchFlowPass(),
//new ConditionV2MutatorPass(),
new ConditionMutatorPass(),
new FakeExceptionJumpFlowPass(),
new FakeJumpFlowPass(),
new SeedFlowPass(),
};

Expand Down Expand Up @@ -220,6 +220,14 @@ public void render(final SkidSession skidSession) {
+ "]");
}

logger.log("[*] Passing fun passes...");
for (ProjectPass projectPass : projectPasses) {
projectPass.pass(skidSession);
logger.log(" [@G3#flow] Finished running "
+ projectPass.getName()
+ " [Changed: " + skidSession.popCount()
+ "]");
}

logger.log("[*] Linearizing GEN3...");

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package dev.skidfuscator.obf.maple;

import org.mapleir.ir.cfg.BasicBlock;
import org.mapleir.ir.cfg.ControlFlowGraph;

public class FakeBlock extends BasicBlock {
public FakeBlock(ControlFlowGraph cfg) {
super(cfg);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package dev.skidfuscator.obf.maple;

import org.mapleir.flowgraph.edges.ConditionalJumpEdge;
import org.mapleir.stdlib.collections.graph.FastGraphVertex;

public class FakeConditionalJumpEdge<N extends FastGraphVertex> extends ConditionalJumpEdge<N> {
public FakeConditionalJumpEdge(N src, N dst, int opcode) {
super(src, dst, opcode);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package dev.skidfuscator.obf.maple;

import org.mapleir.ir.cfg.BasicBlock;
import org.mapleir.ir.code.stmt.UnconditionalJumpStmt;

public class FakeUnconditionalJumpStmt extends UnconditionalJumpStmt {
public FakeUnconditionalJumpStmt(BasicBlock target) {
super(target);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package dev.skidfuscator.obf.skidasm;

import dev.skidfuscator.obf.maple.FakeBlock;
import dev.skidfuscator.obf.maple.FakeConditionalJumpEdge;
import dev.skidfuscator.obf.maple.FakeConditionalJumpStmt;
import dev.skidfuscator.obf.maple.FakeUnconditionalJumpStmt;
import dev.skidfuscator.obf.number.NumberManager;
import dev.skidfuscator.obf.number.encrypt.impl.XorNumberTransformer;
import dev.skidfuscator.obf.number.hash.HashTransformer;
Expand Down Expand Up @@ -37,7 +40,8 @@ public class SkidGraph {
@Getter
private Local local;
private final Map<BasicBlock, SkidBlock> cache = new HashMap<>();
private final Set<LinearLink> linearLinks = new HashSet<>();

public static final boolean DEBUG = false;

public SkidGraph(MethodNode node, SkidMethod method) {
this.node = node;
Expand Down Expand Up @@ -73,7 +77,6 @@ public void postlinearize(final ControlFlowGraph cfg) {
// Phase 2
linearize(cfg);

range(cfg, local);
linkage(cfg, local);

/*BasicBlock next = cfg.verticesInOrder().iterator().next();
Expand All @@ -97,6 +100,9 @@ public void postlinearize(final ControlFlowGraph cfg) {
}*/

for (BasicBlock vertex : cfg.vertices()) {
if (vertex instanceof FakeBlock)
continue;

cfg.getEdges(vertex).stream()
.filter(e -> e instanceof ImmediateEdge)
.forEach(e -> {
Expand Down Expand Up @@ -132,17 +138,17 @@ public void postlinearize(final ControlFlowGraph cfg) {
}
}*/

for (BasicBlock block : cfg.vertices()) {
final SkidBlock targetSeededBlock = getBlock(block);
/*final Local local1 = block.cfg.getLocals().get(block.cfg.getLocals().getMaxLocals() + 2);
block.add(0, new CopyVarStmt(new VarExpr(local1, Type.getType(String.class)),
new ConstantExpr(block.getDisplayName() +" : c-var - begin : " + targetSeededBlock.getSeed())));
final Local local2 = block.cfg.getLocals().get(block.cfg.getLocals().getMaxLocals() + 2);
block.add(block.size() - 1, new CopyVarStmt(new VarExpr(local2, Type.getType(String.class)),
new ConstantExpr(block.getDisplayName() +" : c-var - end : " + targetSeededBlock.getSeed())));
*/
if (DEBUG) {
for (BasicBlock block : cfg.vertices()) {
final SkidBlock targetSeededBlock = getBlock(block);
final Local local1 = block.cfg.getLocals().get(block.cfg.getLocals().getMaxLocals() + 2);
block.add(0, new CopyVarStmt(new VarExpr(local1, Type.getType(String.class)),
new ConstantExpr(block.getDisplayName() +" : c-var - begin : " + targetSeededBlock.getSeed())));
final Local local2 = block.cfg.getLocals().get(block.cfg.getLocals().getMaxLocals() + 2);
block.add(block.size() - 1, new CopyVarStmt(new VarExpr(local2, Type.getType(String.class)),
new ConstantExpr(block.getDisplayName() +" : c-var - end : " + targetSeededBlock.getSeed())));
}
}

}

private void linearize(final ControlFlowGraph cfg) {
Expand All @@ -165,11 +171,19 @@ private void linkage(final ControlFlowGraph cfg, final Local local) {
});
}

for (BasicBlock entry : cfg.vertices()) {
range(cfg, local);

for (BasicBlock entry : new HashSet<>(cfg.vertices())) {
new HashSet<>(entry).forEach(e -> {
if (e instanceof UnconditionalJumpStmt) {
if (e instanceof UnconditionalJumpStmt && !(e instanceof FakeUnconditionalJumpStmt)) {
addSeedToUncJump(local, entry, (UnconditionalJumpStmt) e);
} else if (e instanceof ConditionalJumpStmt && !(e instanceof FakeConditionalJumpStmt)) {
}
});
}

for (BasicBlock entry : new HashSet<>(cfg.vertices())) {
new HashSet<>(entry).forEach(e -> {
if (e instanceof ConditionalJumpStmt && !(e instanceof FakeConditionalJumpStmt)) {
addSeedToCondJump(local, entry, (ConditionalJumpStmt) e);
}
});
Expand Down Expand Up @@ -228,10 +242,13 @@ private void addSeedToImmediate(final Local local, final BasicBlock block, final
final SkidBlock seededBlock = getBlock(block);
final SkidBlock targetSeededBlock = getBlock(immediate);
seededBlock.addSeedLoader(-1, local, seededBlock.getSeed(), targetSeededBlock.getSeed());
/*final Local local1 = block.cfg.getLocals().get(block.cfg.getLocals().getMaxLocals() + 2);
block.add(block.size(), new CopyVarStmt(new VarExpr(local1, Type.getType(String.class)),
new ConstantExpr(block.getDisplayName() +" : c-loc - immediate : " + targetSeededBlock.getSeed())));
*/

if (DEBUG) {
final Local local1 = block.cfg.getLocals().get(block.cfg.getLocals().getMaxLocals() + 2);
block.add(block.size(), new CopyVarStmt(new VarExpr(local1, Type.getType(String.class)),
new ConstantExpr(block.getDisplayName() +" : c-loc - immediate : " + targetSeededBlock.getSeed())));
}

// Ignore, this is for debugging
/*
final Local local1 = block.cfg.getLocals().get(block.cfg.getLocals().getMaxLocals() + 2);
Expand All @@ -248,10 +265,12 @@ private void addSeedToUncJump(final Local local, final BasicBlock block, final U
final SkidBlock targetSeededBlock = getBlock(stmt.getTarget());
seededBlock.addSeedLoader(index, local, seededBlock.getSeed(), targetSeededBlock.getSeed());

/*final Local local1 = block.cfg.getLocals().get(block.cfg.getLocals().getMaxLocals() + 2);
block.add(index, new CopyVarStmt(new VarExpr(local1, Type.getType(String.class)),
new ConstantExpr(block.getDisplayName() +" : c-loc - uncond : " + targetSeededBlock.getSeed())));
*/
if (DEBUG) {
final Local local1 = block.cfg.getLocals().get(block.cfg.getLocals().getMaxLocals() + 2);
block.add(index, new CopyVarStmt(new VarExpr(local1, Type.getType(String.class)),
new ConstantExpr(block.getDisplayName() +" : c-loc - uncond : " + targetSeededBlock.getSeed())));
}

/*
final Local local1 = block.cfg.getLocals().get(block.cfg.getLocals().getMaxLocals() + 2);
block.add(new CopyVarStmt(new VarExpr(local1, Type.getType(String.class)),
Expand All @@ -262,7 +281,7 @@ private void addSeedToUncJump(final Local local, final BasicBlock block, final U
private void addSeedToCondJump(final Local local, final BasicBlock block, final ConditionalJumpStmt stmt) {
// Todo Add support for various different types of conditional jumps
// support such as block splitting and shit to mess with reversers
if (true) {
if (false) {
final SkidBlock seededBlock = getBlock(block);
final SkidBlock targetSeededBlock = getBlock(stmt.getTrueSuccessor());

Expand All @@ -286,7 +305,7 @@ private void addSeedToCondJump(final Local local, final BasicBlock block, final
}

final ConditionalJumpEdge<BasicBlock> edge = block.cfg.getEdges(block).stream()
.filter(e -> !(e instanceof ImmediateEdge))
.filter(e -> e instanceof ConditionalJumpEdge && !(e instanceof FakeConditionalJumpEdge))
.map(e -> (ConditionalJumpEdge<BasicBlock>) e)
.filter(e -> e.dst().equals(stmt.getTrueSuccessor()))
.findFirst()
Expand All @@ -311,6 +330,12 @@ private void addSeedToCondJump(final Local local, final BasicBlock block, final
// Replace successor
stmt.setTrueSuccessor(basicBlock);
block.cfg.addEdge(new ConditionalJumpEdge<>(block, basicBlock, stmt.getOpcode()));

if (DEBUG) {
final Local local1 = block.cfg.getLocals().get(block.cfg.getLocals().getMaxLocals() + 2);
block.add(block.indexOf(stmt), new CopyVarStmt(new VarExpr(local1, Type.getType(String.class)),
new ConstantExpr(block.getDisplayName() +" : c-loc - cond : " + targetSeeded.getSeed())));
}
//seededBlock.addSeedLoader(index + 2, local, targetSeededBlock.getSeed(), seededBlock.getSeed());
}

Expand Down Expand Up @@ -356,15 +381,15 @@ private void addSeedToRange(final Local local, final ControlFlowGraph cfg, final
final SkidBlock internal = getBlock(node);

// Create a new switch block and get it's seeded variant
final BasicBlock block = new BasicBlock(cfg);
final BasicBlock block = new FakeBlock(cfg);
cfg.addVertex(block);
final SkidBlock seededBlock = getBlock(block);

// Add a seed loader for the incoming block and convert it to the handler's
seededBlock.addSeedLoader(0, local, internal.getSeed(), handler.getSeed());

// Jump to handler
block.add(new UnconditionalJumpStmt(basicHandler));
block.add(new FakeUnconditionalJumpStmt(basicHandler));
cfg.addEdge(new UnconditionalJumpEdge<>(block, basicHandler));

// Final hashed
Expand All @@ -391,7 +416,7 @@ private void addSeedToRange(final Local local, final ControlFlowGraph cfg, final
// Haha get fucked
// Todo Fix the other shit to re-enable this; this is for the lil shits
// (love y'all tho) that are gonna try reversing this
for (int i = 0; i < 10; i++) {
/*for (int i = 0; i < 10; i++) {
// Generate random seed + prevent conflict
final int seed = RandomUtil.nextInt();
if (sortedList.contains(seed))
Expand All @@ -412,7 +437,7 @@ private void addSeedToRange(final Local local, final ControlFlowGraph cfg, final

basicBlockMap.put(seed, block);
cfg.addEdge(new SwitchEdge<>(handler.getBlock(), block, seed));
}
}*/

// Hash
final Expr hash = hashTransformer.hash(local);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package dev.skidfuscator.obf.transform.impl.fixer;

import dev.skidfuscator.obf.init.SkidSession;
import dev.skidfuscator.obf.skidasm.SkidGraph;
import dev.skidfuscator.obf.skidasm.SkidMethod;
import dev.skidfuscator.obf.transform.impl.flow.FlowPass;
import org.mapleir.flowgraph.edges.DefaultSwitchEdge;
import org.mapleir.flowgraph.edges.UnconditionalJumpEdge;
import org.mapleir.ir.cfg.BasicBlock;
import org.mapleir.ir.cfg.ControlFlowGraph;
import org.mapleir.ir.code.Stmt;
import org.mapleir.ir.code.stmt.SwitchStmt;
import org.mapleir.ir.code.stmt.UnconditionalJumpStmt;

import java.util.HashSet;

public class ReturnFixerPass implements FlowPass {
@Override
public void pass(SkidSession session, SkidMethod method) {
for (SkidGraph methodNode : method.getMethodNodes()) {
final ControlFlowGraph cfg = session.getCxt().getIRCache().get(methodNode.getNode());

if (cfg == null)
continue;


}
}

@Override
public String getName() {
return "Switch Fixer";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import dev.skidfuscator.obf.init.SkidSession;
import dev.skidfuscator.obf.maple.FakeArithmeticExpr;
import dev.skidfuscator.obf.maple.FakeConditionalJumpStmt;
import dev.skidfuscator.obf.number.NumberManager;
import dev.skidfuscator.obf.number.hash.HashTransformer;
import dev.skidfuscator.obf.number.hash.SkiddedHash;
Expand Down
Loading