Skip to content
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

improve smali printer to show bytecode #1126

Merged
merged 2 commits into from
Mar 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,29 @@ protected void getSmali(StringBuilder sb) {
sb.append(this.clsData.getDisassembledCode());
}

public String getSmaliV2() {
StringBuilder sb = new StringBuilder();
getSmaliV2(sb);
sb.append(System.lineSeparator());
Set<ClassNode> allInlinedClasses = new LinkedHashSet<>();
getInnerAndInlinedClassesRecursive(allInlinedClasses);
for (ClassNode innerClass : allInlinedClasses) {
innerClass.getSmaliV2(sb);
sb.append(System.lineSeparator());
}
return sb.toString();
}

private void getSmaliV2(StringBuilder sb) {
if (this.clsData == null) {
sb.append(String.format("###### Class %s is created by jadx", getFullName()));
return;
}
sb.append(String.format("###### Class %s (%s)", getFullName(), getRawName()));
sb.append(System.lineSeparator());
sb.append(this.clsData.getDisassembledCodeV2());
}

public ProcessState getState() {
return state;
}
Expand Down
31 changes: 31 additions & 0 deletions jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public class JadxSettings extends JadxCLIArgs {
private boolean checkForUpdates = false;
private List<Path> recentProjects = new ArrayList<>();
private String fontStr = "";
private String smaliFontStr = "";
private String editorThemePath = "";
private LangLocale langLocale = NLS.defaultLocale();
private boolean autoStartJobs = false;
Expand All @@ -68,6 +69,7 @@ public class JadxSettings extends JadxCLIArgs {
private int srhResourceSkipSize = 1000;
private String srhResourceFileExt = ".xml|.html|.js|.json|.txt";
private boolean keepCommonDialogOpen = false;
private boolean smaliAreaShowBytecode = false;

/**
* UI setting: the width of the tree showing the classes, resources, ...
Expand Down Expand Up @@ -377,6 +379,27 @@ public void setFont(@Nullable Font font) {
}
}

public Font getSmaliFont() {
if (smaliFontStr.isEmpty()) {
return DEFAULT_FONT;
}
try {
return FontUtils.loadByStr(smaliFontStr);
} catch (Exception e) {
LOG.warn("Failed to load font: {} for smali, reset to default", smaliFontStr, e);
setSmaliFont(DEFAULT_FONT);
return DEFAULT_FONT;
}
}

public void setSmaliFont(@Nullable Font font) {
if (font == null) {
this.smaliFontStr = "";
} else {
this.smaliFontStr = FontUtils.convertToStr(font);
}
}

public void setLogLevel(LogHelper.LogLevelEnum level) {
this.logLevel = level;
}
Expand Down Expand Up @@ -430,6 +453,14 @@ public boolean getKeepCommonDialogOpen() {
return keepCommonDialogOpen;
}

public void setSmaliAreaShowBytecode(boolean yes) {
smaliAreaShowBytecode = yes;
}

public boolean getSmaliAreaShowBytecode() {
return smaliAreaShowBytecode;
}

private void upgradeSettings(int fromVersion) {
LOG.debug("upgrade settings from version: {} to {}", fromVersion, CURRENT_SETTINGS_VERSION);
if (fromVersion == 0) {
Expand Down
65 changes: 63 additions & 2 deletions jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
import java.awt.event.ItemEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import java.util.Collection;
import java.util.*;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
Expand Down Expand Up @@ -292,6 +291,7 @@ private SettingsGroup makeProjectGroup() {

private SettingsGroup makeEditorGroup() {
JButton fontBtn = new JButton(NLS.str("preferences.select_font"));
JButton smaliFontBtn = new JButton(NLS.str("preferences.select_smali_font"));

EditorTheme[] editorThemes = EditorTheme.getAllThemes();
JComboBox<EditorTheme> themesCbx = new JComboBox<>(editorThemes);
Expand All @@ -311,6 +311,7 @@ private SettingsGroup makeEditorGroup() {
SettingsGroup group = new SettingsGroup(NLS.str("preferences.editor"));
JLabel fontLabel = group.addRow(getFontLabelStr(), fontBtn);
group.addRow(NLS.str("preferences.theme"), themesCbx);
JLabel smaliFontLabel = group.addRow(getSmaliFontLabelStr(), smaliFontBtn);

fontBtn.addMouseListener(new MouseAdapter() {
@Override
Expand All @@ -327,6 +328,22 @@ public void mouseClicked(MouseEvent e) {
}
}
});

smaliFontBtn.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
JFontChooser fontChooser = new JPreferredFontChooser();
fontChooser.setSelectedFont(settings.getSmaliFont());
int result = fontChooser.showDialog(JadxSettingsWindow.this);
if (result == JFontChooser.OK_OPTION) {
Font font = fontChooser.getSelectedFont();
LOG.debug("Selected Font: {} for smali", font);
settings.setSmaliFont(font);
mainWindow.loadSettings();
smaliFontLabel.setText(getSmaliFontLabelStr());
}
}
});
return group;
}

Expand All @@ -336,6 +353,12 @@ private String getFontLabelStr() {
return NLS.str("preferences.font") + ": " + font.getFontName() + ' ' + fontStyleName + ' ' + font.getSize();
}

private String getSmaliFontLabelStr() {
Font font = settings.getSmaliFont();
String fontStyleName = FontUtils.convertFontStyleToString(font.getStyle());
return NLS.str("preferences.smali_font") + ": " + font.getFontName() + ' ' + fontStyleName + ' ' + font.getSize();
}

private SettingsGroup makeDecompilationGroup() {
JCheckBox fallback = new JCheckBox();
fallback.setSelected(settings.isFallbackMode());
Expand Down Expand Up @@ -578,4 +601,42 @@ public void end() {
add(Box.createVerticalGlue());
}
}

private static class JPreferredFontChooser extends JFontChooser {
private static final String[] PREFERRED_FONTS = new String[] {
"Monospaced", "Consolas", "Courier", "Courier New",
"Lucida Sans Typewriter", "Lucida Console",
"SimSun", "SimHei",
};

private String[] filteredFonts;

@Override
protected String[] getFontFamilies() {
if (filteredFonts == null) {
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
Set<String> fontSet = new HashSet<>();
Collections.addAll(fontSet, env.getAvailableFontFamilyNames());
ArrayList<String> found = new ArrayList<>(PREFERRED_FONTS.length);
for (String font : PREFERRED_FONTS) {
if (fontSet.contains(font)) {
found.add(font);
}
}
if (found.size() == PREFERRED_FONTS.length) {
filteredFonts = PREFERRED_FONTS;
} else if (found.size() > 0) {
filteredFonts = new String[found.size()];
for (int i = 0; i < found.size(); i++) {
filteredFonts[i] = found.get(i);
}
} else {
// this machine is crazy.
LOG.warn("Can't found any preferred fonts for smali, use all available.");
filteredFonts = env.getAvailableFontFamilyNames();
}
}
return filteredFonts;
}
}
}
4 changes: 4 additions & 0 deletions jadx-gui/src/main/java/jadx/gui/treemodel/JClass.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ public String getSmali() {
return cls.getSmali();
}

public String getSmaliV2() {
return cls.getClassNode().getSmaliV2();
}

@Override
public String getSyntaxName() {
return SyntaxConstants.SYNTAX_STYLE_JAVA;
Expand Down
14 changes: 11 additions & 3 deletions jadx-gui/src/main/java/jadx/gui/ui/codearea/AbstractCodeArea.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,10 @@ public void actionPerformed(ActionEvent e) {
contentPanel.getTabbedPane().getOpenTabs().values().forEach(v -> {
if (v instanceof AbstractCodeContentPanel) {
AbstractCodeArea codeArea = ((AbstractCodeContentPanel) v).getCodeArea();
codeArea.setLineWrap(wrap);
if (codeArea.isVisible()) {
codeArea.repaint();
setCodeAreaLineWrap(codeArea, wrap);
if (v instanceof ClassCodeContentPanel) {
codeArea = ((ClassCodeContentPanel) v).getSmaliCodeArea();
setCodeAreaLineWrap(codeArea, wrap);
}
}
});
Expand Down Expand Up @@ -116,6 +117,13 @@ public void caretUpdate(CaretEvent e) {
});
}

private void setCodeAreaLineWrap(AbstractCodeArea codeArea, boolean wrap) {
codeArea.setLineWrap(wrap);
if (codeArea.isVisible()) {
codeArea.repaint();
}
}

private String highlightCaretWord(String lastText, int pos) {
String text = getWordByPosition(pos);
if (StringUtils.isEmpty(text)) {
Expand Down
Loading