Skip to content

Commit 0ac1858

Browse files
committed
Fix LocalVariableRenameTransformer going outside of scope.
1 parent 18155cb commit 0ac1858

File tree

3 files changed

+91
-18
lines changed

3 files changed

+91
-18
lines changed

src/main/java/net/cvs0/core/ObfuscationEngine.java

Lines changed: 76 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -84,18 +84,39 @@ private Map<String, byte[]> obfuscateWithTransformers(Map<String, byte[]> inputC
8484
byte[] classBytes = entry.getValue();
8585

8686
ClassReader reader = new ClassReader(classBytes);
87-
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
87+
String actualClassName = reader.getClassName();
88+
89+
boolean shouldProcess = shouldProcessClass(actualClassName, config);
90+
if (!shouldProcess) {
91+
result.put(className, classBytes);
92+
continue;
93+
}
94+
95+
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS);
8896

8997
ClassReader currentReader = reader;
9098
ClassWriter currentWriter = writer;
9199

92100
for (Transformer transformer : transformers) {
93101
if (transformer.isEnabled(context)) {
94-
ClassWriter nextWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
102+
ClassWriter nextWriter = new ClassWriter(currentReader, ClassWriter.COMPUTE_MAXS);
95103
transformer.transform(currentReader, nextWriter, context);
96104

97-
currentReader = new ClassReader(nextWriter.toByteArray());
98-
currentWriter = nextWriter;
105+
byte[] transformedBytes = nextWriter.toByteArray();
106+
107+
try {
108+
ClassReader testReader = new ClassReader(transformedBytes);
109+
String testClassName = testReader.getClassName();
110+
if (testClassName == null) {
111+
System.err.println("Transformer " + transformer.getName() + " produced invalid bytecode for class " + className + " - skipping further transformations");
112+
break;
113+
}
114+
currentReader = testReader;
115+
currentWriter = nextWriter;
116+
} catch (Exception e) {
117+
System.err.println("Transformer " + transformer.getName() + " produced malformed bytecode for class " + className + ": " + e.getMessage() + " - skipping further transformations");
118+
break;
119+
}
99120
}
100121
}
101122

