Skip to content

Commit 32edada

Browse files
committed
Fixes + improvements to ghost mappings
1 parent 35578a5 commit 32edada

File tree

11 files changed

+141
-68
lines changed

11 files changed

+141
-68
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,5 @@ org.mapleir.main/out/
2828
org.mapleir.main/dot/
2929

3030
*.DS_Store
31+
32+
obfuscator/src/test/resources/test-out.jar

obfuscator/src/main/java/dev/skidfuscator/obfuscator/Skidfuscator.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -267,18 +267,19 @@ public void run() {
267267

268268
for (File lib : libs) {
269269
LOGGER.post("[+] " + lib.getAbsolutePath());
270-
}
271270

272-
try {
273-
/* Download the libraries jar contents */
274-
final AbstractJarDownloader<ClassNode> jar = MapleJarUtil.importJars(libs);
275-
final GhostLibrary library = GhostHelper.createFromLibraryFile(jar);
271+
final GhostLibrary library = GhostHelper.createFromLibraryFile(lib);
276272
final File output = new File(
277-
session.getLibs().getParent(), "mappings/libraries.json"
273+
session.getLibs().getParent(), "mappings/" + lib.getName() + ".json"
278274
);
279275
output.getParentFile().mkdirs();
280276

281277
GhostHelper.saveLibraryFile(library, output);
278+
}
279+
280+
try {
281+
/* Download the libraries jar contents */
282+
final AbstractJarDownloader<ClassNode> jar = MapleJarUtil.importJars(libs);
282283

283284
/* Create a new library class source with superior to default priority */
284285
final ApplicationClassSource libraryClassSource = new ApplicationClassSource(

obfuscator/src/main/java/dev/skidfuscator/obfuscator/SkidfuscatorSession.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public class SkidfuscatorSession {
2020
private boolean jmod;
2121

2222
/**
23+
*
2324
* @return the input
2425
*/
2526
public File getInput() {

obfuscator/src/main/java/dev/skidfuscator/obfuscator/hierarchy/SkidHierarchy.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
import dev.skidfuscator.obfuscator.Skidfuscator;
44
import dev.skidfuscator.obfuscator.hierarchy.matching.ClassMethodHash;
55
import dev.skidfuscator.obfuscator.skidasm.*;
6+
import dev.skidfuscator.obfuscator.skidasm.cfg.SkidControlFlowGraph;
67
import dev.skidfuscator.obfuscator.util.ProgressUtil;
78
import me.tongfei.progressbar.ProgressBar;
89
import org.mapleir.asm.ClassNode;
910
import org.mapleir.asm.MethodNode;
1011
import org.mapleir.ir.cfg.ControlFlowGraph;
1112
import org.mapleir.ir.code.expr.invoke.*;
1213
import org.objectweb.asm.ClassVisitor;
14+
import org.objectweb.asm.Handle;
1315
import org.objectweb.asm.MethodVisitor;
1416
import org.objectweb.asm.Opcodes;
1517
import org.objectweb.asm.commons.JSRInlinerAdapter;
@@ -135,7 +137,8 @@ public void cache() {
135137
this.annotations = new HashMap<>();
136138

137139
try (ProgressBar progressBar = ProgressUtil.progress(skidfuscator.getClassSource().size())){
138-
nodes = skidfuscator.getClassSource().getClassTree()
140+
nodes = skidfuscator.getClassSource()
141+
.getClassTree()
139142
.vertices()
140143
.parallelStream()
141144
.filter(e -> {
@@ -173,20 +176,33 @@ private void setupInvoke() {
173176
try (ProgressBar invocationBar = ProgressUtil.progress(nodes.size())) {
174177
nodes.forEach(c -> {
175178
for (MethodNode method : c.getMethods()) {
176-
final ControlFlowGraph cfg = skidfuscator.getCxt().getIRCache().getFor(method);
179+
final SkidControlFlowGraph cfg = skidfuscator.getIrFactory().getFor(method);
177180

178181
if (cfg == null) {
179182
System.err.println("Failed to compute CFG for method " + method.toString());
180183
continue;
181184
}
182185

183186
cfg.allExprStream()
184-
.filter(e -> e instanceof Invokable && !(e instanceof DynamicInvocationExpr))
187+
.filter(e -> e instanceof Invokable)
185188
.map(e -> (Invocation) e)
186189
.forEach(invocation -> {
187190
final ClassMethodHash target;
188191

189-
if (invocation instanceof InvocationExpr) {
192+
if (invocation instanceof DynamicInvocationExpr) {
193+
final DynamicInvocationExpr e = (DynamicInvocationExpr) invocation;
194+
195+
if (!e.getOwner().equals("java/lang/invoke/LambdaMetafactory")
196+
|| !e.getName().equals("metafactory")) {
197+
throw new IllegalStateException("Invalid invoke dynamic!");
198+
}
199+
200+
assert (e.getBootstrapArgs().length == 3 && e.getBootstrapArgs()[1] instanceof Handle);
201+
final Handle boundFunc = (Handle) e.getBootstrapArgs()[1];
202+
203+
target = new ClassMethodHash(boundFunc.getName(), boundFunc.getDesc(), boundFunc.getOwner());
204+
205+
} else if (invocation instanceof InvocationExpr) {
190206
final InvocationExpr e = (InvocationExpr) invocation;
191207
target = new ClassMethodHash(e.getName(), e.getDesc(), e.getOwner());
192208
} else if (invocation instanceof InitialisedObjectExpr) {
@@ -249,6 +265,7 @@ private SkidGroup getGroup(final Skidfuscator session, final MethodNode methodNo
249265
group.setStatical(((SkidMethodNode) methodNode).isStatic());
250266
group.setName(methodNode.getName());
251267
group.setDesc(methodNode.getDesc());
268+
System.out.println(group.getDesc());
252269

253270
for (MethodNode method : methods) {
254271
if (method instanceof SkidMethodNode) {

obfuscator/src/main/java/dev/skidfuscator/obfuscator/phantom/jghost/Ghost.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ static class TypeSerializer extends TypeAdapter<Type> {
2424
@Override
2525
public void write(JsonWriter out, Type value) throws IOException {
2626
out .beginObject()
27-
.name("internalName").value(value.getInternalName())
27+
.name("itrlNme").value(value.getInternalName())
2828
.endObject();
2929
}
3030

obfuscator/src/main/java/dev/skidfuscator/obfuscator/phantom/jghost/GhostHelper.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,26 @@ public GhostLibrary readFromLibraryFile(final File file) {
2727
}
2828
}
2929

30-
public GhostLibrary createFromLibraryFile(final AbstractJarDownloader<ClassNode> downloader) {
30+
public GhostLibrary createFromLibraryFile(final File file) {
31+
final JarInfo jarInfo = new JarInfo(file);
32+
final SingleJarDownloader<ClassNode> downloader = new SingleJarDownloader<>(jarInfo);
33+
34+
try {
35+
downloader.download();
36+
} catch (IOException e) {
37+
Skidfuscator.LOGGER.error("Failed to download library", e);
38+
return null;
39+
}
40+
3141
final GhostContents ghostContents = new GhostContents();
3242
final GhostLibrary ghostLibrary = new GhostLibrary();
3343
ghostLibrary.setContents(ghostContents);
3444

3545
try {
36-
//final ByteSource byteSource = Files.asByteSource(downloader.getJarContents().getJarUrls());
37-
//ghostLibrary.setMd5(byteSource.hash(Hashing.md5()).toString());
38-
//ghostLibrary.setSha1(byteSource.hash(Hashing.sha1()).toString());
39-
//ghostLibrary.setSha256(byteSource.hash(Hashing.sha256()).toString());
46+
final ByteSource byteSource = Files.asByteSource(file);
47+
ghostLibrary.setMd5(byteSource.hash(Hashing.md5()).toString());
48+
ghostLibrary.setSha1(byteSource.hash(Hashing.sha1()).toString());
49+
ghostLibrary.setSha256(byteSource.hash(Hashing.sha256()).toString());
4050
} catch (Throwable e) {
4151
Skidfuscator.LOGGER.error("Failed to hash library", e);
4252
return null;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package dev.skidfuscator.obfuscator.predicate.cache;
2+
3+
public interface PredicateCache {
4+
}

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

Lines changed: 71 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -411,78 +411,97 @@ public Stmt apply(Expr expr) {
411411
void handle(final InitGroupTransformEvent event) {
412412
final SkidGroup skidGroup = event.getGroup();
413413

414+
/*
415+
* This can occur. Warn the user then skip. No significant damage
416+
* should be caused by skipping this method.
417+
*
418+
* TODO: Add stricter exception logging for this
419+
*/
414420
if (skidGroup.getPredicate().getGetter() != null) {
415421
System.err.println("SkidGroup " + skidGroup.getName() + " does not have getter!");
416422
return;
417423
}
418424

419425
final boolean entryPoint = skidGroup.isEntryPoint();
420-
Local local = null;
421426
int stackHeight = -1;
427+
428+
/*
429+
* If the skid group is an entry point (it has no direct invocation)
430+
* or in the future when we support reflection calls
431+
*/
432+
if (entryPoint) {
433+
stackHeight = OpcodeUtil.getArgumentsSizes(skidGroup.getDesc());
434+
435+
if (skidGroup.isStatical())
436+
stackHeight -= 1;
437+
438+
skidGroup.setStackHeight(stackHeight);
439+
return;
440+
}
441+
442+
Local local = null;
422443
String desc = null;
423444

424-
if (!entryPoint) {
425-
for (MethodNode methodNode : skidGroup.getMethodNodeList()) {
426-
final SkidMethodNode skidMethodNode = (SkidMethodNode) methodNode;
427-
428-
stackHeight = OpcodeUtil.getArgumentsSizes(methodNode.getDesc());
429-
if (methodNode.isStatic()) stackHeight -= 1;
430-
431-
final Map<String, Local> localMap = new HashMap<>();
432-
for (Map.Entry<String, Local> stringLocalEntry :
433-
skidMethodNode.getCfg().getLocals().getCache().entrySet()) {
434-
final String old = stringLocalEntry.getKey();
435-
final String oldStringId = old.split("var")[1].split("_")[0];
436-
final int oldId = Integer.parseInt(oldStringId);
437-
438-
if (oldId < stackHeight) {
439-
localMap.put(old, stringLocalEntry.getValue());
440-
continue;
441-
}
442-
final int newId = oldId + 1;
443-
444-
final String newVar = old.replace("var" + oldStringId, "var" + Integer.toString(newId));
445-
stringLocalEntry.getValue().setIndex(stringLocalEntry.getValue().getIndex() + 1);
446-
localMap.put(newVar, stringLocalEntry.getValue());
447-
}
445+
for (MethodNode methodNode : skidGroup.getMethodNodeList()) {
446+
final SkidMethodNode skidMethodNode = (SkidMethodNode) methodNode;
448447

449-
skidMethodNode.getCfg().getLocals().getCache().clear();
450-
skidMethodNode.getCfg().getLocals().getCache().putAll(localMap);
448+
stackHeight = OpcodeUtil.getArgumentsSizes(methodNode.getDesc());
449+
if (methodNode.isStatic()) stackHeight -= 1;
451450

452-
final Parameter parameter = new Parameter(methodNode.getDesc());
453-
parameter.addParameter(Type.INT_TYPE);
454-
methodNode.node.desc = desc = parameter.getDesc();
451+
final Map<String, Local> localMap = new HashMap<>();
452+
for (Map.Entry<String, Local> stringLocalEntry :
453+
skidMethodNode.getCfg().getLocals().getCache().entrySet()) {
454+
final String old = stringLocalEntry.getKey();
455+
final String oldStringId = old.split("var")[1].split("_")[0];
456+
final int oldId = Integer.parseInt(oldStringId);
455457

456-
if (local == null) {
457-
local = skidMethodNode.getCfg().getLocals().get(stackHeight);
458+
if (oldId < stackHeight) {
459+
localMap.put(old, stringLocalEntry.getValue());
460+
continue;
458461
}
462+
final int newId = oldId + 1;
463+
464+
final String newVar = old.replace("var" + oldStringId, "var" + Integer.toString(newId));
465+
stringLocalEntry.getValue().setIndex(stringLocalEntry.getValue().getIndex() + 1);
466+
localMap.put(newVar, stringLocalEntry.getValue());
459467
}
460468

461-
for (SkidInvocation invoker : skidGroup.getInvokers()) {
462-
assert invoker != null : String.format("Invoker %s is null!", Arrays.toString(skidGroup.getInvokers().toArray()));
463-
assert invoker.getExpr() != null : String.format("Invoker %s is null!", invoker.getOwner().getDisplayName());
469+
skidMethodNode.getCfg().getLocals().getCache().clear();
470+
skidMethodNode.getCfg().getLocals().getCache().putAll(localMap);
464471

465-
int index = 0;
466-
for (Expr argumentExpr : invoker.getExpr().getArgumentExprs()) {
467-
assert argumentExpr != null : "Argument of index " + index + " is null!";
468-
index++;
469-
}
472+
final Parameter parameter = new Parameter(methodNode.getDesc());
473+
parameter.addParameter(Type.INT_TYPE);
474+
methodNode.node.desc = desc = parameter.getDesc();
470475

471-
final Expr[] args = new Expr[invoker.getExpr().getArgumentExprs().length + 1];
472-
System.arraycopy(
473-
invoker.getExpr().getArgumentExprs(),
474-
0,
475-
args,
476-
0,
477-
invoker.getExpr().getArgumentExprs().length
478-
);
476+
if (local == null) {
477+
local = skidMethodNode.getCfg().getLocals().get(stackHeight);
478+
}
479+
}
479480

480-
final ConstantExpr constant = new SkidConstantExpr(skidGroup.getPredicate().getPublic());
481-
args[args.length - 1] = constant;
481+
for (SkidInvocation invoker : skidGroup.getInvokers()) {
482+
assert invoker != null : String.format("Invoker %s is null!", Arrays.toString(skidGroup.getInvokers().toArray()));
483+
assert invoker.getExpr() != null : String.format("Invoker %s is null!", invoker.getOwner().getDisplayName());
482484

483-
invoker.getExpr().setArgumentExprs(args);
484-
invoker.getExpr().setDesc(desc);
485+
int index = 0;
486+
for (Expr argumentExpr : invoker.getExpr().getArgumentExprs()) {
487+
assert argumentExpr != null : "Argument of index " + index + " is null!";
488+
index++;
485489
}
490+
491+
final Expr[] args = new Expr[invoker.getExpr().getArgumentExprs().length + 1];
492+
System.arraycopy(
493+
invoker.getExpr().getArgumentExprs(),
494+
0,
495+
args,
496+
0,
497+
invoker.getExpr().getArgumentExprs().length
498+
);
499+
500+
final ConstantExpr constant = new SkidConstantExpr(skidGroup.getPredicate().getPublic());
501+
args[args.length - 1] = constant;
502+
503+
invoker.getExpr().setArgumentExprs(args);
504+
invoker.getExpr().setDesc(desc);
486505
}
487506

488507
final int finalStackHeight = stackHeight;

obfuscator/src/main/java/dev/skidfuscator/obfuscator/skidasm/SkidGroup.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ public void setStatical(boolean statical) {
4949
}
5050

5151
public void setDesc(final String desc) {
52+
this.desc = desc;
53+
5254
for (MethodNode methodNode : methodNodeList) {
5355
methodNode.node.desc = desc;
5456
}
@@ -59,6 +61,8 @@ public void setDesc(final String desc) {
5961
}
6062

6163
public void setName(final String name) {
64+
this.name = name;
65+
6266
for (MethodNode methodNode : methodNodeList) {
6367
methodNode.node.name = name;
6468
}

obfuscator/src/main/java/dev/skidfuscator/obfuscator/skidasm/cfg/SkidControlFlowGraph.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
import org.mapleir.ir.cfg.ControlFlowGraph;
77
import org.mapleir.ir.code.CodeUnit;
88
import org.mapleir.ir.code.Stmt;
9+
import org.mapleir.ir.code.expr.invoke.DynamicInvocationExpr;
10+
import org.mapleir.ir.code.expr.invoke.Invocation;
11+
import org.mapleir.ir.code.expr.invoke.Invokable;
912
import org.mapleir.ir.locals.LocalsPool;
1013

1114
import java.util.Collection;
@@ -22,6 +25,18 @@ public SkidControlFlowGraph(ControlFlowGraph cfg) {
2225
super(cfg);
2326
}
2427

28+
public Stream<Invocation> staticInvocationStream() {
29+
return allExprStream()
30+
.filter(e -> e instanceof Invokable && !(e instanceof DynamicInvocationExpr))
31+
.map(e -> (Invocation) e);
32+
}
33+
34+
public Stream<DynamicInvocationExpr> dynamicInvocationStream() {
35+
return allExprStream()
36+
.filter(e -> e instanceof DynamicInvocationExpr)
37+
.map(e -> (DynamicInvocationExpr) e);
38+
}
39+
2540
@Override
2641
public Stream<CodeUnit> allExprStream() {
2742
return vertices()

0 commit comments

Comments
 (0)