Skip to content

Added new HexViewer #2469

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 12 commits into
base: master
Choose a base branch
from
6 changes: 6 additions & 0 deletions jadx-gui/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ dependencies {
implementation("com.android.tools.build:apksig:8.9.2")
implementation("io.github.skylot:jdwp:2.0.0")

// Library for hex viewing data
val bined = "0.2.1"
implementation("org.exbin.bined:bined-extended:$bined")
implementation("org.exbin.bined:bined-swing:$bined")
implementation("org.exbin.auxiliary:binary_data:$bined")

testImplementation(project.project(":jadx-core").sourceSets.getByName("test").output)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

import jadx.api.metadata.ICodeNodeRef;
import jadx.gui.treemodel.JNode;
import jadx.gui.ui.action.JNodeAction;
import jadx.gui.ui.codearea.CodeArea;
import jadx.gui.ui.codearea.JNodeAction;

public class CodePopupAction {
private final String name;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package jadx.gui.plugins.script;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.util.Collections;
Expand Down Expand Up @@ -237,6 +238,11 @@ public AbstractCodeArea getCodeArea() {
return scriptArea;
}

@Override
public Component getChildrenComponent() {
return getCodeArea();
}

@Override
public void loadSettings() {
applySettings();
Expand Down
108 changes: 108 additions & 0 deletions jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.awt.Font;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.event.ActionEvent;
Expand All @@ -21,6 +22,7 @@
import java.awt.event.WindowEvent;
import java.awt.geom.AffineTransform;
import java.io.File;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
Expand Down Expand Up @@ -64,6 +66,7 @@
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import org.exbin.bined.swing.basic.CodeArea;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
Expand Down Expand Up @@ -128,12 +131,16 @@
import jadx.gui.ui.codearea.theme.EditorThemeManager;
import jadx.gui.ui.dialog.ADBDialog;
import jadx.gui.ui.dialog.AboutDialog;
import jadx.gui.ui.dialog.CharsetDialog;
import jadx.gui.ui.dialog.ExceptionDialog;
import jadx.gui.ui.dialog.GotoAddressDialog;
import jadx.gui.ui.dialog.LogViewerDialog;
import jadx.gui.ui.dialog.SearchDialog;
import jadx.gui.ui.export.ExportProjectDialog;
import jadx.gui.ui.filedialog.FileDialogWrapper;
import jadx.gui.ui.filedialog.FileOpenMode;
import jadx.gui.ui.hexviewer.HexInspectorPanel;
import jadx.gui.ui.hexviewer.HexPreviewPanel;
import jadx.gui.ui.menu.HiddenMenuItem;
import jadx.gui.ui.menu.JadxMenu;
import jadx.gui.ui.menu.JadxMenuBar;
Expand Down Expand Up @@ -233,6 +240,7 @@ public class MainWindow extends JFrame {
private final ShortcutsController shortcutsController;
private JadxMenuBar menuBar;
private JMenu pluginsMenu;
public JMenu hexViewerMenu;

private final transient RenameMappingsGui renameMappings;

Expand Down Expand Up @@ -959,6 +967,66 @@ public void textSearch() {
SearchDialog.search(MainWindow.this, SearchDialog.SearchPreset.TEXT);
}

private void sendActionsToHexViewer(ActionModel action) {
HexPreviewPanel hexPreviewPanel = getCurrentHexViewTab();
if (hexPreviewPanel != null) {
HexInspectorPanel inspector = hexPreviewPanel.getInspector();
CodeArea hexEditor = hexPreviewPanel.getEditor();
switch (action) {
case HEX_VIEWER_SHOW_INSPECTOR:
hexPreviewPanel.getInspector().setVisible(!inspector.isVisible());
break;
case HEX_VIEWER_CHANGE_ENCODING:
String result = CharsetDialog.chooseCharset(this, hexEditor.getCharset().name());
if (!StringUtils.isEmpty(result)) {
hexEditor.setCharset(Charset.forName(result));
}
break;
case HEX_VIEWER_GO_TO_ADDRESS:
new GotoAddressDialog().showSetSelectionDialog(hexEditor, NLS.str("hex_viewer.goto_address"));
break;
case HEX_VIEWER_FIND:
if (hexEditor.hasSelection()) {
// FindReplacePanel.getInstance().useSelectionForFind(hexEditor);
} else {
// FindReplacePanel.getInstance().showDialog(this, hexEditor);
}
break;
case HEX_VIEWER_FIND_NEXT:
// if (!FindReplacePanel.getInstance().findNext(hexEditor)) {
Toolkit.getDefaultToolkit().beep();
// }
break;
case HEX_VIEWER_FIND_PREVIOUS:
// if (!FindReplacePanel.getInstance().findPrevious(hexEditor)) {
Toolkit.getDefaultToolkit().beep();
// }
break;
case HEX_VIEWER_COPY_HEX:
hexPreviewPanel.performCopyAsCode();
break;
case HEX_VIEWER_COPY_TEXT:
hexPreviewPanel.performCopy();
break;
}
}
}

public HexPreviewPanel getCurrentHexViewTab() {
ContentPanel panel = tabbedPane.getSelectedContentPanel();
if (panel instanceof AbstractCodeContentPanel) {
Component childrenComponent = ((AbstractCodeContentPanel) panel).getChildrenComponent();
if (childrenComponent instanceof HexPreviewPanel) {
return (HexPreviewPanel) childrenComponent;
}
}
return null;
}

public void toggleHexViewMenu() {
hexViewerMenu.setEnabled(getCurrentHexViewTab() != null);
}

public void goToMainActivity() {
AndroidManifestParser parser = new AndroidManifestParser(
AndroidManifestParser.getAndroidManifest(getWrapper().getResources()),
Expand Down Expand Up @@ -1055,6 +1123,9 @@ private void initMenuAndToolbar() {
JMenu recentProjects = new JadxMenu(NLS.str("menu.recent_projects"), shortcutsController);
recentProjects.addMenuListener(new RecentProjectsMenuListener(this, recentProjects));

hexViewerMenu = new JadxMenu(NLS.str("menu.hex_viewer"), shortcutsController);
initHexViewMenu();

JadxGuiAction prefsAction = new JadxGuiAction(ActionModel.PREFS, this::openSettings);
JadxGuiAction exitAction = new JadxGuiAction(ActionModel.EXIT, this::closeWindow);

Expand Down Expand Up @@ -1157,6 +1228,7 @@ private void initMenuAndToolbar() {
JMenu view = new JadxMenu(NLS.str("menu.view"), shortcutsController);
view.setMnemonic(KeyEvent.VK_V);
view.add(quickTabsAction.makeCheckBoxMenuItem());
view.add(hexViewerMenu);
view.add(flatPkgMenuItem);
view.addSeparator();
view.add(enablePreviewTabMenuItem);
Expand Down Expand Up @@ -1732,4 +1804,40 @@ public EditorThemeManager getEditorThemeManager() {
public JadxGuiEventsImpl events() {
return events;
}

private void initHexViewMenu() {
hexViewerMenu.setEnabled(false);

JadxGuiAction showInspectorAction = new JadxGuiAction(ActionModel.HEX_VIEWER_SHOW_INSPECTOR,
() -> sendActionsToHexViewer(ActionModel.HEX_VIEWER_SHOW_INSPECTOR));
JCheckBoxMenuItem showInspectorMenuItem = new JCheckBoxMenuItem(showInspectorAction);

JadxGuiAction changeEncoding = new JadxGuiAction(ActionModel.HEX_VIEWER_CHANGE_ENCODING,
() -> sendActionsToHexViewer(ActionModel.HEX_VIEWER_CHANGE_ENCODING));
JadxGuiAction goToAddress = new JadxGuiAction(ActionModel.HEX_VIEWER_GO_TO_ADDRESS,
() -> sendActionsToHexViewer(ActionModel.HEX_VIEWER_GO_TO_ADDRESS));

JadxGuiAction findAction = new JadxGuiAction(ActionModel.HEX_VIEWER_FIND,
() -> sendActionsToHexViewer(ActionModel.HEX_VIEWER_FIND));
JadxGuiAction findNextAction = new JadxGuiAction(ActionModel.HEX_VIEWER_FIND_NEXT,
() -> sendActionsToHexViewer(ActionModel.HEX_VIEWER_FIND_NEXT));
JadxGuiAction findPreviousAction = new JadxGuiAction(ActionModel.HEX_VIEWER_FIND_PREVIOUS,
() -> sendActionsToHexViewer(ActionModel.HEX_VIEWER_FIND_PREVIOUS));

JadxGuiAction copyHexAction = new JadxGuiAction(ActionModel.HEX_VIEWER_COPY_HEX,
() -> sendActionsToHexViewer(ActionModel.HEX_VIEWER_COPY_HEX));
JadxGuiAction copyTextAction = new JadxGuiAction(ActionModel.HEX_VIEWER_COPY_TEXT,
() -> sendActionsToHexViewer(ActionModel.HEX_VIEWER_COPY_TEXT));

hexViewerMenu.add(showInspectorMenuItem);
hexViewerMenu.add(changeEncoding);
hexViewerMenu.add(goToAddress);
hexViewerMenu.addSeparator();
hexViewerMenu.add(findAction);
hexViewerMenu.add(findNextAction);
hexViewerMenu.add(findPreviousAction);
hexViewerMenu.addSeparator();
hexViewerMenu.add(copyHexAction);
hexViewerMenu.add(copyTextAction);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
public enum ActionCategory {
MENU_TOOLBAR("action_category.menu_toolbar"),
CODE_AREA("action_category.code_area"),
PLUGIN_SCRIPT("action_category.plugin_script");
PLUGIN_SCRIPT("action_category.plugin_script"),
HEX_VIEWER_MENU("action_category.hex_viewer");

private final String nameRes;

Expand Down
19 changes: 18 additions & 1 deletion jadx-gui/src/main/java/jadx/gui/ui/action/ActionModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,24 @@ public enum ActionModel {
SCRIPT_SAVE(PLUGIN_SCRIPT, "script.save", "script.save", "ui/menu-saveall",
Shortcut.keyboard(KeyEvent.VK_S, UiUtils.ctrlButton())),
SCRIPT_AUTO_COMPLETE(PLUGIN_SCRIPT, "script.auto_complete", "script.auto_complete", null,
Shortcut.keyboard(KeyEvent.VK_SPACE, UiUtils.ctrlButton()));
Shortcut.keyboard(KeyEvent.VK_SPACE, UiUtils.ctrlButton())),

HEX_VIEWER_SHOW_INSPECTOR(HEX_VIEWER_MENU, "hex_viewer.show_inspector", "hex_viewer.show_inspector",
null, Shortcut.none()),
HEX_VIEWER_CHANGE_ENCODING(HEX_VIEWER_MENU, "hex_viewer.change_encoding", "hex_viewer.change_encoding",
null, Shortcut.none()),
HEX_VIEWER_GO_TO_ADDRESS(HEX_VIEWER_MENU, "hex_viewer.goto_address", "hex_viewer.goto_address",
null, Shortcut.keyboard(KeyEvent.VK_J, UiUtils.ctrlButton())),
HEX_VIEWER_FIND(HEX_VIEWER_MENU, "hex_viewer.find", "hex_viewer.find",
null, Shortcut.keyboard(KeyEvent.VK_F, UiUtils.ctrlButton())),
HEX_VIEWER_FIND_NEXT(HEX_VIEWER_MENU, "hex_viewer.find_next", "hex_viewer.find_next",
null, Shortcut.keyboard(KeyEvent.VK_G, UiUtils.ctrlButton())),
HEX_VIEWER_FIND_PREVIOUS(HEX_VIEWER_MENU, "hex_viewer.find_previous", "hex_viewer.find_previous",
null, Shortcut.keyboard(KeyEvent.VK_G, UiUtils.ctrlButton() | KeyEvent.SHIFT_DOWN_MASK)),
HEX_VIEWER_COPY_HEX(HEX_VIEWER_MENU, "hex_viewer.copy_hex", "hex_viewer.copy_hex",
null, Shortcut.keyboard(KeyEvent.VK_C, UiUtils.ctrlButton())),
HEX_VIEWER_COPY_TEXT(HEX_VIEWER_MENU, "hex_viewer.copy_text", "hex_viewer.copy_hex",
null, Shortcut.keyboard(KeyEvent.VK_C, UiUtils.ctrlButton() | KeyEvent.SHIFT_DOWN_MASK));

private final ActionCategory category;
private final String nameRes;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package jadx.gui.ui.codearea;
package jadx.gui.ui.action;

import jadx.gui.ui.action.ActionModel;
import jadx.gui.ui.action.JadxGuiAction;
import jadx.gui.ui.codearea.CodeArea;

public class CodeAreaAction extends JadxGuiAction {
protected transient CodeArea codeArea;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package jadx.gui.ui.codearea;
package jadx.gui.ui.action;

import java.awt.event.ActionEvent;

import jadx.gui.ui.action.ActionModel;
import jadx.gui.ui.codearea.CodeArea;
import jadx.gui.ui.dialog.SearchDialog;

public class CommentSearchAction extends CodeAreaAction {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package jadx.gui.ui.codearea;
package jadx.gui.ui.action;

import jadx.gui.treemodel.JNode;
import jadx.gui.ui.action.ActionModel;
import jadx.gui.ui.codearea.CodeArea;
import jadx.gui.ui.dialog.UsageDialog;

public final class FindUsageAction extends JNodeAction {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package jadx.gui.ui.codearea;
package jadx.gui.ui.action;

import java.util.List;
import java.util.Objects;
Expand All @@ -23,7 +23,7 @@
import jadx.gui.treemodel.JField;
import jadx.gui.treemodel.JMethod;
import jadx.gui.treemodel.JNode;
import jadx.gui.ui.action.ActionModel;
import jadx.gui.ui.codearea.CodeArea;
import jadx.gui.utils.NLS;
import jadx.gui.utils.UiUtils;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package jadx.gui.ui.codearea;
package jadx.gui.ui.action;

import jadx.gui.treemodel.JNode;
import jadx.gui.ui.action.ActionModel;
import jadx.gui.ui.codearea.CodeArea;

public final class GoToDeclarationAction extends JNodeAction {
private static final long serialVersionUID = -1186470538894941301L;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package jadx.gui.ui.codearea;
package jadx.gui.ui.action;

import java.awt.event.ActionEvent;
import java.beans.PropertyChangeListener;

import org.jetbrains.annotations.Nullable;

import jadx.gui.treemodel.JNode;
import jadx.gui.ui.action.ActionModel;
import jadx.gui.ui.action.JadxGuiAction;
import jadx.gui.ui.codearea.CodeArea;

/**
* Add menu and key binding actions for JNode in code area
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package jadx.gui.ui.codearea;
package jadx.gui.ui.action;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;

import jadx.core.utils.GsonUtils;
import jadx.gui.treemodel.JNode;
import jadx.gui.ui.action.ActionModel;
import jadx.gui.ui.codearea.CodeArea;

public class JsonPrettifyAction extends JNodeAction {
private static final long serialVersionUID = -2682529369671695550L;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package jadx.gui.ui.codearea;
package jadx.gui.ui.action;

import jadx.gui.treemodel.JNode;
import jadx.gui.treemodel.JRenameNode;
import jadx.gui.ui.action.ActionModel;
import jadx.gui.ui.codearea.CodeArea;
import jadx.gui.ui.dialog.RenameDialog;

public final class RenameAction extends JNodeAction {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package jadx.gui.ui.codearea
package jadx.gui.ui.action

import jadx.core.dex.instructions.args.ArgType
import jadx.core.dex.instructions.args.PrimitiveType
Expand All @@ -8,7 +8,7 @@ import jadx.gui.treemodel.JClass
import jadx.gui.treemodel.JField
import jadx.gui.treemodel.JMethod
import jadx.gui.treemodel.JNode
import jadx.gui.ui.action.ActionModel
import jadx.gui.ui.codearea.CodeArea
import jadx.gui.utils.NLS
import jadx.gui.utils.UiUtils
import org.slf4j.Logger
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import jadx.gui.treemodel.JEditableNode;
import jadx.gui.treemodel.JNode;
import jadx.gui.ui.MainWindow;
import jadx.gui.ui.action.JNodeAction;
import jadx.gui.ui.panel.ContentPanel;
import jadx.gui.utils.DefaultPopupMenuListener;
import jadx.gui.utils.JumpPosition;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package jadx.gui.ui.codearea;

import java.awt.Component;

import jadx.gui.treemodel.JNode;
import jadx.gui.ui.panel.ContentPanel;
import jadx.gui.ui.tab.TabbedPane;
Expand All @@ -15,4 +17,6 @@ protected AbstractCodeContentPanel(TabbedPane panel, JNode jnode) {
}

public abstract AbstractCodeArea getCodeArea();

public abstract Component getChildrenComponent();
}
Loading