Skip to content

Commit 4bf32a9

Browse files
committed
Merge branch 'master' of github.com:ubfx/BinDiffHelper
2 parents 908be03 + 07b98b2 commit 4bf32a9

File tree

6 files changed

+100
-12
lines changed

6 files changed

+100
-12
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
strategy:
2121
fail-fast: false
2222
matrix:
23-
ghidra: ${{ fromJSON(format('[{0}]', inputs.ghidra_version || '"latest","11.2.1","11.2","11.1.2","11.1.1","11.1","11.0.3","11.0.2","11.0.1","11.0"')) }}
23+
ghidra: ${{ fromJSON(format('[{0}]', inputs.ghidra_version || '"latest","11.4.2","11.4.1","11.4","11.3.2","11.3.1","11.3","11.2.1","11.2","11.1.2","11.1.1","11.1","11.0.3","11.0.2","11.0.1","11.0"')) }}
2424

2525
steps:
2626
- name: Clone Repository

src/main/java/bindiffhelper/BinDiffHelperPlugin.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import ghidra.app.plugin.PluginCategoryNames;
3232
import ghidra.app.plugin.ProgramPlugin;
3333
import ghidra.app.services.CodeViewerService;
34+
import ghidra.app.util.Option;
3435
import ghidra.app.util.exporter.Exporter;
3536
import ghidra.framework.model.DomainFile;
3637
import ghidra.framework.plugintool.PluginInfo;
@@ -63,12 +64,14 @@ public class BinDiffHelperPlugin extends ProgramPlugin {
6364
Exporter binExportExporter;
6465
String binDiffBinary;
6566
String diffCommand;
67+
boolean enableNamespace;
6668
protected String defaultBinPath;
6769
protected String defaultDiffCommand;
6870
Program program;
6971

7072
public final static String BDBINPROPERTY = "de.ubfx.bindiffhelper.bindiffbinary";
7173
public final static String DIFFCOMMAND = "de.ubfx.bindiffhelper.diffCommand";
74+
public final static String ENABLENAMESPACE = "de.ubfx.bindiffhelper.enableNamespace";
7275
/**
7376
* Plugin constructor.
7477
*
@@ -113,6 +116,7 @@ public BinDiffHelperPlugin(PluginTool tool) {
113116

114117
binDiffBinary = Preferences.getProperty(BDBINPROPERTY, defaultBinPath);
115118
diffCommand = Preferences.getProperty(DIFFCOMMAND, defaultDiffCommand);
119+
enableNamespace = Boolean.parseBoolean(Preferences.getProperty(ENABLENAMESPACE, "false"));
116120

117121
provider = new BinDiffHelperProvider(this, this.getCurrentProgram());
118122
provider.setTitle("BinDiffHelper");
@@ -130,6 +134,14 @@ File binExportDomainFile(DomainFile df)
130134
if (dof instanceof Program)
131135
{
132136
out = File.createTempFile(df.getName() + "_bdh", ".BinExport");
137+
138+
if (enableNamespace) {
139+
binExportExporter.setOptions(
140+
List.of(
141+
new Option("Prepend Namespace to Function Names", true)
142+
)
143+
);
144+
}
133145

134146
if (binExportExporter.export(out, dof, null, TaskMonitor.DUMMY) == false)
135147
{
@@ -286,6 +298,12 @@ public boolean updateBinDiffBinary() throws IOException
286298

287299
return true;
288300
}
301+
302+
public void updateEnableNamespace(boolean enable)
303+
{
304+
enableNamespace = enable;
305+
Preferences.setProperty(ENABLENAMESPACE, Boolean.toString(enable));
306+
}
289307

290308
public void updateDiffCommand(String cmd)
291309
{

src/main/java/bindiffhelper/BinDiffHelperProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ protected void doDiffWork() {
313313
Set<Long> secFnSet = secondary.beFile.getFunctionAddressSet();
314314
Set<Long> commonSecFnSet = new TreeSet<Long>();
315315

316-
ctm = new ComparisonTableModel();
316+
ctm = new ComparisonTableModel(plugin.enableNamespace);
317317
try {
318318
Statement stmt = conn.createStatement();
319319

src/main/java/bindiffhelper/ComparisonTableModel.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@ public class ComparisonTableModel extends AbstractTableModel {
1919

2020
private List<Entry> data;
2121

22-
public ComparisonTableModel() {
22+
private boolean showNamespace = false;
23+
24+
public ComparisonTableModel(boolean showNamespace) {
2325
data = new ArrayList<Entry>();
26+
this.showNamespace = showNamespace;
2427
}
2528

2629
public void addEntry(Entry e) {
@@ -54,8 +57,21 @@ public Object getValueAt(int row, int col) {
5457
return "0x" + Long.toHexString(e.primaryAddress.getUnsignedOffset());
5558
return "";
5659
case 2:
57-
if (e.primaryFunctionSymbol != null)
58-
return e.primaryFunctionSymbol.getName();
60+
if (e.primaryFunctionSymbol != null){
61+
if (showNamespace) {
62+
var functionNameComponents = new ArrayList<String>();
63+
var parentNamespace = e.primaryFunctionSymbol.getParentNamespace();
64+
while (parentNamespace != null && !"Global".equals(parentNamespace.getName())) {
65+
functionNameComponents.add(0, parentNamespace.getName());
66+
parentNamespace = parentNamespace.getParentNamespace();
67+
}
68+
// Add the name of the function as the last component.
69+
functionNameComponents.add(e.primaryFunctionSymbol.getName());
70+
return String.join("::", functionNameComponents);
71+
} else {
72+
return e.primaryFunctionSymbol.getName();
73+
}
74+
}
5975
return "No Symbol";
6076
case 3:
6177
if (e.primaryFunctionNameDb != null)

src/main/java/bindiffhelper/ImportFunctionNamesAction.java

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
import docking.action.DockingAction;
99
import docking.action.MenuData;
1010
import docking.action.ToolBarData;
11+
import ghidra.program.model.listing.Program;
12+
import ghidra.program.model.symbol.Namespace;
1113
import ghidra.program.model.symbol.SourceType;
14+
import ghidra.program.model.symbol.SymbolTable;
1215
import ghidra.util.HTMLUtilities;
1316
import ghidra.util.Msg;
1417
import resources.ResourceManager;
@@ -32,6 +35,31 @@ protected boolean shouldImportEntry(ComparisonTableModel.Entry e) {
3235
return false;
3336
}
3437

38+
private Namespace getOrCreateNamespace(Program program, String namespacePath) throws Exception {
39+
40+
SymbolTable symbolTable = program.getSymbolTable();
41+
Namespace currentNamespace = program.getGlobalNamespace();
42+
43+
if (namespacePath == null || namespacePath.isEmpty()) {
44+
return currentNamespace;
45+
}
46+
47+
String[] namespaces = namespacePath.split("::");
48+
for (String namespaceName : namespaces) {
49+
ghidra.program.model.symbol.Namespace nextNamespace = symbolTable.getNamespace(
50+
namespaceName, currentNamespace);
51+
52+
if (nextNamespace == null) {
53+
nextNamespace = symbolTable.createNameSpace(
54+
currentNamespace, namespaceName, SourceType.IMPORTED);
55+
}
56+
57+
currentNamespace = nextNamespace;
58+
}
59+
60+
return currentNamespace;
61+
}
62+
3563
@Override
3664
public void actionPerformed(ActionContext arg0) {
3765
int trans = plugin.program.startTransaction("Rename functions");
@@ -46,7 +74,24 @@ public void actionPerformed(ActionContext arg0) {
4674
Exception exp = null;
4775
try {
4876
transformation = e.primaryFunctionSymbol.getName() + " -> " + e.secondaryFunctionName;
49-
e.primaryFunctionSymbol.setName(e.secondaryFunctionName, SourceType.IMPORTED);
77+
78+
if (e.secondaryFunctionName.contains("::")) {
79+
String[] parts = e.secondaryFunctionName.split("::");
80+
String methodName = parts[parts.length - 1];
81+
82+
StringBuilder namespacePath = new StringBuilder();
83+
for (int i = 0; i < parts.length - 1; i++) {
84+
if (i > 0) namespacePath.append("::");
85+
namespacePath.append(parts[i]);
86+
}
87+
88+
Namespace namespace = getOrCreateNamespace(plugin.program, namespacePath.toString());
89+
90+
e.primaryFunctionSymbol.setNameAndNamespace(methodName, namespace, SourceType.IMPORTED);
91+
} else {
92+
e.primaryFunctionSymbol.setName(e.secondaryFunctionName, SourceType.IMPORTED);
93+
}
94+
5095
e.do_import = false;
5196
} catch (Exception ex) {
5297
exp = ex;

src/main/java/bindiffhelper/SettingsDialog.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,7 @@
33
import java.awt.BorderLayout;
44
import java.io.IOException;
55

6-
import javax.swing.BorderFactory;
7-
import javax.swing.JButton;
8-
import javax.swing.JLabel;
9-
import javax.swing.JPanel;
10-
import javax.swing.JTextField;
6+
import javax.swing.*;
117

128
import docking.DialogComponentProvider;
139
import docking.widgets.filechooser.GhidraFileChooserPanel;
@@ -18,6 +14,7 @@ public class SettingsDialog extends DialogComponentProvider {
1814
protected BinDiffHelperPlugin plugin;
1915
protected GhidraFileChooserPanel fileChooserPanel;
2016
private JTextField customTextField;
17+
private JCheckBox enableNamespaceCheckBox;
2118

2219
public SettingsDialog(BinDiffHelperPlugin plugin) {
2320
super("Settings");
@@ -51,7 +48,18 @@ public SettingsDialog(BinDiffHelperPlugin plugin) {
5148
diffCommandTextField.add(customTextField, BorderLayout.CENTER);
5249

5350
diffCommandPanel.add(diffCommandTextField, BorderLayout.CENTER);
54-
panel.add(diffCommandPanel, BorderLayout.SOUTH);
51+
52+
JPanel namespacePanel = new JPanel(new BorderLayout());
53+
namespacePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
54+
enableNamespaceCheckBox = new JCheckBox("Enable export Namespace");
55+
enableNamespaceCheckBox.setSelected(plugin.enableNamespace);
56+
namespacePanel.add(enableNamespaceCheckBox, BorderLayout.CENTER);
57+
58+
JPanel southContainer = new JPanel();
59+
southContainer.setLayout(new BoxLayout(southContainer, BoxLayout.Y_AXIS));
60+
southContainer.add(diffCommandPanel);
61+
southContainer.add(namespacePanel);
62+
panel.add(southContainer, BorderLayout.SOUTH);
5563

5664
addWorkPanel(panel);
5765

@@ -76,6 +84,7 @@ protected void okCallback() {
7684
}
7785

7886
plugin.updateDiffCommand(customTextField.getText());
87+
plugin.updateEnableNamespace(enableNamespaceCheckBox.isSelected());
7988
plugin.provider.generateWarnings();
8089
}
8190
}

0 commit comments

Comments
 (0)