static int processAndSave(JadxCLIArgs inputArgs) { JadxDecompiler jadx = new JadxDecompiler(inputArgs.toJadxArgs()); try { jadx.load(); } catch (JadxArgsValidateException e) { LOG.error("Incorrect arguments: {}", e.getMessage()); return 1; } jadx.save(); int errorsCount = jadx.getErrorsCount(); if (errorsCount != 0) { jadx.printErrorsReport(); LOG.error("finished with errors"); } else { LOG.info("done"); } return errorsCount; } }
/** * Get the complete list of classes */ public List<JavaClass> getClasses() { return decompiler.getClasses(); }
@Override public String toString() { return "jadx decompiler " + getVersion(); } }
public void openFile(File file) { this.openFile = file; try { this.decompiler = new JadxDecompiler(settings.toJadxArgs()); this.decompiler.getArgs().setInputFiles(Collections.singletonList(file)); this.decompiler.load(); } catch (Exception e) { LOG.error("Error load file: {}", file, e); } }
public void load() { reset(); JadxArgsValidator.validate(args); init(); LOG.info("loading ..."); loadFiles(args.getInputFiles()); root = new RootNode(args); root.load(inputFiles); root.initClassPath(); root.loadResources(getResources()); initVisitors(); }
@Test @Ignore public void testExampleUsage() { JadxArgs args = new JadxArgs(); args.getInputFiles().add(new File("test.apk")); args.setOutDir(new File("jadx-test-output")); JadxDecompiler jadx = new JadxDecompiler(args); jadx.load(); jadx.save(); }
protected void decompile(JadxArgs jadxArgs, @Nullable String clsPatternStr, @Nullable String mthPatternStr) { JadxDecompiler jadx = new JadxDecompiler(jadxArgs); jadx.load(); if (clsPatternStr == null) { processAll(jadx); // jadx.saveSources(); } else { Pattern clsPtrn = Pattern.compile(clsPatternStr); Pattern mthPtrn = mthPatternStr == null ? null : Pattern.compile(mthPatternStr); processByPatterns(jadx, clsPtrn, mthPtrn); } printErrorReport(jadx); }
@Override public void run() { try { decompiler.getArgs().setRootDir(dir); ThreadPoolExecutor ex = (ThreadPoolExecutor) decompiler.getSaveExecutor(); ex.shutdown(); while (ex.isTerminating()) { long total = ex.getTaskCount(); long done = ex.getCompletedTaskCount(); progressMonitor.setProgress((int) (done * 100.0 / (double) total)); Thread.sleep(500); } progressMonitor.close(); LOG.info("decompilation complete, freeing memory ..."); decompiler.getClasses().forEach(JavaClass::unload); LOG.info("done"); } catch (InterruptedException e) { LOG.error("Save interrupted", e); Thread.currentThread().interrupt(); } } };
public void saveSources() { save(true, false); }
private void printErrorReport(JadxDecompiler jadx) { jadx.printErrorsReport(); assertThat(jadx.getErrorsCount(), is(0)); } }
@Before public void init() { JRoot root = mock(JRoot.class); when(root.isFlatPackages()).thenReturn(false); JadxWrapper wrapper = mock(JadxWrapper.class); sources = new JSources(root, wrapper); decompiler = new JadxDecompiler(new JadxArgs()); }
public JadxArgs getArgs() { return decompiler.getArgs(); } }
private void save(boolean saveSources, boolean saveResources) { ExecutorService ex = getSaveExecutor(saveSources, saveResources); ex.shutdown(); try { ex.awaitTermination(1, TimeUnit.DAYS); } catch (InterruptedException e) { LOG.error("Save interrupted", e); Thread.currentThread().interrupt(); } }
public List<ResourceFile> getResources() { return decompiler.getResources(); }
public ClassNode getClassNodeFromFile(File file, String clsName) { JadxDecompiler d = null; try { args.setInputFiles(Collections.singletonList(file)); d = new JadxDecompiler(args); d.load(); } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } RootNode root = JadxInternalAccess.getRoot(d); insertResources(root); ClassNode cls = root.searchClassByName(clsName); assertThat("Class not found: " + clsName, cls, notNullValue()); assertThat(clsName, is(cls.getClassInfo().getFullName())); if (unloadCls) { decompile(d, cls); } else { decompileWithoutUnload(d, cls); } System.out.println("-----------------------------------------------------------"); System.out.println(cls.getCode()); System.out.println("-----------------------------------------------------------"); checkCode(cls); compile(cls); runAutoCheck(clsName); return cls; }
public void saveResources() { save(false, true); }
private void processByPatterns(JadxDecompiler jadx, Pattern clsPattern, @Nullable Pattern mthPattern) { List<IDexTreeVisitor> passes = Jadx.getPassesList(jadx.getArgs()); RootNode root = JadxInternalAccess.getRoot(jadx); int processed = 0; for (ClassNode classNode : root.getClasses(true)) { String clsFullName = classNode.getClassInfo().getFullName(); if (clsPattern.matcher(clsFullName).matches()) { if (processCls(mthPattern, passes, classNode)) { processed++; } } } assertThat("No classes processed", processed, greaterThan(0)); }
public ExecutorService getSaveExecutor() { return getSaveExecutor(!args.isSkipSources(), !args.isSkipResources()); }
private void appendResourcesSave(ExecutorService executor, File outDir) { for (ResourceFile resourceFile : getResources()) { executor.execute(new ResourcesSaver(outDir, resourceFile)); } }
private static Release checkForNewRelease() throws IOException { String version = JadxDecompiler.getVersion(); if (version.contains("dev")) { LOG.debug("Ignore check for update: development version"); return null; } List<Release> list = get(GITHUB_RELEASES_URL, RELEASES_LIST_TYPE); if (list == null) { return null; } list.removeIf(release -> release.getName().equalsIgnoreCase(version) || release.isPreRelease()); if (list.isEmpty()) { return null; } list.sort(RELEASE_COMPARATOR); Release latest = list.get(list.size() - 1); if (VersionComparator.checkAndCompare(version, latest.getName()) >= 0) { return null; } LOG.info("Found new jadx version: {}", latest); return latest; }