Skip to content

Commit e0f5214

Browse files
committed
lazily load frames, some renaming
1 parent 27eaefd commit e0f5214

File tree

15 files changed

+48
-43
lines changed

15 files changed

+48
-43
lines changed

deobfuscator-api/src/main/java/uwu/narumi/deobfuscator/api/asm/MethodContext.java

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package uwu.narumi.deobfuscator.api.asm;
22

3-
import org.jetbrains.annotations.Nullable;
43
import org.jetbrains.annotations.Unmodifiable;
54
import org.objectweb.asm.tree.AbstractInsnNode;
65
import org.objectweb.asm.tree.MethodNode;
@@ -17,17 +16,20 @@
1716
public class MethodContext {
1817
private final ClassWrapper classWrapper;
1918
private final MethodNode methodNode;
20-
private final @Nullable @Unmodifiable Map<AbstractInsnNode, Frame<OriginalSourceValue>> frames;
19+
private final FramesProvider framesProvider;
20+
// Lazily initialized
21+
private Map<AbstractInsnNode, Frame<OriginalSourceValue>> frames = null;
22+
// Lazily initialized
2123
private Map<AbstractInsnNode, Set<AbstractInsnNode>> consumersMap = null;
2224

2325
private MethodContext(
2426
ClassWrapper classWrapper,
2527
MethodNode methodNode,
26-
@Nullable @Unmodifiable Map<AbstractInsnNode, Frame<OriginalSourceValue>> frames
28+
FramesProvider framesProvider
2729
) {
2830
this.classWrapper = classWrapper;
2931
this.methodNode = methodNode;
30-
this.frames = frames;
32+
this.framesProvider = framesProvider;
3133
}
3234

3335
/**
@@ -47,38 +49,41 @@ public MethodNode methodNode() {
4749
/**
4850
* Frames of the method
4951
*/
50-
public @Nullable @Unmodifiable Map<AbstractInsnNode, Frame<OriginalSourceValue>> frames() {
52+
@Unmodifiable
53+
public synchronized Map<AbstractInsnNode, Frame<OriginalSourceValue>> frames() {
54+
if (this.frames == null) {
55+
// Lazy initialization
56+
this.frames = this.framesProvider.compute(this.classWrapper.classNode(), this.methodNode);
57+
}
5158
return frames;
5259
}
5360

5461
public synchronized Map<AbstractInsnNode, Set<AbstractInsnNode>> getConsumersMap() {
55-
if (this.frames == null) {
56-
throw new IllegalStateException("Got frameless method context");
57-
}
5862
if (consumersMap == null) {
5963
// Lazy initialization
6064
this.consumersMap = MethodHelper.computeConsumersMap(this.frames);
6165
}
6266
return consumersMap;
6367
}
6468

65-
public InsnContext newInsnContext(AbstractInsnNode insn) {
69+
/**
70+
* Creates new {@link InsnContext} instance at specified instruction
71+
*
72+
* @param insn instruction
73+
* @return new {@link InsnContext} instance
74+
*/
75+
public InsnContext at(AbstractInsnNode insn) {
6676
return new InsnContext(insn, this);
6777
}
6878

69-
public static MethodContext framed(ClassWrapper classWrapper, MethodNode methodNode) {
70-
return framed(classWrapper, methodNode, MethodHelper::analyzeSource);
79+
public static MethodContext of(ClassWrapper classWrapper, MethodNode methodNode) {
80+
return of(classWrapper, methodNode, MethodHelper::analyzeSource);
7181
}
7282

7383
/**
74-
* Creates new {@link MethodContext} and computes its frames
84+
* Creates new {@link MethodContext} instance
7585
*/
76-
public static MethodContext framed(ClassWrapper classWrapper, MethodNode methodNode, FramesProvider framesProvider) {
77-
Map<AbstractInsnNode, Frame<OriginalSourceValue>> frames = framesProvider.compute(classWrapper.classNode(), methodNode);
78-
return new MethodContext(classWrapper, methodNode, frames);
79-
}
80-
81-
public static MethodContext frameless(ClassWrapper classWrapper, MethodNode methodNode) {
82-
return new MethodContext(classWrapper, methodNode, null);
86+
public static MethodContext of(ClassWrapper classWrapper, MethodNode methodNode, FramesProvider framesProvider) {
87+
return new MethodContext(classWrapper, methodNode, framesProvider);
8388
}
8489
}

deobfuscator-api/src/main/java/uwu/narumi/deobfuscator/api/asm/matcher/Match.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public List<MatchContext> findAllMatches(MethodContext methodContext) {
5757
List<MatchContext> allMatches = new ArrayList<>();
5858

5959
for (AbstractInsnNode insn : methodContext.methodNode().instructions) {
60-
InsnContext insnContext = methodContext.newInsnContext(insn);
60+
InsnContext insnContext = methodContext.at(insn);
6161
MatchContext match = this.matchResult(insnContext);
6262
if (match != null) {
6363
allMatches.add(match);

deobfuscator-api/src/main/java/uwu/narumi/deobfuscator/api/helper/FramedInstructionsStream.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,12 @@ public void forEach(Consumer<InsnContext> consumer) {
8282
if (instructionsStreamModifier.apply(Arrays.stream(methodNode.instructions.toArray())).findAny().isEmpty()) return;
8383

8484
// Get frames of the method
85-
MethodContext methodContext = MethodContext.framed(classWrapper, methodNode, this.framesProvider);
85+
MethodContext methodContext = MethodContext.of(classWrapper, methodNode, this.framesProvider);
8686

8787
// Iterate over instructions SYNC
8888
instructionsStreamModifier.apply(Arrays.stream(methodNode.instructions.toArray()))
8989
.forEach(insn -> {
90-
InsnContext insnContext = methodContext.newInsnContext(insn);
90+
InsnContext insnContext = methodContext.at(insn);
9191
// Check if frame exists
9292
if (insnContext.frame() == null) return;
9393

deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/clean/peephole/PopUnUsedLocalVariablesTransformer.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ public class PopUnUsedLocalVariablesTransformer extends Transformer {
1717
@Override
1818
protected void transform() throws Exception {
1919
scopedClasses().forEach(classWrapper -> classWrapper.methods().forEach(methodNode -> {
20-
MethodContext methodContext = MethodContext.framed(classWrapper, methodNode);
20+
MethodContext methodContext = MethodContext.of(classWrapper, methodNode);
2121

2222
Set<VarInsnNode> varStoresInUse = new HashSet<>();
2323

2424
// Find all local variables in use
2525
for (AbstractInsnNode insn : methodNode.instructions.toArray()) {
2626
if ((insn instanceof VarInsnNode && !insn.isVarStore()) || insn instanceof IincInsnNode) {
27-
InsnContext insnContext = methodContext.newInsnContext(insn);
27+
InsnContext insnContext = methodContext.at(insn);
2828

2929
Frame<OriginalSourceValue> frame = insnContext.frame();
3030
if (frame == null) return;
@@ -50,7 +50,7 @@ protected void transform() throws Exception {
5050
for (AbstractInsnNode insn : methodNode.instructions.toArray()) {
5151
if (insn instanceof VarInsnNode varInsnNode && insn.isVarStore()) {
5252
if (!varStoresInUse.contains(varInsnNode)) {
53-
InsnContext insnContext = methodContext.newInsnContext(insn);
53+
InsnContext insnContext = methodContext.at(insn);
5454

5555
// Pop the value from the stack
5656
insnContext.placePops();

deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/hp888/HP888StringTransformer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ protected void transform() throws Exception {
4343

4444
// Find all encrypted strings
4545
classWrapper.methods().forEach(methodNode -> {
46-
MethodContext methodContext = MethodContext.framed(classWrapper, methodNode);
46+
MethodContext methodContext = MethodContext.of(classWrapper, methodNode);
4747

4848
// Find encrypted strings
4949
ENCRYPTED_STRING.findAllMatches(methodContext).forEach(matchContext -> {
@@ -55,7 +55,7 @@ protected void transform() throws Exception {
5555
findMethod(classWrapper.classNode(), methodRef).ifPresent(decryptMethod -> {
5656
String key = keyInsn.asString();
5757

58-
MethodContext decryptMethodContext = MethodContext.framed(classWrapper, decryptMethod);
58+
MethodContext decryptMethodContext = MethodContext.of(classWrapper, decryptMethod);
5959

6060
// Find class for constant pool
6161
LdcInsnNode constantPoolClassLdc = (LdcInsnNode) CLASS_FOR_CONSTANT_POOL.findAllMatches(decryptMethodContext)

deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/qprotect/qProtectFieldFlowTransformer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public class qProtectFieldFlowTransformer extends Transformer {
2525
protected void transform() throws Exception {
2626
scopedClasses().forEach(classWrapper -> {
2727
classWrapper.methods().forEach(methodNode -> {
28-
MethodContext methodContext = MethodContext.frameless(classWrapper, methodNode);
28+
MethodContext methodContext = MethodContext.of(classWrapper, methodNode);
2929
FIELD_FLOW_PATTERN.findAllMatches(methodContext).forEach(match -> {
3030
FieldInsnNode fieldInsn = (FieldInsnNode) match.captures().get("field").insn();
3131

deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/qprotect/qProtectNumberPoolTransformer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public class qProtectNumberPoolTransformer extends Transformer {
3535
protected void transform() throws Exception {
3636
scopedClasses().forEach(classWrapper -> {
3737
MatchContext numberPoolMatchCtx = classWrapper.methods().stream()
38-
.map(methodNode -> NUMBER_POOL_METHOD_MATCH.findFirstMatch(MethodContext.framed(classWrapper, methodNode)))
38+
.map(methodNode -> NUMBER_POOL_METHOD_MATCH.findFirstMatch(MethodContext.of(classWrapper, methodNode)))
3939
.filter(Objects::nonNull)
4040
.findFirst()
4141
.orElse(null);
@@ -75,7 +75,7 @@ protected void transform() throws Exception {
7575

7676
// Replace number pool references with actual values
7777
classWrapper.methods().forEach(methodNode -> {
78-
MethodContext methodContext = MethodContext.framed(classWrapper, methodNode);
78+
MethodContext methodContext = MethodContext.of(classWrapper, methodNode);
7979

8080
numberPoolReferenceMatch.findAllMatches(methodContext).forEach(numberPoolReferenceCtx -> {
8181
int index = numberPoolReferenceCtx.captures().get("index").insn().asInteger();

deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/qprotect/qProtectStringPoolTransformer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public class qProtectStringPoolTransformer extends Transformer {
3434
protected void transform() throws Exception {
3535
scopedClasses().forEach(classWrapper -> {
3636
MatchContext stringPoolMatchCtx = classWrapper.methods().stream()
37-
.map(methodNode -> STRING_POOL_METHOD_MATCH.findFirstMatch(MethodContext.framed(classWrapper, methodNode)))
37+
.map(methodNode -> STRING_POOL_METHOD_MATCH.findFirstMatch(MethodContext.of(classWrapper, methodNode)))
3838
.filter(Objects::nonNull)
3939
.findFirst()
4040
.orElse(null);
@@ -72,7 +72,7 @@ protected void transform() throws Exception {
7272

7373
// Replace number pool references with actual values
7474
classWrapper.methods().forEach(methodNode -> {
75-
MethodContext methodContext = MethodContext.framed(classWrapper, methodNode);
75+
MethodContext methodContext = MethodContext.of(classWrapper, methodNode);
7676

7777
stringPoolReferenceMatch.findAllMatches(methodContext).forEach(numberPoolReferenceCtx -> {
7878
int index = numberPoolReferenceCtx.captures().get("index").insn().asInteger();

deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/qprotect/qProtectStringTransformer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ protected void transform() throws Exception {
3232
AtomicReference<MethodRef> decryptionMethodRef = new AtomicReference<>();
3333

3434
classWrapper.methods().forEach(methodNode -> {
35-
DECRYPT_STRING_MATCH.findAllMatches(MethodContext.framed(classWrapper, methodNode)).forEach(matchContext -> {
35+
DECRYPT_STRING_MATCH.findAllMatches(MethodContext.of(classWrapper, methodNode)).forEach(matchContext -> {
3636
String encryptedText = matchContext.captures().get("encryptedText").insn().asString();
3737
String xorKey = matchContext.captures().get("xorKey").insn().asString();
3838
String encryptedData = matchContext.captures().get("encryptedData").insn().asString();

deobfuscator-transformers/src/main/java/uwu/narumi/deobfuscator/core/other/impl/qprotect/qProtectTryCatchTransformer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public class qProtectTryCatchTransformer extends Transformer {
4646
@Override
4747
protected void transform() throws Exception {
4848
scopedClasses().forEach(classWrapper -> classWrapper.methods().forEach(methodNode -> {
49-
MethodContext methodContext = MethodContext.frameless(classWrapper, methodNode);
49+
MethodContext methodContext = MethodContext.of(classWrapper, methodNode);
5050

5151
// Remove infinite loop try catch blocks
5252
methodNode.tryCatchBlocks.removeIf(tryCatch -> {
@@ -69,7 +69,7 @@ protected void transform() throws Exception {
6969
LabelNode handlerLabel = tryCatch.handler;
7070
AbstractInsnNode nextInsn = handlerLabel.getNext();
7171

72-
MatchContext matchContext = SELF_THROW_TRY_CATCH_MATCH.matchResult(methodContext.newInsnContext(nextInsn));
72+
MatchContext matchContext = SELF_THROW_TRY_CATCH_MATCH.matchResult(methodContext.at(nextInsn));
7373
if (matchContext != null) {
7474
matchContext.removeAll();
7575
markChange();

0 commit comments

Comments
 (0)