diff --git a/jadx-core/src/main/java/jadx/api/JadxDecompiler.java b/jadx-core/src/main/java/jadx/api/JadxDecompiler.java index cbea776a5..bb3a49e25 100644 --- a/jadx-core/src/main/java/jadx/api/JadxDecompiler.java +++ b/jadx-core/src/main/java/jadx/api/JadxDecompiler.java @@ -29,6 +29,7 @@ import jadx.api.metadata.annotations.NodeDeclareRef; import jadx.api.metadata.annotations.VarNode; import jadx.api.metadata.annotations.VarRef; import jadx.api.plugins.JadxPlugin; +import jadx.api.plugins.events.IJadxEvents; import jadx.api.plugins.input.ICodeLoader; import jadx.api.plugins.input.JadxCodeInput; import jadx.api.plugins.pass.JadxPass; @@ -44,6 +45,7 @@ import jadx.core.dex.nodes.RootNode; import jadx.core.dex.visitors.SaveCode; import jadx.core.export.ExportGradleTask; import jadx.core.plugins.JadxPluginManager; +import jadx.core.plugins.events.JadxEventsImpl; import jadx.core.utils.DecompilerScheduler; import jadx.core.utils.Utils; import jadx.core.utils.exceptions.JadxRuntimeException; @@ -94,6 +96,7 @@ public final class JadxDecompiler implements Closeable { private ProtoXMLParser protoXmlParser; private final IDecompileScheduler decompileScheduler = new DecompilerScheduler(); + private final JadxEventsImpl events = new JadxEventsImpl(); private final List customCodeLoaders = new ArrayList<>(); private final Map> customPasses = new HashMap<>(); @@ -129,6 +132,7 @@ public final class JadxDecompiler implements Closeable { LOG.info("reloading (passes only) ..."); customPasses.clear(); root.resetPasses(); + events.reset(); loadPlugins(); root.mergePasses(customPasses); root.restartVisitors(); @@ -159,6 +163,7 @@ public final class JadxDecompiler implements Closeable { resources = null; binaryXmlParser = null; protoXmlParser = null; + events.reset(); } @Override @@ -660,6 +665,10 @@ public final class JadxDecompiler implements Closeable { return decompileScheduler; } + public IJadxEvents events() { + return events; + } + public void addCustomCodeLoader(ICodeLoader customCodeLoader) { customCodeLoaders.add(customCodeLoader); } diff --git a/jadx-core/src/main/java/jadx/api/JavaClass.java b/jadx-core/src/main/java/jadx/api/JavaClass.java index 91bd9c7f9..8a373fae2 100644 --- a/jadx-core/src/main/java/jadx/api/JavaClass.java +++ b/jadx-core/src/main/java/jadx/api/JavaClass.java @@ -99,6 +99,11 @@ public final class JavaClass implements JavaNode { return false; } + @Override + public ICodeNodeRef getCodeNodeRef() { + return cls; + } + /** * Internal API. Not Stable! */ diff --git a/jadx-core/src/main/java/jadx/api/JavaField.java b/jadx-core/src/main/java/jadx/api/JavaField.java index 1ee8df859..f9b8b3550 100644 --- a/jadx-core/src/main/java/jadx/api/JavaField.java +++ b/jadx-core/src/main/java/jadx/api/JavaField.java @@ -5,6 +5,7 @@ import java.util.List; import org.jetbrains.annotations.ApiStatus; import jadx.api.metadata.ICodeAnnotation; +import jadx.api.metadata.ICodeNodeRef; import jadx.core.dex.info.AccessInfo; import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.nodes.FieldNode; @@ -74,6 +75,11 @@ public final class JavaField implements JavaNode { return false; } + @Override + public ICodeNodeRef getCodeNodeRef() { + return field; + } + /** * Internal API. Not Stable! */ diff --git a/jadx-core/src/main/java/jadx/api/JavaMethod.java b/jadx-core/src/main/java/jadx/api/JavaMethod.java index ed32607cb..22d4a5460 100644 --- a/jadx-core/src/main/java/jadx/api/JavaMethod.java +++ b/jadx-core/src/main/java/jadx/api/JavaMethod.java @@ -10,6 +10,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import jadx.api.metadata.ICodeAnnotation; +import jadx.api.metadata.ICodeNodeRef; import jadx.core.dex.attributes.AType; import jadx.core.dex.attributes.nodes.MethodOverrideAttr; import jadx.core.dex.info.AccessInfo; @@ -116,6 +117,11 @@ public final class JavaMethod implements JavaNode { return false; } + @Override + public ICodeNodeRef getCodeNodeRef() { + return mth; + } + /** * Internal API. Not Stable! */ diff --git a/jadx-core/src/main/java/jadx/api/JavaNode.java b/jadx-core/src/main/java/jadx/api/JavaNode.java index 86ea79747..3253d46d8 100644 --- a/jadx-core/src/main/java/jadx/api/JavaNode.java +++ b/jadx-core/src/main/java/jadx/api/JavaNode.java @@ -3,9 +3,12 @@ package jadx.api; import java.util.List; import jadx.api.metadata.ICodeAnnotation; +import jadx.api.metadata.ICodeNodeRef; public interface JavaNode { + ICodeNodeRef getCodeNodeRef(); + String getName(); String getFullName(); diff --git a/jadx-core/src/main/java/jadx/api/JavaPackage.java b/jadx-core/src/main/java/jadx/api/JavaPackage.java index ac665392f..d333d5981 100644 --- a/jadx-core/src/main/java/jadx/api/JavaPackage.java +++ b/jadx-core/src/main/java/jadx/api/JavaPackage.java @@ -8,6 +8,7 @@ import org.jetbrains.annotations.ApiStatus.Internal; import org.jetbrains.annotations.NotNull; import jadx.api.metadata.ICodeAnnotation; +import jadx.api.metadata.ICodeNodeRef; import jadx.core.dex.info.PackageInfo; import jadx.core.dex.nodes.PackageNode; @@ -75,6 +76,11 @@ public final class JavaPackage implements JavaNode, Comparable { return !Objects.equals(parent, aliasParent); } + @Override + public ICodeNodeRef getCodeNodeRef() { + return pkgNode; + } + @Internal public PackageNode getPkgNode() { return pkgNode; diff --git a/jadx-core/src/main/java/jadx/api/JavaVariable.java b/jadx-core/src/main/java/jadx/api/JavaVariable.java index 5112e61fb..679ffeb48 100644 --- a/jadx-core/src/main/java/jadx/api/JavaVariable.java +++ b/jadx-core/src/main/java/jadx/api/JavaVariable.java @@ -7,6 +7,7 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import jadx.api.metadata.ICodeAnnotation; +import jadx.api.metadata.ICodeNodeRef; import jadx.api.metadata.annotations.VarNode; import jadx.api.metadata.annotations.VarRef; import jadx.core.dex.instructions.args.ArgType; @@ -37,6 +38,11 @@ public class JavaVariable implements JavaNode { return varNode.getName(); } + @Override + public ICodeNodeRef getCodeNodeRef() { + return varNode; + } + @ApiStatus.Internal public VarNode getVarNode() { return varNode; diff --git a/jadx-core/src/main/java/jadx/api/metadata/ICodeAnnotation.java b/jadx-core/src/main/java/jadx/api/metadata/ICodeAnnotation.java index b3c4ec039..1fde82e50 100644 --- a/jadx-core/src/main/java/jadx/api/metadata/ICodeAnnotation.java +++ b/jadx-core/src/main/java/jadx/api/metadata/ICodeAnnotation.java @@ -6,6 +6,7 @@ public interface ICodeAnnotation { CLASS, FIELD, METHOD, + PKG, VAR, VAR_REF, DECLARATION, diff --git a/jadx-core/src/main/java/jadx/api/plugins/JadxPluginContext.java b/jadx-core/src/main/java/jadx/api/plugins/JadxPluginContext.java index a650eba85..8ceb1a50c 100644 --- a/jadx-core/src/main/java/jadx/api/plugins/JadxPluginContext.java +++ b/jadx-core/src/main/java/jadx/api/plugins/JadxPluginContext.java @@ -6,6 +6,7 @@ import org.jetbrains.annotations.Nullable; import jadx.api.JadxArgs; import jadx.api.JadxDecompiler; +import jadx.api.plugins.events.IJadxEvents; import jadx.api.plugins.gui.JadxGuiContext; import jadx.api.plugins.input.JadxCodeInput; import jadx.api.plugins.options.JadxPluginOptions; @@ -30,6 +31,11 @@ public interface JadxPluginContext { */ void registerInputsHashSupplier(Supplier supplier); + /** + * Subscribe and send events + */ + IJadxEvents events(); + @Nullable JadxGuiContext getGuiContext(); } diff --git a/jadx-core/src/main/java/jadx/api/plugins/events/IJadxEvent.java b/jadx-core/src/main/java/jadx/api/plugins/events/IJadxEvent.java new file mode 100644 index 000000000..ba7b5bf12 --- /dev/null +++ b/jadx-core/src/main/java/jadx/api/plugins/events/IJadxEvent.java @@ -0,0 +1,6 @@ +package jadx.api.plugins.events; + +public interface IJadxEvent { + + JadxEventType getType(); +} diff --git a/jadx-core/src/main/java/jadx/api/plugins/events/IJadxEvents.java b/jadx-core/src/main/java/jadx/api/plugins/events/IJadxEvents.java new file mode 100644 index 000000000..429a96000 --- /dev/null +++ b/jadx-core/src/main/java/jadx/api/plugins/events/IJadxEvents.java @@ -0,0 +1,18 @@ +package jadx.api.plugins.events; + +import java.util.function.Consumer; + +public interface IJadxEvents { + + /** + * Send an event object. + * For public event types check {@link JadxEvents} class. + */ + void send(IJadxEvent event); + + /** + * Register listener for specific event. + * For public event types check {@link JadxEvents} class. + */ + void addListener(JadxEventType eventType, Consumer listener); +} diff --git a/jadx-core/src/main/java/jadx/api/plugins/events/JadxEventType.java b/jadx-core/src/main/java/jadx/api/plugins/events/JadxEventType.java new file mode 100644 index 000000000..98be11ca0 --- /dev/null +++ b/jadx-core/src/main/java/jadx/api/plugins/events/JadxEventType.java @@ -0,0 +1,9 @@ +package jadx.api.plugins.events; + +public abstract class JadxEventType { + + public static JadxEventType create() { + return new JadxEventType<>() { + }; + } +} diff --git a/jadx-core/src/main/java/jadx/api/plugins/events/JadxEvents.java b/jadx-core/src/main/java/jadx/api/plugins/events/JadxEvents.java new file mode 100644 index 000000000..53196501d --- /dev/null +++ b/jadx-core/src/main/java/jadx/api/plugins/events/JadxEvents.java @@ -0,0 +1,16 @@ +package jadx.api.plugins.events; + +import jadx.api.plugins.events.types.NodeRenamedByUser; + +import static jadx.api.plugins.events.JadxEventType.create; + +/** + * Typed and extendable enumeration of event types + */ +public class JadxEvents { + + /** + * Notify about renames done by user (GUI only). + */ + public static final JadxEventType NODE_RENAMED_BY_USER = create(); +} diff --git a/jadx-core/src/main/java/jadx/api/plugins/events/types/NodeRenamedByUser.java b/jadx-core/src/main/java/jadx/api/plugins/events/types/NodeRenamedByUser.java new file mode 100644 index 000000000..7580c30ae --- /dev/null +++ b/jadx-core/src/main/java/jadx/api/plugins/events/types/NodeRenamedByUser.java @@ -0,0 +1,41 @@ +package jadx.api.plugins.events.types; + +import jadx.api.metadata.ICodeNodeRef; +import jadx.api.plugins.events.IJadxEvent; +import jadx.api.plugins.events.JadxEventType; +import jadx.api.plugins.events.JadxEvents; + +public class NodeRenamedByUser implements IJadxEvent { + + private final ICodeNodeRef node; + private final String oldName; + private final String newName; + + public NodeRenamedByUser(ICodeNodeRef node, String oldName, String newName) { + this.node = node; + this.oldName = oldName; + this.newName = newName; + } + + public ICodeNodeRef getNode() { + return node; + } + + public String getOldName() { + return oldName; + } + + public String getNewName() { + return newName; + } + + @Override + public JadxEventType getType() { + return JadxEvents.NODE_RENAMED_BY_USER; + } + + @Override + public String toString() { + return "NodeRenamedByUser{" + node + ", '" + oldName + "' -> '" + newName + "'}"; + } +} diff --git a/jadx-core/src/main/java/jadx/core/Consts.java b/jadx-core/src/main/java/jadx/core/Consts.java index 4e46f0cc5..32b98286c 100644 --- a/jadx-core/src/main/java/jadx/core/Consts.java +++ b/jadx-core/src/main/java/jadx/core/Consts.java @@ -9,6 +9,7 @@ public class Consts { public static final boolean DEBUG_EXC_HANDLERS = false; public static final boolean DEBUG_FINALLY = false; public static final boolean DEBUG_ATTRIBUTES = false; + public static final boolean DEBUG_EVENTS = true; public static final String CLASS_OBJECT = "java.lang.Object"; public static final String CLASS_STRING = "java.lang.String"; diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/PackageNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/PackageNode.java index 1756b5939..66c70744e 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/PackageNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/PackageNode.java @@ -8,11 +8,14 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import jadx.api.JavaPackage; +import jadx.api.metadata.ICodeNodeRef; +import jadx.core.dex.attributes.nodes.LineAttrNode; import jadx.core.dex.info.PackageInfo; import static jadx.core.utils.StringUtils.containsChar; -public class PackageNode implements IPackageUpdate, IDexNode, Comparable { +public class PackageNode extends LineAttrNode + implements IPackageUpdate, IDexNode, ICodeNodeRef, Comparable { private final RootNode root; private final PackageInfo pkgInfo; @@ -194,6 +197,11 @@ public class PackageNode implements IPackageUpdate, IDexNode, Comparable void addListener(JadxEventType eventType, Consumer listener) { + manager.addListener(eventType, listener); + } + + public void reset() { + manager.reset(); + } +} diff --git a/jadx-core/src/main/java/jadx/core/plugins/events/JadxEventsManager.java b/jadx-core/src/main/java/jadx/core/plugins/events/JadxEventsManager.java new file mode 100644 index 000000000..269e5fdbc --- /dev/null +++ b/jadx-core/src/main/java/jadx/core/plugins/events/JadxEventsManager.java @@ -0,0 +1,61 @@ +package jadx.core.plugins.events; + +import java.util.ArrayList; +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; + +import org.jetbrains.annotations.NotNull; + +import jadx.api.plugins.events.IJadxEvent; +import jadx.api.plugins.events.JadxEventType; + +/** + * Handle events sending and receiving + */ +public class JadxEventsManager { + + private final Map, List>> listeners = new IdentityHashMap<>(); + + private final ExecutorService eventsThreadPool; + + public JadxEventsManager() { + // TODO: allow to change threading strategy + this.eventsThreadPool = Executors.newSingleThreadExecutor(makeThreadFactory()); + } + + @SuppressWarnings("unchecked") + public synchronized void addListener(JadxEventType eventType, Consumer listener) { + listeners.computeIfAbsent(eventType, et -> new ArrayList<>()) + .add((Consumer) listener); + } + + public synchronized void send(IJadxEvent event) { + List> consumers = listeners.get(event.getType()); + if (consumers != null) { + for (Consumer consumer : consumers) { + eventsThreadPool.execute(() -> consumer.accept(event)); + } + } + } + + public synchronized void reset() { + listeners.clear(); + } + + private static ThreadFactory makeThreadFactory() { + return new ThreadFactory() { + private final AtomicInteger threadNumber = new AtomicInteger(0); + + @Override + public Thread newThread(@NotNull Runnable r) { + return new Thread(r, "jadx-events-thread-" + threadNumber.incrementAndGet()); + } + }; + } +} diff --git a/jadx-gui/src/main/java/jadx/gui/events/JadxGuiEvents.java b/jadx-gui/src/main/java/jadx/gui/events/JadxGuiEvents.java new file mode 100644 index 000000000..ff6d33051 --- /dev/null +++ b/jadx-gui/src/main/java/jadx/gui/events/JadxGuiEvents.java @@ -0,0 +1,11 @@ +package jadx.gui.events; + +import jadx.api.plugins.events.JadxEventType; +import jadx.gui.events.types.TreeUpdate; + +import static jadx.api.plugins.events.JadxEventType.create; + +public class JadxGuiEvents { + + public static final JadxEventType TREE_UPDATE = create(); +} diff --git a/jadx-gui/src/main/java/jadx/gui/events/types/TreeUpdate.java b/jadx-gui/src/main/java/jadx/gui/events/types/TreeUpdate.java new file mode 100644 index 000000000..febca551f --- /dev/null +++ b/jadx-gui/src/main/java/jadx/gui/events/types/TreeUpdate.java @@ -0,0 +1,24 @@ +package jadx.gui.events.types; + +import jadx.api.plugins.events.IJadxEvent; +import jadx.api.plugins.events.JadxEventType; +import jadx.gui.events.JadxGuiEvents; +import jadx.gui.treemodel.JRoot; + +public class TreeUpdate implements IJadxEvent { + + private final JRoot jRoot; + + public TreeUpdate(JRoot jRoot) { + this.jRoot = jRoot; + } + + public JRoot getJRoot() { + return jRoot; + } + + @Override + public JadxEventType getType() { + return JadxGuiEvents.TREE_UPDATE; + } +} diff --git a/jadx-gui/src/main/java/jadx/gui/treemodel/JRenameNode.java b/jadx-gui/src/main/java/jadx/gui/treemodel/JRenameNode.java index 9e3626a3e..61d46c35c 100644 --- a/jadx-gui/src/main/java/jadx/gui/treemodel/JRenameNode.java +++ b/jadx-gui/src/main/java/jadx/gui/treemodel/JRenameNode.java @@ -11,6 +11,8 @@ import jadx.gui.ui.MainWindow; public interface JRenameNode { + JavaNode getJavaNode(); + String getTitle(); String getName(); diff --git a/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java b/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java index 31e261e0c..030ab3cd7 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java @@ -78,11 +78,14 @@ import org.slf4j.LoggerFactory; import ch.qos.logback.classic.Level; import jadx.api.JadxArgs; +import jadx.api.JadxDecompiler; import jadx.api.JavaNode; import jadx.api.ResourceFile; +import jadx.api.plugins.events.IJadxEvents; import jadx.api.plugins.utils.CommonFileUtils; import jadx.core.Jadx; import jadx.core.export.TemplateFile; +import jadx.core.plugins.events.JadxEventsImpl; import jadx.core.utils.ListUtils; import jadx.core.utils.StringUtils; import jadx.core.utils.exceptions.JadxRuntimeException; @@ -1639,4 +1642,15 @@ public class MainWindow extends JFrame { public RenameMappingsGui getRenameMappings() { return renameMappings; } + + /** + * Events instance if decompiler not yet available + */ + private final IJadxEvents fallbackEvents = new JadxEventsImpl(); + + public IJadxEvents events() { + return wrapper.getCurrentDecompiler() + .map(JadxDecompiler::events) + .orElse(fallbackEvents); + } } diff --git a/jadx-gui/src/main/java/jadx/gui/ui/dialog/RenameDialog.java b/jadx-gui/src/main/java/jadx/gui/ui/dialog/RenameDialog.java index 1ccd39de3..a05a44fd2 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/dialog/RenameDialog.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/dialog/RenameDialog.java @@ -34,6 +34,8 @@ import org.slf4j.LoggerFactory; import jadx.api.JavaNode; import jadx.api.data.ICodeRename; import jadx.api.data.impl.JadxCodeData; +import jadx.api.metadata.ICodeNodeRef; +import jadx.api.plugins.events.types.NodeRenamedByUser; import jadx.core.utils.Utils; import jadx.gui.jobs.TaskStatus; import jadx.gui.settings.JadxProject; @@ -126,13 +128,21 @@ public class RenameDialog extends JDialog { private void processRename(String newName, Set renames) { ICodeRename rename = node.buildCodeRename(newName, renames); renames.remove(rename); + String oldName = node.getName(); if (newName.isEmpty()) { node.removeAlias(); + sendRenameEvent(oldName, node.getJavaNode().getName()); } else { renames.add(rename); + sendRenameEvent(oldName, newName); } } + private void sendRenameEvent(String oldName, String newName) { + ICodeNodeRef nodeRef = node.getJavaNode().getCodeNodeRef(); + mainWindow.events().send(new NodeRenamedByUser(nodeRef, oldName, newName)); + } + private void updateCodeRenames(Consumer> updater) { JadxProject project = mainWindow.getProject(); JadxCodeData codeData = project.getCodeData(); diff --git a/jadx-gui/src/main/java/jadx/gui/utils/pkgs/JRenamePackage.java b/jadx-gui/src/main/java/jadx/gui/utils/pkgs/JRenamePackage.java index ec786c4c5..5bd71a20b 100644 --- a/jadx-gui/src/main/java/jadx/gui/utils/pkgs/JRenamePackage.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/pkgs/JRenamePackage.java @@ -35,6 +35,11 @@ public class JRenamePackage implements JRenameNode { this.name = name; } + @Override + public JavaNode getJavaNode() { + return refPkg; + } + @Override public String getTitle() { return fullName; diff --git a/jadx-plugins/jadx-script/examples/build.gradle.kts b/jadx-plugins/jadx-script/examples/build.gradle.kts index bda87e0f0..a379e42b4 100644 --- a/jadx-plugins/jadx-script/examples/build.gradle.kts +++ b/jadx-plugins/jadx-script/examples/build.gradle.kts @@ -22,6 +22,7 @@ sourceSets { main { kotlin.srcDirs( "scripts", + "scripts/gui", "context" ) } diff --git a/jadx-plugins/jadx-script/examples/scripts/gui_custom_frida.jadx.kts b/jadx-plugins/jadx-script/examples/scripts/gui/custom_frida.jadx.kts similarity index 100% rename from jadx-plugins/jadx-script/examples/scripts/gui_custom_frida.jadx.kts rename to jadx-plugins/jadx-script/examples/scripts/gui/custom_frida.jadx.kts diff --git a/jadx-plugins/jadx-script/examples/scripts/gui/log_events.jadx.kts b/jadx-plugins/jadx-script/examples/scripts/gui/log_events.jadx.kts new file mode 100644 index 000000000..b9ea0f016 --- /dev/null +++ b/jadx-plugins/jadx-script/examples/scripts/gui/log_events.jadx.kts @@ -0,0 +1,11 @@ +import jadx.api.plugins.events.JadxEvents + +/** + * Log events + */ + +val jadx = getJadxInstance() + +jadx.events.addListener(JadxEvents.NODE_RENAMED_BY_USER) { rename -> + log.info { "Rename from '${rename.oldName}' to '${rename.newName}' for node ${rename.node}" } +} diff --git a/jadx-plugins/jadx-script/examples/scripts/gui.jadx.kts b/jadx-plugins/jadx-script/examples/scripts/gui/menu_entry.jadx.kts similarity index 100% rename from jadx-plugins/jadx-script/examples/scripts/gui.jadx.kts rename to jadx-plugins/jadx-script/examples/scripts/gui/menu_entry.jadx.kts diff --git a/jadx-plugins/jadx-script/jadx-script-runtime/src/main/kotlin/jadx/plugins/script/runtime/ScriptRuntime.kt b/jadx-plugins/jadx-script/jadx-script-runtime/src/main/kotlin/jadx/plugins/script/runtime/ScriptRuntime.kt index 51494e17c..502057216 100644 --- a/jadx-plugins/jadx-script/jadx-script-runtime/src/main/kotlin/jadx/plugins/script/runtime/ScriptRuntime.kt +++ b/jadx-plugins/jadx-script/jadx-script-runtime/src/main/kotlin/jadx/plugins/script/runtime/ScriptRuntime.kt @@ -7,6 +7,7 @@ import jadx.api.JadxArgs import jadx.api.JadxDecompiler import jadx.api.JavaClass import jadx.api.plugins.JadxPluginContext +import jadx.api.plugins.events.IJadxEvents import jadx.api.plugins.pass.JadxPass import jadx.plugins.script.runtime.data.Debug import jadx.plugins.script.runtime.data.Decompile @@ -50,6 +51,9 @@ class JadxScriptInstance( val gui: Gui by lazy { Gui(this, scriptData.pluginContext.guiContext) } val debug: Debug by lazy { Debug(this) } + val events: IJadxEvents + get() = scriptData.pluginContext.events() + val args: JadxArgs get() = decompiler.args