Skip to content

Commit ce19ee1

Browse files
committed
wip(obf): new parity based key deriver
1 parent 8c14ee5 commit ce19ee1

2 files changed

Lines changed: 220 additions & 1 deletion

File tree

dev.skidfuscator.obfuscator/src/main/java/dev/skidfuscator/obfuscator/predicate/renderer/seed/SeedLoadable.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import dev.skidfuscator.obfuscator.Skidfuscator;
44
import dev.skidfuscator.obfuscator.predicate.opaque.BlockOpaquePredicate;
5-
import dev.skidfuscator.obfuscator.predicate.renderer.seed.impl.ExceptionSeedLoaderRenderer;
65
import dev.skidfuscator.obfuscator.predicate.renderer.seed.impl.InternalSeedLoaderRenderer;
76
import dev.skidfuscator.obfuscator.predicate.renderer.seed.impl.StaticSeedLoaderRenderer;
87
import dev.skidfuscator.obfuscator.predicate.renderer.seed.impl.SwitchSeedLoaderRenderer;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
package dev.skidfuscator.obfuscator.predicate.renderer.seed.impl;
2+
3+
import dev.skidfuscator.obfuscator.attribute.AttributeKey;
4+
import dev.skidfuscator.obfuscator.predicate.factory.PredicateFlowGetter;
5+
import dev.skidfuscator.obfuscator.predicate.factory.PredicateFlowSetter;
6+
import dev.skidfuscator.obfuscator.predicate.opaque.BlockOpaquePredicate;
7+
import dev.skidfuscator.obfuscator.predicate.renderer.IntegerBlockPredicateRenderer;
8+
import dev.skidfuscator.obfuscator.skidasm.SkidClassNode;
9+
import dev.skidfuscator.obfuscator.skidasm.SkidFieldNode;
10+
import dev.skidfuscator.obfuscator.skidasm.SkidInvocation;
11+
import dev.skidfuscator.obfuscator.skidasm.SkidMethodNode;
12+
import dev.skidfuscator.obfuscator.skidasm.cfg.SkidBlock;
13+
import dev.skidfuscator.obfuscator.skidasm.cfg.SkidControlFlowGraph;
14+
import dev.skidfuscator.obfuscator.skidasm.fake.FakeConditionalJumpStmt;
15+
import dev.skidfuscator.obfuscator.util.RandomUtil;
16+
import dev.skidfuscator.obfuscator.util.cfg.Blocks;
17+
import org.mapleir.flowgraph.edges.ConditionalJumpEdge;
18+
import org.mapleir.ir.cfg.BasicBlock;
19+
import org.mapleir.ir.code.Expr;
20+
import org.mapleir.ir.code.Stmt;
21+
import org.mapleir.ir.code.expr.ArithmeticExpr;
22+
import org.mapleir.ir.code.expr.ConstantExpr;
23+
import org.mapleir.ir.code.expr.FieldLoadExpr;
24+
import org.mapleir.ir.code.expr.VarExpr;
25+
import org.mapleir.ir.code.expr.invoke.StaticInvocationExpr;
26+
import org.mapleir.ir.code.stmt.ConditionalJumpStmt;
27+
import org.mapleir.ir.code.stmt.FieldStoreStmt;
28+
import org.mapleir.ir.code.stmt.ReturnStmt;
29+
import org.mapleir.ir.code.stmt.copy.CopyVarStmt;
30+
import org.mapleir.ir.locals.Local;
31+
import org.mapleir.ir.locals.LocalsPool;
32+
import org.objectweb.asm.Opcodes;
33+
import org.objectweb.asm.Type;
34+
35+
public class EnhancedStaticSeedLoaderRenderer extends AbstractSeedLoaderRenderer {
36+
public static final AttributeKey LOADER = new AttributeKey("loader");
37+
38+
@Override
39+
public void addSeedLoader(
40+
final SkidMethodNode methodNode,
41+
final SkidBlock block,
42+
final SkidBlock targetBlock,
43+
final int index,
44+
final BlockOpaquePredicate predicate,
45+
final int value,
46+
final String type
47+
) {
48+
49+
final SkidClassNode parent = methodNode.getParent();
50+
51+
if (!parent.hasAttribute(LOADER)) {
52+
final SkidMethodNode loader = parent
53+
.createMethod()
54+
.access(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC)
55+
.name(RandomUtil.randomAlphabeticalString(16))
56+
.desc("(II)I")
57+
.exceptions(new String[0])
58+
.phantom(false)
59+
.build();
60+
61+
final LocalsPool pool = loader.getCfg().getLocals();
62+
final boolean swapped = RandomUtil.nextBoolean();
63+
64+
final Local left = pool.get(0);
65+
final Local right = pool.get(1);
66+
67+
loader.getCfg()
68+
.getEntry()
69+
.add(new ReturnStmt(
70+
Type.INT_TYPE,
71+
new ArithmeticExpr(
72+
new VarExpr(
73+
swapped ? left : right,
74+
Type.INT_TYPE
75+
),
76+
new VarExpr(
77+
swapped ? right : left,
78+
Type.INT_TYPE
79+
),
80+
ArithmeticExpr.Operator.XOR
81+
)
82+
));
83+
84+
loader.getGroup().addAttribute(LOADER, true);
85+
parent.addAttribute(LOADER, loader);
86+
}
87+
88+
final SkidMethodNode node = parent.getAttribute(LOADER);
89+
90+
final int target = predicate.get(targetBlock);
91+
final PredicateFlowGetter getter = predicate.getGetter();
92+
final PredicateFlowSetter setter = predicate.getSetter();
93+
94+
final StaticInvocationExpr load = new StaticInvocationExpr(
95+
new Expr[]{
96+
getter.get(block),
97+
new ConstantExpr(value ^ target)
98+
},
99+
node.owner.node.name,
100+
node.node.name,
101+
node.node.desc
102+
);
103+
node.getGroup().getInvokers().add(
104+
new SkidInvocation(methodNode, load)
105+
);
106+
107+
final Stmt set = setter.apply(load);
108+
109+
block.add(
110+
index < 0 ? block.size() : index,
111+
set
112+
);
113+
if (IntegerBlockPredicateRenderer.DEBUG) {
114+
final BasicBlock exception = Blocks.exception(
115+
block.cfg,
116+
block.getDisplayName() + " --> "
117+
+ targetBlock.getDisplayName()
118+
+ " # Failed to match seed of type "
119+
+ type
120+
+ " and value "
121+
+ target
122+
);
123+
124+
final Stmt jumpStmt = new FakeConditionalJumpStmt(
125+
getter.get(targetBlock),
126+
new ConstantExpr(
127+
target,
128+
Type.INT_TYPE
129+
),
130+
exception,
131+
ConditionalJumpStmt.ComparisonType.NE
132+
);
133+
block.cfg.addEdge(
134+
new ConditionalJumpEdge<>(
135+
block,
136+
exception,
137+
Opcodes.GOTO
138+
)
139+
);
140+
block.add(
141+
index < 0 ? block.size() : index + 1,
142+
jumpStmt
143+
);
144+
}
145+
}
146+
147+
private void createInternal(final SkidClassNode parent) {
148+
final SkidMethodNode loader = parent
149+
.createMethod()
150+
.access(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC)
151+
.name(RandomUtil.randomAlphabeticalString(16))
152+
.desc("(II)I")
153+
.exceptions(new String[0])
154+
.phantom(false)
155+
.build();
156+
157+
final SkidFieldNode pair = parent
158+
.createField()
159+
.access(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT)
160+
.name(RandomUtil.randomAlphabeticalString(16))
161+
.desc("I")
162+
.value(0 + 2 * RandomUtil.nextInt(127))
163+
.build();
164+
final SkidFieldNode odd = parent
165+
.createField()
166+
.access(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT)
167+
.name(RandomUtil.randomAlphabeticalString(16))
168+
.desc("I")
169+
.value(1 + 2 * RandomUtil.nextInt(127))
170+
.build();
171+
172+
final LocalsPool pool = loader.getCfg().getLocals();
173+
final boolean swapped = RandomUtil.nextBoolean();
174+
final Local left = pool.get(0);
175+
final Local right = pool.get(1);
176+
final Local next = pool.get(2);
177+
178+
final SkidControlFlowGraph cfg = loader.getCfg();
179+
180+
final BasicBlock fakeOutput = new BasicBlock(cfg);
181+
final BasicBlock realOutput = new BasicBlock(cfg);
182+
183+
final BasicBlock entry = cfg.getEntry();
184+
185+
if (RandomUtil.nextBoolean()) {
186+
entry.add(new CopyVarStmt(
187+
new VarExpr(next, Type.INT_TYPE),
188+
new ArithmeticExpr(
189+
new ArithmeticExpr(
190+
new FieldLoadExpr(
191+
null,
192+
parent.getName(),
193+
pair.node.name,
194+
pair.node.desc,
195+
true
196+
),
197+
new ConstantExpr(
198+
1 + 2 * RandomUtil.nextInt(63),
199+
Type.INT_TYPE
200+
),
201+
ArithmeticExpr.Operator.ADD
202+
),
203+
new ConstantExpr(256, Type.INT_TYPE),
204+
ArithmeticExpr.Operator.REM
205+
)
206+
));
207+
208+
entry.add(new FieldStoreStmt(
209+
null,
210+
new VarExpr(next, Type.INT_TYPE),
211+
parent.getName(),
212+
odd.node.name,
213+
odd.node.desc,
214+
true
215+
));
216+
217+
218+
}
219+
}
220+
}

0 commit comments

Comments
 (0)