diff --git a/jadx-core/src/main/java/jadx/api/JadxDecompiler.java b/jadx-core/src/main/java/jadx/api/JadxDecompiler.java index 4a82d9bb5..d69c9d26d 100644 --- a/jadx-core/src/main/java/jadx/api/JadxDecompiler.java +++ b/jadx-core/src/main/java/jadx/api/JadxDecompiler.java @@ -435,7 +435,7 @@ public final class JadxDecompiler implements Closeable { return list; } - public List getClasses() { + public synchronized List getClasses() { if (root == null) { return Collections.emptyList(); } @@ -443,10 +443,7 @@ public final class JadxDecompiler implements Closeable { List classNodeList = root.getClasses(); List clsList = new ArrayList<>(classNodeList.size()); for (ClassNode classNode : classNodeList) { - if (classNode.contains(AFlag.DONT_GENERATE)) { - continue; - } - if (!classNode.getClassInfo().isInner()) { + if (!classNode.contains(AFlag.DONT_GENERATE) && !classNode.isInner()) { clsList.add(convertClassNode(classNode)); } } diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java index dd205f3ff..5f95fbb43 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java @@ -612,17 +612,9 @@ public class ClassNode extends NotificationAttrNode return parentClass; } - public void updateParentClass() { - if (clsInfo.isInner()) { - ClassNode parent = root.resolveClass(clsInfo.getParentClass()); - if (parent != null) { - parentClass = parent; - return; - } - // undo inner mark in class info - clsInfo.notInner(root); - } - parentClass = this; + public void notInner() { + this.clsInfo.notInner(root); + this.parentClass = this; } /** diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java index bb78e5d75..4d7a16982 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java @@ -159,7 +159,7 @@ public class RootNode { LOG.info("Loaded classes: {}, methods: {}, instructions: {}", classes.size(), mthCount, insnsCount); // sort classes by name, expect top classes before inner - classes.sort(Comparator.comparing(ClassNode::getFullName)); + classes.sort(Comparator.comparing(ClassNode::getRawName)); if (args.isMoveInnerClasses()) { // detect and move inner classes @@ -309,10 +309,8 @@ public class RootNode { ClassInfo clsInfo = cls.getClassInfo(); ClassNode parent = resolveParentClass(clsInfo); if (parent == null) { - clsMap.remove(clsInfo); - clsInfo.notInner(this); - clsMap.put(clsInfo, cls); updated.add(cls); + cls.notInner(); } else { parent.addInnerClass(cls); } @@ -323,7 +321,6 @@ public class RootNode { innerCls.getClassInfo().updateNames(this); } } - classes.forEach(ClassNode::updateParentClass); for (PackageNode pkg : packages) { pkg.getClasses().removeIf(cls -> cls.getClassInfo().isInner()); } diff --git a/jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java b/jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java index 626fac77e..dd23a7fb9 100644 --- a/jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java +++ b/jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java @@ -221,8 +221,7 @@ public abstract class IntegrationTest extends TestUtils { } else { LOG.info("Convert back to top level: {}", cls); cls.getTopParentClass().decompile(); // keep correct process order - cls.getClassInfo().notInner(root); - cls.updateParentClass(); + cls.notInner(); } decompileAndCheck(cls); return cls; diff --git a/jadx-plugins/jadx-smali-input/src/main/java/jadx/plugins/input/smali/SmaliConvert.java b/jadx-plugins/jadx-smali-input/src/main/java/jadx/plugins/input/smali/SmaliConvert.java index e3dc3c1d2..83d5732f7 100644 --- a/jadx-plugins/jadx-smali-input/src/main/java/jadx/plugins/input/smali/SmaliConvert.java +++ b/jadx-plugins/jadx-smali-input/src/main/java/jadx/plugins/input/smali/SmaliConvert.java @@ -1,11 +1,11 @@ package jadx.plugins.input.smali; -import java.io.OutputStream; -import java.io.PrintStream; import java.nio.file.FileSystems; import java.nio.file.Path; import java.nio.file.PathMatcher; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -51,16 +51,18 @@ public class SmaliConvert { long start = System.currentTimeMillis(); if (threads == 1 || inputFiles.size() == 1) { for (Path inputFile : inputFiles) { - assemble(inputFile, smaliOptions); + assemble(dexData, inputFile, smaliOptions); } } else { try { ExecutorService executor = Executors.newFixedThreadPool(threads); + List syncList = Collections.synchronizedList(dexData); for (Path inputFile : inputFiles) { - executor.execute(() -> assemble(inputFile, smaliOptions)); + executor.execute(() -> assemble(syncList, inputFile, smaliOptions)); } executor.shutdown(); - executor.awaitTermination(1, TimeUnit.DAYS); + executor.awaitTermination(1, TimeUnit.HOURS); + dexData.sort(Comparator.comparing(IDexData::getFileName)); } catch (InterruptedException e) { LOG.error("Smali compile interrupted", e); } @@ -70,30 +72,16 @@ public class SmaliConvert { } } - private void assemble(Path inputFile, SmaliOptions smaliOptions) { + private void assemble(List results, Path inputFile, SmaliOptions smaliOptions) { Path path = inputFile.toAbsolutePath(); try { byte[] dexContent = SmaliUtils.assemble(path.toFile(), smaliOptions); - dexData.add(new SimpleDexData(path.toString(), dexContent)); + results.add(new SimpleDexData(path.toString(), dexContent)); } catch (Exception e) { LOG.error("Failed to assemble smali file: {}", path, e); } } - private static void collectSystemErrors(OutputStream out, Runnable exec) { - PrintStream systemErr = System.err; - try (PrintStream err = new PrintStream(out)) { - System.setErr(err); - try { - exec.run(); - } catch (Exception e) { - e.printStackTrace(err); - } - } finally { - System.setErr(systemErr); - } - } - private List filterSmaliFiles(List input) { PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**.smali"); return input.stream()