@@ -113,23 +134,42 @@ private void setupMappingManager(ObfuscationContext context, Map<String, byte[]>
113134
mappingManager.setInheritanceTracker(inheritanceTracker);
114135

115136
for (Map.Entry<String, byte[]> entry : inputClasses.entrySet()) {
116-
ClassReader reader = new ClassReader(entry.getValue());
117-
net.cvs0.discovery.InheritanceDiscoveryVisitor inheritanceVisitor = new net.cvs0.discovery.InheritanceDiscoveryVisitor(inheritanceTracker);
118-
reader.accept(inheritanceVisitor, ClassReader.SKIP_CODE);
137+
try {
138+
ClassReader reader = new ClassReader(entry.getValue());
139+
if (reader.getClassName() != null) {
140+
net.cvs0.discovery.InheritanceDiscoveryVisitor inheritanceVisitor = new net.cvs0.discovery.InheritanceDiscoveryVisitor(inheritanceTracker);
141+
reader.accept(inheritanceVisitor, ClassReader.SKIP_CODE);
142+
}
143+
} catch (Exception e) {
144+
System.err.println("Skipping class during inheritance discovery: " + entry.getKey() + " - " + e.getMessage());
145+
}
119146
}
120147

121148
Set<String> classNames = new HashSet<>();
122149
for (String className : inputClasses.keySet()) {
123-
ClassReader reader = new ClassReader(inputClasses.get(className));
124-
classNames.add(reader.getClassName());
150+
try {
151+
ClassReader reader = new ClassReader(inputClasses.get(className));
152+
String readerClassName = reader.getClassName();
153+
if (readerClassName != null) {
154+
classNames.add(readerClassName);
155+
}
156+
} catch (Exception e) {
157+
System.err.println("Skipping class during name collection: " + className + " - " + e.getMessage());
158+
}
125159
}
126160

127161
mappingManager.generateClassMappings(classNames);
128162

129163
for (Map.Entry<String, byte[]> entry : inputClasses.entrySet()) {
130-
ClassReader reader = new ClassReader(entry.getValue());
131-
net.cvs0.discovery.ClassDiscoveryVisitor discoveryVisitor = new net.cvs0.discovery.ClassDiscoveryVisitor(mappingManager, inheritanceTracker);
132-
reader.accept(discoveryVisitor, ClassReader.SKIP_CODE);
164+
try {
165+
ClassReader reader = new ClassReader(entry.getValue());
166+
if (reader.getClassName() != null) {
167+
net.cvs0.discovery.ClassDiscoveryVisitor discoveryVisitor = new net.cvs0.discovery.ClassDiscoveryVisitor(mappingManager, inheritanceTracker);
168+
reader.accept(discoveryVisitor, ClassReader.SKIP_CODE);
169+
}
170+
} catch (Exception e) {
171+
System.err.println("Skipping class during discovery: " + entry.getKey() + " - " + e.getMessage());
172+
}
133173
}
134174

135175
context.setMappingManager(mappingManager);
@@ -180,8 +220,16 @@ private Map<String, byte[]> loadClassesFromJar(File inputJar) throws IOException
180220
.forEach(entry -> {
181221
try (InputStream inputStream = jarFile.getInputStream(entry)) {
182222
byte[] classBytes = inputStream.readAllBytes();
183-
String className = entry.getName().substring(0, entry.getName().length() - 6);
184-
classes.put(className, classBytes);
223+
224+
try {
225+
ClassReader testReader = new ClassReader(classBytes);
226+
String className = testReader.getClassName();
227+
if (className != null && !className.isEmpty()) {
228+
classes.put(className, classBytes);
229+
}
230+
} catch (Exception e) {
231+
System.err.println("Skipping invalid class file: " + entry.getName() + " - " + e.getMessage());
232+
}
185233
} catch (IOException e) {
186234
throw new RuntimeException("Failed to read class: " + entry.getName(), e);
187235
}
@@ -191,6 +239,20 @@ private Map<String, byte[]> loadClassesFromJar(File inputJar) throws IOException
191239
return classes;
192240
}
193241

242+
private boolean shouldProcessClass(String className, ObfuscationConfig config)
243+
{
244+
if (className == null) {
245+
return false;
246+
}
247+
248+
String packageScope = config.getPackageScope();
249+
if (packageScope != null && !packageScope.isEmpty()) {
250+
return className.startsWith(packageScope);
251+
}
252+
253+
return true;
254+
}
255+
194256
private void writeObfuscatedJar(File inputJar, File outputJar, Map<String, byte[]> obfuscatedClasses) throws IOException
195257
{
196258
try (JarFile jarFile = new JarFile(inputJar);

src/main/java/net/cvs0/transformers/ClassRenameTransformer.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,17 @@ public void transform(ClassReader reader, ClassWriter writer, ObfuscationContext
2323
}
2424

2525
String className = reader.getClassName();
26+
if (className == null) {
27+
try {
28+
logTransformation("ClassReader returned null className. Reader info - access: " + reader.getAccess() +
29+
", superName: " + reader.getSuperName() + ", interfaces: " + java.util.Arrays.toString(reader.getInterfaces()), context);
30+
} catch (Exception e) {
31+
logTransformation("ClassReader returned null className and failed to get additional info: " + e.getMessage(), context);
32+
}
33+
reader.accept(writer, 0);
34+
return;
35+
}
36+
2637
GlobalRemapper globalRemapper = new GlobalRemapper(context.getMappingManager());
2738
ClassRemapper remapper = new ClassRemapper(writer, globalRemapper);
2839

src/main/java/net/cvs0/transformers/LocalVariableRenameTransformer.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,11 @@ private boolean shouldRenameLocalVariable(String name, int index)
109109
return false;
110110
}
111111

112-
if (name.equals("this")) {
112+
if (name != null && name.equals("this")) {
113113
return false;
114114
}
115115

116-
if (name.startsWith("$")) {
116+
if (name != null && name.startsWith("$")) {
117117
return false;
118118
}
119119

@@ -126,11 +126,11 @@ private boolean shouldRenameParameter(String name)
126126
return false;
127127
}
128128

129-
if (name.equals("this")) {
129+
if (name != null && name.equals("this")) {
130130
return false;
131131
}
132132

133-
if (name.startsWith("$")) {
133+
if (name != null && name.startsWith("$")) {
134134
return false;
135135
}
136136

0 commit comments

Comments
 (0)