Skip to content

Commit 47d3327

Browse files
committed
Merge ThisTestUser's fork
1 parent be6fb1f commit 47d3327

34 files changed

+5962
-1115
lines changed

src/main/java/com/javadeobfuscator/deobfuscator/Deobfuscator.java

Lines changed: 80 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -16,41 +16,26 @@
1616

1717
package com.javadeobfuscator.deobfuscator;
1818

19-
import com.javadeobfuscator.deobfuscator.asm.ConstantPool;
20-
import com.javadeobfuscator.deobfuscator.config.Configuration;
21-
import com.javadeobfuscator.deobfuscator.config.TransformerConfig;
22-
import com.javadeobfuscator.deobfuscator.exceptions.NoClassInPathException;
23-
import com.javadeobfuscator.deobfuscator.rules.Rule;
24-
import com.javadeobfuscator.deobfuscator.rules.Rules;
25-
import com.javadeobfuscator.deobfuscator.transformers.Transformer;
26-
import com.javadeobfuscator.deobfuscator.utils.ClassTree;
27-
import com.javadeobfuscator.deobfuscator.utils.Utils;
28-
import org.apache.commons.io.IOUtils;
29-
import org.objectweb.asm.ClassReader;
30-
import org.objectweb.asm.ClassWriter;
31-
import org.objectweb.asm.Opcodes;
32-
import org.objectweb.asm.commons.JSRInlinerAdapter;
33-
import org.objectweb.asm.tree.AbstractInsnNode;
34-
import org.objectweb.asm.tree.ClassNode;
35-
import org.objectweb.asm.tree.MethodInsnNode;
36-
import org.objectweb.asm.tree.MethodNode;
37-
import org.objectweb.asm.util.CheckClassAdapter;
38-
import org.slf4j.Logger;
39-
import org.slf4j.LoggerFactory;
40-
41-
import java.io.File;
42-
import java.io.FileOutputStream;
43-
import java.io.IOException;
44-
import java.lang.reflect.Modifier;
45-
import java.util.AbstractMap.SimpleEntry;
19+
import com.javadeobfuscator.deobfuscator.asm.*;
20+
import com.javadeobfuscator.deobfuscator.config.*;
21+
import com.javadeobfuscator.deobfuscator.exceptions.*;
22+
import com.javadeobfuscator.deobfuscator.rules.*;
23+
import com.javadeobfuscator.deobfuscator.transformers.*;
24+
import com.javadeobfuscator.deobfuscator.utils.*;
25+
import org.apache.commons.io.*;
26+
import org.objectweb.asm.*;
27+
import org.objectweb.asm.commons.*;
28+
import org.objectweb.asm.tree.*;
29+
import org.objectweb.asm.util.*;
30+
import org.slf4j.*;
31+
32+
import java.io.*;
33+
import java.lang.reflect.*;
34+
import java.util.AbstractMap.*;
4635
import java.util.*;
47-
import java.util.Map.Entry;
48-
import java.util.regex.Matcher;
49-
import java.util.regex.Pattern;
50-
import java.util.regex.PatternSyntaxException;
51-
import java.util.zip.ZipEntry;
52-
import java.util.zip.ZipFile;
53-
import java.util.zip.ZipOutputStream;
36+
import java.util.Map.*;
37+
import java.util.regex.*;
38+
import java.util.zip.*;
5439

