Skip to content

Commit 9e4de94

Browse files
committed
Allow frame/attribute removing transformer to operate on ClassNode
Some obfuscated samples have issues with keeping frames as-is, so these transformers when put first allow frames to be recomputed.
1 parent d3d5266 commit 9e4de94

File tree

3 files changed

+61
-15
lines changed

3 files changed

+61
-15
lines changed

recaf-core/src/main/java/software/coley/recaf/services/deobfuscation/transform/generic/FrameRemovingTransformer.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
import jakarta.enterprise.context.Dependent;
55
import org.objectweb.asm.ClassReader;
66
import org.objectweb.asm.ClassWriter;
7+
import org.objectweb.asm.tree.AbstractInsnNode;
8+
import org.objectweb.asm.tree.ClassNode;
9+
import org.objectweb.asm.tree.FrameNode;
10+
import org.objectweb.asm.tree.InsnList;
11+
import org.objectweb.asm.tree.MethodNode;
712
import software.coley.recaf.info.JvmClassInfo;
813
import software.coley.recaf.services.transform.JvmClassTransformer;
914
import software.coley.recaf.services.transform.JvmTransformerContext;
@@ -23,10 +28,25 @@ public class FrameRemovingTransformer implements JvmClassTransformer {
2328
public void transform(@Nonnull JvmTransformerContext context, @Nonnull Workspace workspace,
2429
@Nonnull WorkspaceResource resource, @Nonnull JvmClassBundle bundle,
2530
@Nonnull JvmClassInfo initialClassState) throws TransformationException {
26-
ClassReader reader = new ClassReader(context.getBytecode(bundle, initialClassState));
27-
ClassWriter writer = new ClassWriter(reader, 0);
28-
reader.accept(writer, ClassReader.SKIP_FRAMES);
29-
context.setBytecode(bundle, initialClassState, writer.toByteArray());
31+
if (context.isNode(bundle, initialClassState)) {
32+
ClassNode node = context.getNode(bundle, initialClassState);
33+
for (MethodNode method : node.methods) {
34+
InsnList instructions = method.instructions;
35+
if (instructions != null) {
36+
for (int i = instructions.size() - 1; i > 0; i--) {
37+
AbstractInsnNode insn = instructions.get(i);
38+
if (insn instanceof FrameNode)
39+
instructions.remove(insn);
40+
}
41+
}
42+
}
43+
} else {
44+
ClassReader reader = new ClassReader(context.getBytecode(bundle, initialClassState));
45+
ClassWriter writer = new ClassWriter(reader, 0);
46+
reader.accept(writer, ClassReader.SKIP_FRAMES);
47+
context.setBytecode(bundle, initialClassState, writer.toByteArray());
48+
}
49+
context.setRecomputeFrames(initialClassState.getName());
3050
}
3151

3252
@Nonnull

recaf-core/src/main/java/software/coley/recaf/services/deobfuscation/transform/generic/UnknownAttributeRemovingTransformer.java

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,12 @@
22

33
import jakarta.annotation.Nonnull;
44
import jakarta.enterprise.context.Dependent;
5-
import org.objectweb.asm.AnnotationVisitor;
6-
import org.objectweb.asm.Attribute;
75
import org.objectweb.asm.ClassReader;
8-
import org.objectweb.asm.ClassVisitor;
96
import org.objectweb.asm.ClassWriter;
10-
import org.objectweb.asm.FieldVisitor;
11-
import org.objectweb.asm.MethodVisitor;
12-
import org.objectweb.asm.RecordComponentVisitor;
13-
import software.coley.recaf.RecafConstants;
7+
import org.objectweb.asm.tree.ClassNode;
8+
import org.objectweb.asm.tree.FieldNode;
9+
import org.objectweb.asm.tree.MethodNode;
10+
import org.objectweb.asm.tree.RecordComponentNode;
1411
import software.coley.recaf.info.JvmClassInfo;
1512
import software.coley.recaf.services.transform.JvmClassTransformer;
1613
import software.coley.recaf.services.transform.JvmTransformerContext;
@@ -31,10 +28,26 @@ public class UnknownAttributeRemovingTransformer implements JvmClassTransformer
3128
public void transform(@Nonnull JvmTransformerContext context, @Nonnull Workspace workspace,
3229
@Nonnull WorkspaceResource resource, @Nonnull JvmClassBundle bundle,
3330
@Nonnull JvmClassInfo initialClassState) throws TransformationException {
34-
ClassReader reader = new ClassReader(context.getBytecode(bundle, initialClassState));
35-
ClassWriter writer = new ClassWriter(reader, 0);
36-
reader.accept(new UnknownAttributeRemovingVisitor(writer), 0);
37-
context.setBytecode(bundle, initialClassState, writer.toByteArray());
31+
if (context.isNode(bundle, initialClassState)) {
32+
ClassNode node = context.getNode(bundle, initialClassState);
33+
if (node.attrs != null)
34+
node.attrs.clear();
35+
for (FieldNode field : node.fields)
36+
if (field.attrs != null)
37+
field.attrs.clear();
38+
for (MethodNode method : node.methods)
39+
if (method.attrs != null)
40+
method.attrs.clear();
41+
if (node.recordComponents != null)
42+
for (RecordComponentNode recordComponent : node.recordComponents)
43+
if (recordComponent.attrs != null)
44+
recordComponent.attrs.clear();
45+
} else {
46+
ClassReader reader = new ClassReader(context.getBytecode(bundle, initialClassState));
47+
ClassWriter writer = new ClassWriter(reader, 0);
48+
reader.accept(new UnknownAttributeRemovingVisitor(writer), 0);
49+
context.setBytecode(bundle, initialClassState, writer.toByteArray());
50+
}
3851
}
3952

4053
@Nonnull

recaf-core/src/main/java/software/coley/recaf/services/transform/JvmTransformerContext.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,19 @@ public boolean pruneDeadCode(@Nonnull ClassNode declaringClass, @Nonnull MethodN
221221
return getJvmTransformer(DeadCodeRemovingTransformer.class).prune(declaringClass, method);
222222
}
223223

224+
/**
225+
* @param bundle
226+
* Bundle containing the class.
227+
* @param info
228+
* The class's model in the workspace.
229+
*
230+
* @return {@code true} when the context currently has the class represented as a node <i>(vs raw {@code byte[]})</i.>
231+
*/
232+
public boolean isNode(@Nonnull JvmClassBundle bundle, @Nonnull JvmClassInfo info) {
233+
JvmClassData data = getJvmClassData(bundle, info);
234+
return data.node != null;
235+
}
236+
224237
/**
225238
* Gets the current ASM node representation of the given class.
226239
* <p/>

0 commit comments

Comments
 (0)