Skip to content

Commit

Permalink
feat(cli): add option to disable plugins (#2277)
Browse files Browse the repository at this point in the history
  • Loading branch information
skylot committed Nov 1, 2024
1 parent 313c4a1 commit 57238de
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 18 deletions.
8 changes: 8 additions & 0 deletions jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,9 @@ public class JadxCLIArgs {
@Parameter(names = { "-q", "--quiet" }, description = "turn off output (set --log-level to QUIET)")
protected boolean quiet = false;

@Parameter(names = { "--disable-plugins" }, description = "comma separated list of plugin ids to disable")
protected String disablePlugins = "";

@Parameter(names = { "--version" }, description = "print jadx version")
protected boolean printVersion = false;

Expand Down Expand Up @@ -370,6 +373,7 @@ public JadxArgs toJadxArgs() {
args.setIntegerFormat(integerFormat);
args.setUseDxInput(useDx);
args.setPluginOptions(pluginOptions);
args.setDisabledPlugins(Arrays.stream(disablePlugins.split(",")).map(String::trim).collect(Collectors.toSet()));
return args;
}

Expand Down Expand Up @@ -580,6 +584,10 @@ public Map<String, String> getPluginOptions() {
return pluginOptions;
}

public String getDisablePlugins() {
return disablePlugins;
}

static class RenameConverter implements IStringConverter<Set<RenameEnum>> {
private final String paramName;

Expand Down
4 changes: 2 additions & 2 deletions jadx-cli/src/main/java/jadx/cli/JadxCLICommands.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package jadx.cli;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;

import com.beust.jcommander.JCommander;

Expand All @@ -10,7 +10,7 @@
import jadx.core.utils.exceptions.JadxArgsValidateException;

public class JadxCLICommands {
private static final Map<String, ICommand> COMMANDS_MAP = new TreeMap<>();
private static final Map<String, ICommand> COMMANDS_MAP = new LinkedHashMap<>();

static {
JadxCLICommands.register(new CommandPlugins());
Expand Down
49 changes: 38 additions & 11 deletions jadx-cli/src/main/java/jadx/cli/commands/CommandPlugins.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package jadx.cli.commands;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;

import jadx.api.plugins.JadxPluginInfo;
import jadx.cli.JCommanderWrapper;
import jadx.cli.LogHelper;
import jadx.plugins.tools.JadxPluginsList;
import jadx.plugins.tools.JadxPluginsTools;
import jadx.plugins.tools.data.JadxPluginMetadata;
Expand All @@ -24,6 +29,9 @@ public class CommandPlugins implements ICommand {
@Parameter(names = { "-l", "--list" }, description = "list installed plugins")
protected boolean list;

@Parameter(names = { "--list-all" }, description = "list all plugins including bundled and dropins")
protected boolean listAll;

@Parameter(names = { "-a", "--available" }, description = "list available plugins")
protected boolean available;

Expand Down Expand Up @@ -53,8 +61,12 @@ public void process(JCommanderWrapper<?> jcw, JCommander subCommander) {
jcw.printUsage(subCommander);
return;
}
if (!subCommander.getUnknownOptions().isEmpty()) {
System.out.println("Error: found unknown options: " + subCommander.getUnknownOptions());
Set<String> unknownOptions = new HashSet<>(subCommander.getUnknownOptions());
boolean verbose = unknownOptions.remove("-v") || unknownOptions.remove("--verbose");
LogHelper.setLogLevel(verbose ? LogHelper.LogLevelEnum.DEBUG : LogHelper.LogLevelEnum.INFO);

if (!unknownOptions.isEmpty()) {
System.out.println("Error: found unknown options: " + unknownOptions);
}

if (install != null) {
Expand All @@ -79,7 +91,10 @@ public void process(JCommanderWrapper<?> jcw, JCommander subCommander) {
}
}
if (list) {
printInstalledPlugins();
printPlugins(JadxPluginsTools.getInstance().getInstalled());
}
if (listAll) {
printAllPlugins();
}

if (available) {
Expand Down Expand Up @@ -107,28 +122,40 @@ public void process(JCommanderWrapper<?> jcw, JCommander subCommander) {
}
}

private static void printInstalledPlugins() {
List<JadxPluginMetadata> installed = JadxPluginsTools.getInstance().getInstalled();
private static void printPlugins(List<JadxPluginMetadata> installed) {
System.out.println("Installed plugins: " + installed.size());
for (JadxPluginMetadata plugin : installed) {
StringBuilder sb = new StringBuilder();
sb.append(" - ");
sb.append(plugin.getPluginId());
sb.append(" - ").append(plugin.getPluginId());
String version = plugin.getVersion();
if (version != null) {
sb.append(" (").append(version).append(')');
}
if (plugin.isDisabled()) {
sb.append(" (disabled)");
}
sb.append(" - ");
sb.append(plugin.getName());
sb.append(": ");
sb.append(plugin.getDescription());
sb.append(" - ").append(plugin.getName());
sb.append(": ").append(plugin.getDescription());
System.out.println(sb);
}
}

private static void printAllPlugins() {
List<JadxPluginMetadata> installed = JadxPluginsTools.getInstance().getInstalled();
printPlugins(installed);
Set<String> installedSet = installed.stream().map(JadxPluginMetadata::getPluginId).collect(Collectors.toSet());

List<JadxPluginInfo> plugins = JadxPluginsTools.getInstance().getAllPluginsInfo();
System.out.println("Other plugins: " + plugins.size());
for (JadxPluginInfo plugin : plugins) {
if (!installedSet.contains(plugin.getPluginId())) {
System.out.println(" - " + plugin.getPluginId()
+ " - " + plugin.getName()
+ ": " + plugin.getDescription());
}
}
}

private void installPlugin(String locationId) {
JadxPluginMetadata plugin = JadxPluginsTools.getInstance().install(locationId);
System.out.println("Plugin installed: " + plugin.getPluginId() + ":" + plugin.getVersion());
Expand Down
11 changes: 11 additions & 0 deletions jadx-core/src/main/java/jadx/api/JadxArgs.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -194,6 +195,8 @@ public enum UseKotlinMethodsForVarNames {

private Map<String, String> pluginOptions = new HashMap<>();

private Set<String> disabledPlugins = new HashSet<>();

private JadxPluginLoader pluginLoader = new JadxBasePluginLoader();

private boolean loadJadxClsSetFile = true;
Expand Down Expand Up @@ -766,6 +769,14 @@ public void setPluginOptions(Map<String, String> pluginOptions) {
this.pluginOptions = pluginOptions;
}

public Set<String> getDisabledPlugins() {
return disabledPlugins;
}

public void setDisabledPlugins(Set<String> disabledPlugins) {
this.disabledPlugins = disabledPlugins;
}

public JadxPluginLoader getPluginLoader() {
return pluginLoader;
}
Expand Down
8 changes: 5 additions & 3 deletions jadx-core/src/main/java/jadx/api/JadxDecompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,15 @@ public final class JadxDecompiler implements Closeable {
private static final Logger LOG = LoggerFactory.getLogger(JadxDecompiler.class);

private final JadxArgs args;
private final JadxPluginManager pluginManager = new JadxPluginManager(this);
private final JadxPluginManager pluginManager;
private final List<ICodeLoader> loadedInputs = new ArrayList<>();

private RootNode root;
private List<JavaClass> classes;
private List<ResourceFile> resources;

private final IDecompileScheduler decompileScheduler = new DecompilerScheduler();
private final ResourcesLoader resourcesLoader = new ResourcesLoader(this);
private final ResourcesLoader resourcesLoader;

private final List<ICodeLoader> customCodeLoaders = new ArrayList<>();
private final List<CustomResourcesLoader> customResourcesLoaders = new ArrayList<>();
Expand All @@ -106,7 +106,9 @@ public JadxDecompiler() {
}

public JadxDecompiler(JadxArgs args) {
this.args = args;
this.args = Objects.requireNonNull(args);
this.pluginManager = new JadxPluginManager(this);
this.resourcesLoader = new ResourcesLoader(this);
}

public void load() {
Expand Down
13 changes: 12 additions & 1 deletion jadx-core/src/main/java/jadx/core/plugins/JadxPluginManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -26,6 +28,7 @@ public class JadxPluginManager {

private final JadxDecompiler decompiler;
private final JadxPluginsData pluginsData;
private final Set<String> disabledPlugins;
private final SortedSet<PluginContext> allPlugins = new TreeSet<>();
private final SortedSet<PluginContext> resolvedPlugins = new TreeSet<>();
private final Map<String, String> provideSuggestions = new TreeMap<>();
Expand All @@ -35,6 +38,7 @@ public class JadxPluginManager {
public JadxPluginManager(JadxDecompiler decompiler) {
this.decompiler = decompiler;
this.pluginsData = new JadxPluginsData(decompiler, this);
this.disabledPlugins = decompiler.getArgs().getDisabledPlugins();
}

/**
Expand All @@ -55,12 +59,19 @@ public void load(JadxPluginLoader pluginLoader) {
public void register(JadxPlugin plugin) {
Objects.requireNonNull(plugin);
PluginContext addedPlugin = addPlugin(plugin);
if (addedPlugin == null) {
LOG.debug("Can't register plugin, it was disabled: {}", plugin.getPluginInfo().getPluginId());
return;
}
LOG.debug("Register plugin: {}", addedPlugin.getPluginId());
resolve();
}

private PluginContext addPlugin(JadxPlugin plugin) {
private @Nullable PluginContext addPlugin(JadxPlugin plugin) {
PluginContext pluginContext = new PluginContext(decompiler, pluginsData, plugin);
if (disabledPlugins.contains(pluginContext.getPluginId())) {
return null;
}
LOG.debug("Loading plugin: {}", pluginContext);
if (!allPlugins.add(pluginContext)) {
throw new IllegalArgumentException("Duplicate plugin id: " + pluginContext + ", class " + plugin.getClass());
Expand Down
1 change: 1 addition & 0 deletions jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public class JadxSettings extends JadxCLIArgs {
static final Set<String> SKIP_FIELDS = new HashSet<>(Arrays.asList(
"files", "input", "outDir", "outDirSrc", "outDirRes", "outputFormat",
"deobfuscationMapFile",
"disablePlugins",
"verbose", "quiet", "logLevel",
"printVersion", "printHelp"));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ public List<PluginContext> build() {
.ifPresent(decompiler -> allPlugins.addAll(decompiler.getPluginManager().getResolvedPluginContexts()));

// collect and init not loaded plugins in new temp context
try (JadxDecompiler decompiler = new JadxDecompiler(new JadxArgs())) {
JadxArgs jadxArgs = mainWindow.getSettings().toJadxArgs();
try (JadxDecompiler decompiler = new JadxDecompiler(jadxArgs)) {
JadxPluginManager pluginManager = decompiler.getPluginManager();
pluginManager.registerAddPluginListener(pluginContext -> {
AppContext appContext = new AppContext();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -115,6 +116,20 @@ public List<JadxPluginMetadata> getInstalled() {
return loadPluginsJson().getInstalled();
}

/**
* Return all loadable plugins info (including installed, bundled and dropins).
* <br>
* For only installed plugins prefer {@link jadx.plugins.tools.JadxPluginsTools#getInstalled}
* method.
*/
public List<JadxPluginInfo> getAllPluginsInfo() {
try (JadxExternalPluginsLoader pluginsLoader = new JadxExternalPluginsLoader()) {
return pluginsLoader.load().stream()
.map(JadxPlugin::getPluginInfo)
.collect(Collectors.toList());
}
}

public List<Path> getAllPluginJars() {
List<Path> list = new ArrayList<>();
for (JadxPluginMetadata pluginMetadata : loadPluginsJson().getInstalled()) {
Expand Down

0 comments on commit 57238de

Please sign in to comment.