5540
public class Deobfuscator {
5641
private Map<String, ClassNode> classpath = new HashMap<>();
@@ -83,6 +68,13 @@ public Deobfuscator(Configuration configuration) {
8368
* enable this to dump troublesome classes. Note that this will not get rid of all junk classes.
8469
*/
8570
private static final boolean DELETE_USELESS_CLASSES = false;
71+
72+
public Map<String, byte[]> invaildClasses = new HashMap<>();
73+
74+
/**
75+
* Must enable for paramorphism obfuscated files.
76+
*/
77+
private static final boolean PARAMORPHISM = false;
8678

8779
public ConstantPool getConstantPool(ClassNode classNode) {
8880
return this.constantPools.get(classNode);
@@ -176,26 +168,69 @@ private boolean isClassIgnored(ClassNode classNode) {
176168
}
177169

178170
private void loadInput() throws IOException {
171+
if(PARAMORPHISM)
172+
{
173+
Map<String, String> classNameToName = new HashMap<>();
174+
Map<String, byte[]> entries = new HashMap<>();
175+
//Check all duplicate files
176+
try (ZipFile zipIn = new ZipFile(configuration.getInput())) {
177+
Enumeration<? extends ZipEntry> e = zipIn.entries();
178+
while (e.hasMoreElements()) {
179+
ZipEntry next = e.nextElement();
180+
if (next.isDirectory() || !next.getName().endsWith(".class")) {
181+
continue;
182+
}
183+
184+
try {
185+
byte[] data = IOUtils.toByteArray(zipIn.getInputStream(next));
186+
ClassReader reader = new ClassReader(data);
187+
ClassNode node = new ClassNode();
188+
reader.accept(node, ClassReader.SKIP_FRAMES);
189+
if(entries.containsKey(node.name))
190+
{
191+
invaildClasses.put(next.getName(), data);
192+
invaildClasses.put(classNameToName.get(node.name), entries.get(node.name));
193+
}else
194+
{
195+
classNameToName.put(node.name, next.getName());
196+
entries.put(node.name, data);
197+
}
198+
}catch(Exception ex)
199+
{
200+
continue;
201+
}
202+
}
203+
}
204+
//Filter out real classes
205+
List<String> real = new ArrayList<>();
206+
for(Entry<String, byte[]> entry : invaildClasses.entrySet())
207+
{
208+
ClassReader reader = new ClassReader(entry.getValue());
209+
ClassNode node = new ClassNode();
210+
reader.accept(node, ClassReader.SKIP_FRAMES);
211+
if((node.name + ".class").equals(entry.getKey()))
212+
real.add(entry.getKey());
213+
}
214+
real.forEach(s -> invaildClasses.remove(s));
215+
}
179216
try (ZipFile zipIn = new ZipFile(configuration.getInput())) {
180217
Enumeration<? extends ZipEntry> e = zipIn.entries();
181218
while (e.hasMoreElements()) {
182219
ZipEntry next = e.nextElement();
183-
if (next.isDirectory() && !next.getName().endsWith(".class/")) {
220+
if (next.isDirectory()) {
184221
continue;
185222
}
186223

187224
byte[] data = IOUtils.toByteArray(zipIn.getInputStream(next));
188225
loadInput(next.getName(), data);
189226
}
190-
191-
classpath.putAll(classes);
192227
}
193228
}
194229

195230
public void loadInput(String name, byte[] data) {
196231
boolean passthrough = true;
197232

198-
if (name.endsWith(".class") || name.endsWith(".class/")) {
233+
if (name.endsWith(".class")) {
199234
try {
200235
ClassReader reader = new ClassReader(data);
201236
ClassNode node = new ClassNode();
@@ -212,13 +247,17 @@ public void loadInput(String name, byte[] data) {
212247
node.methods.set(i, adapter);
213248
}
214249

215-
classes.put(node.name, node);
250+
if(!invaildClasses.containsKey(name))
251+
classes.put(node.name, node);
252+
classpath.put(node.name, node);
216253
passthrough = false;
217254
} else {
218255
classpath.put(node.name, node);
219256
}
220-
} catch (Exception x) {
221-
logger.error("Could not parse {} (is it a class file?)", name, x);
257+
} catch (IllegalArgumentException x) {
258+
logger.error("Could not parse {} (is it a class file?)", name, x);
259+
} catch (ArrayIndexOutOfBoundsException x) {
260+
logger.error("Could not parse {} (is it a class file?)", name, x);
222261
}
223262
}
224263

@@ -402,10 +441,6 @@ public List<ClassNode> loadHierachy(ClassNode specificNode) {
402441
if (specificNode.name.equals("java/lang/Object")) {
403442
return Collections.emptyList();
404443
}
405-
if ((specificNode.access & Opcodes.ACC_INTERFACE) != 0) {
406-
getOrCreateClassTree(specificNode.name).parentClasses.add("java/lang/Object");
407-
return Collections.emptyList();
408-
}
409444
List<ClassNode> toProcess = new ArrayList<>();
410445

411446
ClassTree thisTree = getOrCreateClassTree(specificNode.name);

0 commit comments

Comments
 (0)