From d7aab23c92e2d1266788185d87f43b0db03ec668 Mon Sep 17 00:00:00 2001
From: comex
Date: Sat, 11 May 2019 17:00:37 -0700
Subject: [PATCH 001/140] Call UIManager.getDefaults() instead of
UIManager.getLookAndFeel().getDefaults()
---
.../main/java/docking/menu/DockingCheckboxMenuItemUI.java | 3 +--
.../src/main/java/docking/menu/DockingMenuItemUI.java | 3 +--
.../Docking/src/main/java/docking/menu/DockingMenuUI.java | 3 +--
.../ghidra/docking/util/DockingWindowsLookAndFeelUtils.java | 5 ++---
4 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/Ghidra/Framework/Docking/src/main/java/docking/menu/DockingCheckboxMenuItemUI.java b/Ghidra/Framework/Docking/src/main/java/docking/menu/DockingCheckboxMenuItemUI.java
index 6cfc44548b..bbffa22fda 100644
--- a/Ghidra/Framework/Docking/src/main/java/docking/menu/DockingCheckboxMenuItemUI.java
+++ b/Ghidra/Framework/Docking/src/main/java/docking/menu/DockingCheckboxMenuItemUI.java
@@ -26,9 +26,8 @@ import javax.swing.plaf.MenuItemUI;
public class DockingCheckboxMenuItemUI extends DockingMenuItemUI {
public static ComponentUI createUI(JComponent c) {
- LookAndFeel underlying = UIManager.getLookAndFeel();
DockingCheckboxMenuItemUI result = new DockingCheckboxMenuItemUI();
- result.ui = (MenuItemUI) underlying.getDefaults().getUI(c);
+ result.ui = (MenuItemUI) UIManager.getDefaults().getUI(c);
return result;
}
}
diff --git a/Ghidra/Framework/Docking/src/main/java/docking/menu/DockingMenuItemUI.java b/Ghidra/Framework/Docking/src/main/java/docking/menu/DockingMenuItemUI.java
index 6d6c2042d0..d7ad215f24 100644
--- a/Ghidra/Framework/Docking/src/main/java/docking/menu/DockingMenuItemUI.java
+++ b/Ghidra/Framework/Docking/src/main/java/docking/menu/DockingMenuItemUI.java
@@ -67,9 +67,8 @@ public class DockingMenuItemUI extends MenuItemUI {
protected MenuItemUI ui;
public static ComponentUI createUI(JComponent c) {
- LookAndFeel underlying = UIManager.getLookAndFeel();
DockingMenuItemUI result = new DockingMenuItemUI();
- result.ui = (MenuItemUI) underlying.getDefaults().getUI(c);
+ result.ui = (MenuItemUI) UIManager.getDefaults().getUI(c);
return result;
}
diff --git a/Ghidra/Framework/Docking/src/main/java/docking/menu/DockingMenuUI.java b/Ghidra/Framework/Docking/src/main/java/docking/menu/DockingMenuUI.java
index 8b61ac3cb4..7a6a4589c0 100644
--- a/Ghidra/Framework/Docking/src/main/java/docking/menu/DockingMenuUI.java
+++ b/Ghidra/Framework/Docking/src/main/java/docking/menu/DockingMenuUI.java
@@ -22,9 +22,8 @@ import javax.swing.plaf.MenuItemUI;
public class DockingMenuUI extends DockingMenuItemUI {
public static ComponentUI createUI(JComponent c) {
- LookAndFeel underlying = UIManager.getLookAndFeel();
DockingMenuUI result = new DockingMenuUI();
- result.ui = (MenuItemUI) underlying.getDefaults().getUI(c);
+ result.ui = (MenuItemUI) UIManager.getDefaults().getUI(c);
return result;
}
}
diff --git a/Ghidra/Framework/Docking/src/main/java/ghidra/docking/util/DockingWindowsLookAndFeelUtils.java b/Ghidra/Framework/Docking/src/main/java/ghidra/docking/util/DockingWindowsLookAndFeelUtils.java
index 121a3b0de7..6e7956efe1 100644
--- a/Ghidra/Framework/Docking/src/main/java/ghidra/docking/util/DockingWindowsLookAndFeelUtils.java
+++ b/Ghidra/Framework/Docking/src/main/java/ghidra/docking/util/DockingWindowsLookAndFeelUtils.java
@@ -204,7 +204,7 @@ public class DockingWindowsLookAndFeelUtils {
case NIMBUS_LOOK_AND_FEEL:
// fix scroll bar grabber disappearing. See https://bugs.openjdk.java.net/browse/JDK-8134828
// This fix looks like it should not cause harm even if the bug is fixed on the jdk side.
- UIDefaults defaults = lookAndFeel.getDefaults();
+ UIDefaults defaults = UIManager.getDefaults();
defaults.put("ScrollBar.minimumThumbSize", new Dimension(30, 30));
break;
}
@@ -275,8 +275,7 @@ public class DockingWindowsLookAndFeelUtils {
/** Allows you to globally set the font size (don't use this method!) */
private static void setGlobalFontSizeOverride(int fontSize) {
- LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
- UIDefaults defaults = lookAndFeel.getDefaults();
+ UIDefaults defaults = UIManager.getDefaults();
Set> set = defaults.entrySet();
Iterator> iterator = set.iterator();
From ca1047cd970f3ef09c3aec6dc756fe0a830e7607 Mon Sep 17 00:00:00 2001
From: Nick Fox
Date: Thu, 1 Oct 2020 10:58:55 -0400
Subject: [PATCH 002/140] fix #2283 - 'persistent' spelling error
---
.../formats/gfilesystem/FileSystemService.java | 2 +-
.../java/ghidra/util/state/VarnodeOperation.java | 2 +-
.../Features/Decompiler/ghidra_scripts/GraphAST.java | 2 +-
.../ghidra/program/model/pcode/PcodeFactory.java | 2 +-
.../ghidra/program/model/pcode/PcodeSyntaxTree.java | 4 ++--
.../java/ghidra/program/model/pcode/Varnode.java | 6 +++---
.../java/ghidra/program/model/pcode/VarnodeAST.java | 12 ++++++------
7 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/formats/gfilesystem/FileSystemService.java b/Ghidra/Features/Base/src/main/java/ghidra/formats/gfilesystem/FileSystemService.java
index b2711c6493..1ada2cecae 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/formats/gfilesystem/FileSystemService.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/formats/gfilesystem/FileSystemService.java
@@ -56,7 +56,7 @@ import ghidra.util.timer.GTimer;
*
* Refactor fileInfo -> needs dialog to show properties
* Refactor GFile.getInfo() to return Map<> instead of String.
- * Persistant filesystem - when reopen tool, filesystems should auto-reopen.
+ * Persistent filesystem - when reopen tool, filesystems should auto-reopen.
* Unify GhidraFileChooser with GFileSystem.
* Add "Mounted Filesystems" button to show currently opened GFilesystems?
* Dockable filesystem browser in FrontEnd.
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/util/state/VarnodeOperation.java b/Ghidra/Features/Base/src/main/java/ghidra/util/state/VarnodeOperation.java
index 0d098c9bc1..df53f942cf 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/util/state/VarnodeOperation.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/util/state/VarnodeOperation.java
@@ -170,7 +170,7 @@ public class VarnodeOperation extends Varnode {
}
@Override
- public boolean isPersistant() {
+ public boolean isPersistent() {
return false;
}
diff --git a/Ghidra/Features/Decompiler/ghidra_scripts/GraphAST.java b/Ghidra/Features/Decompiler/ghidra_scripts/GraphAST.java
index f1d5d06ff9..badf03d654 100644
--- a/Ghidra/Features/Decompiler/ghidra_scripts/GraphAST.java
+++ b/Ghidra/Features/Decompiler/ghidra_scripts/GraphAST.java
@@ -128,7 +128,7 @@ public class GraphAST extends GhidraScript {
else if (vn.isUnique()) {
colorattrib = "Black";
}
- else if (vn.isPersistant()) {
+ else if (vn.isPersistent()) {
colorattrib = "DarkOrange";
}
else if (vn.isAddrTied()) {
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/PcodeFactory.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/PcodeFactory.java
index 11e248eec2..da39b07af5 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/PcodeFactory.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/PcodeFactory.java
@@ -61,7 +61,7 @@ public interface PcodeFactory {
public HighSymbol getSymbol(long symbolId);
public Varnode setInput(Varnode vn,boolean val);
public void setAddrTied(Varnode vn,boolean val);
- public void setPersistant(Varnode vn,boolean val);
+ public void setPersistent(Varnode vn, boolean val);
public void setUnaffected(Varnode vn,boolean val);
public void setMergeGroup(Varnode vn,short val);
public void setDataType(Varnode vn,DataType type);
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/PcodeSyntaxTree.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/PcodeSyntaxTree.java
index 48cd3429a6..4e1002e758 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/PcodeSyntaxTree.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/PcodeSyntaxTree.java
@@ -392,9 +392,9 @@ public class PcodeSyntaxTree implements PcodeFactory {
}
@Override
- public void setPersistant(Varnode vn, boolean val) {
+ public void setPersistent(Varnode vn, boolean val) {
VarnodeAST vnast = (VarnodeAST) vn;
- vnast.setPersistant(val);
+ vnast.setPersistent(val);
}
@Override
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/Varnode.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/Varnode.java
index 58a175c7a9..4e6f867f4b 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/Varnode.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/Varnode.java
@@ -255,9 +255,9 @@ public class Varnode {
}
/**
- * @return is persistant
+ * @return is persistent
*/
- public boolean isPersistant() {
+ public boolean isPersistent() {
return false; // Not a valid query with a free varnode
}
@@ -476,7 +476,7 @@ public class Varnode {
}
attrstring = el.getAttribute("persists");
if ((attrstring != null) && (SpecXmlUtils.decodeBoolean(attrstring))) {
- factory.setPersistant(vn, true);
+ factory.setPersistent(vn, true);
}
attrstring = el.getAttribute("addrtied");
if ((attrstring != null) && (SpecXmlUtils.decodeBoolean(attrstring))) {
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/VarnodeAST.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/VarnodeAST.java
index 8a837809e4..a3c3241b6a 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/VarnodeAST.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/pcode/VarnodeAST.java
@@ -37,7 +37,7 @@ public class VarnodeAST extends Varnode {
private boolean bInput;
private boolean bAddrTied;
- private boolean bPersistant;
+ private boolean bPersistent;
private boolean bUnaffected;
private boolean bFree;
private int uniqId; // Unique Id for distinguishing otherwise identical varnodes
@@ -50,7 +50,7 @@ public class VarnodeAST extends Varnode {
super(a, sz);
bInput = false;
bAddrTied = false;
- bPersistant = false;
+ bPersistent = false;
bUnaffected = false;
bFree = true;
uniqId = id;
@@ -70,8 +70,8 @@ public class VarnodeAST extends Varnode {
}
@Override
- public boolean isPersistant() {
- return bPersistant;
+ public boolean isPersistent() {
+ return bPersistent;
}
@Override
@@ -132,8 +132,8 @@ public class VarnodeAST extends Varnode {
def = null;
}
- public void setPersistant(boolean val) {
- bPersistant = val;
+ public void setPersistent(boolean val) {
+ bPersistent = val;
}
public void setUnaffected(boolean val) {
From 6609c53a2ff0326e35b00634ec816fe6e78d21af Mon Sep 17 00:00:00 2001
From: dev747368 <48332326+dev747368@users.noreply.github.com>
Date: Wed, 7 Oct 2020 14:56:58 -0400
Subject: [PATCH 003/140] GP-0 update bug report template with ghidra distro
question
---
.github/ISSUE_TEMPLATE/bug_report.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 385782a424..2882356cb6 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -29,7 +29,8 @@ If applicable, please attach any files that caused problems or log files generat
**Environment (please complete the following information):**
- OS: [e.g. macOS 10.14.2]
- Java Version: [e.g. 11.0]
- - Ghidra Version: [e.g. 9.0]
+ - Ghidra Version: [e.g. 9.1.2]
+ - Ghidra Origin: [e.g. official ghidra-sre.org distro, third party distro, locally built]
**Additional context**
Add any other context about the problem here.
From 865b156b08c42e03edc5e50a41d7ba41108b3870 Mon Sep 17 00:00:00 2001
From: Jeffrey
Date: Thu, 12 Nov 2020 01:21:03 +0100
Subject: [PATCH 004/140] Fixed ARM coproc regs for CRn == c1
---
.../ARM/data/languages/ARMinstructions.sinc | 37 +++++++++++++++----
1 file changed, 29 insertions(+), 8 deletions(-)
diff --git a/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc b/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc
index a755d7895b..86b48c779e 100644
--- a/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc
+++ b/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc
@@ -676,8 +676,9 @@ define pcodeop coproc_moveto_Cache_Type;
define pcodeop coproc_moveto_TCM_Status;
define pcodeop coproc_moveto_TLB_Type;
define pcodeop coproc_moveto_Control;
-define pcodeop coproc_moveto_Auxilary_Control;
+define pcodeop coproc_moveto_Auxiliary_Control;
define pcodeop coproc_moveto_Coprocessor_Access_Control;
+define pcodeop coproc_moveto_Secure_Configuration;
define pcodeop coproc_moveto_Translation_table_base_0;
define pcodeop coproc_moveto_Translation_table_base_1;
define pcodeop coproc_moveto_Translation_table_control;
@@ -726,8 +727,9 @@ define pcodeop coproc_movefrom_Cache_Type;
define pcodeop coproc_movefrom_TCM_Status;
define pcodeop coproc_movefrom_TLB_Type;
define pcodeop coproc_movefrom_Control;
-define pcodeop coproc_movefrom_Auxilary_Control;
+define pcodeop coproc_movefrom_Auxiliary_Control;
define pcodeop coproc_movefrom_Coprocessor_Access_Control;
+define pcodeop coproc_movefrom_Secure_Configuration;
define pcodeop coproc_movefrom_Translation_table_base_0;
define pcodeop coproc_movefrom_Translation_table_base_1;
define pcodeop coproc_movefrom_Translation_table_control;
@@ -2941,16 +2943,16 @@ ArmPCRelImmed12: reloff is U23=0 & immed & rotate
:mcr^COND mcrOperands is
- $(AMODE) & CRm=1 & c0404=1 & opc2=0 & cpn=15 & Rd & CRn=1 & c2020=0 & opc1=0 & c2427=14 & COND &
+ $(AMODE) & CRm=0 & c0404=1 & opc2=1 & cpn=15 & Rd & CRn=1 & c2020=0 & opc1=0 & c2427=14 & COND &
mcrOperands
{
build COND;
- coproc_moveto_Auxilary_Control(Rd);
+ coproc_moveto_Auxiliary_Control(Rd);
}
:mcr^COND mcrOperands is
- $(AMODE) & CRm=2 & c0404=1 & opc2=0 & cpn=15 & Rd & CRn=1 & c2020=0 & opc1=0 & c2427=14 & COND &
+ $(AMODE) & CRm=0 & c0404=1 & opc2=2 & cpn=15 & Rd & CRn=1 & c2020=0 & opc1=0 & c2427=14 & COND &
mcrOperands
{
build COND;
@@ -2958,6 +2960,15 @@ ArmPCRelImmed12: reloff is U23=0 & immed & rotate
}
+:mcr^COND mcrOperands is
+ $(AMODE) & CRm=1 & c0404=1 & opc2=0 & cpn=15 & Rd & CRn=1 & c2020=0 & opc1=0 & c2427=14 & COND &
+ mcrOperands
+{
+ build COND;
+ coproc_moveto_Secure_Configuration(Rd);
+}
+
+
:mcr^COND mcrOperands is
$(AMODE) & CRm=0 & c0404=1 & opc2=0 & cpn=15 & Rd & CRn=2 & c2020=0 & opc1=0 & c2427=14 & COND &
mcrOperands
@@ -3590,17 +3601,17 @@ ArmPCRelImmed12: reloff is U23=0 & immed & rotate
:mrc^COND mcrOperands is
- $(AMODE) & CRm=1 & c0404=1 & opc2=0 & cpn=15 & Rd & CRn=1 & c2020=1 & opc1=0 & c2427=14 & COND &
+ $(AMODE) & CRm=0 & c0404=1 & opc2=1 & cpn=15 & Rd & CRn=1 & c2020=1 & opc1=0 & c2427=14 & COND &
mcrOperands
{
build COND;
- Rd = coproc_movefrom_Auxilary_Control();
+ Rd = coproc_movefrom_Auxiliary_Control();
}
:mrc^COND mcrOperands is
- $(AMODE) & CRm=2 & c0404=1 & opc2=0 & cpn=15 & Rd & CRn=1 & c2020=1 & opc1=0 & c2427=14 & COND &
+ $(AMODE) & CRm=0 & c0404=1 & opc2=2 & cpn=15 & Rd & CRn=1 & c2020=1 & opc1=0 & c2427=14 & COND &
mcrOperands
{
build COND;
@@ -3609,6 +3620,16 @@ ArmPCRelImmed12: reloff is U23=0 & immed & rotate
+:mrc^COND mcrOperands is
+ $(AMODE) & CRm=1 & c0404=1 & opc2=0 & cpn=15 & Rd & CRn=1 & c2020=1 & opc1=0 & c2427=14 & COND &
+ mcrOperands
+{
+ build COND;
+ Rd = coproc_movefrom_Secure_Configuration();
+}
+
+
+
:mrc^COND mcrOperands is
$(AMODE) & CRm=0 & c0404=1 & opc2=0 & cpn=15 & Rd & CRn=2 & c2020=1 & opc1=0 & c2427=14 & COND &
mcrOperands
From 823887cf89786eb19caadfe49ca546fda3073d63 Mon Sep 17 00:00:00 2001
From: Jeffrey
Date: Thu, 12 Nov 2020 01:21:30 +0100
Subject: [PATCH 005/140] Added missing CRn == c1, op1 == 0 coproc registers
---
.../ARM/data/languages/ARMinstructions.sinc | 42 +++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc b/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc
index 86b48c779e..2a4651d775 100644
--- a/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc
+++ b/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc
@@ -679,6 +679,8 @@ define pcodeop coproc_moveto_Control;
define pcodeop coproc_moveto_Auxiliary_Control;
define pcodeop coproc_moveto_Coprocessor_Access_Control;
define pcodeop coproc_moveto_Secure_Configuration;
+define pcodeop coproc_moveto_Secure_Debug_Enable;
+define pcodeop coproc_moveto_Non-Secure_Access_Control;
define pcodeop coproc_moveto_Translation_table_base_0;
define pcodeop coproc_moveto_Translation_table_base_1;
define pcodeop coproc_moveto_Translation_table_control;
@@ -730,6 +732,8 @@ define pcodeop coproc_movefrom_Control;
define pcodeop coproc_movefrom_Auxiliary_Control;
define pcodeop coproc_movefrom_Coprocessor_Access_Control;
define pcodeop coproc_movefrom_Secure_Configuration;
+define pcodeop coproc_movefrom_Secure_Debug_Enable;
+define pcodeop coproc_movefrom_Non-Secure_Access_Control;
define pcodeop coproc_movefrom_Translation_table_base_0;
define pcodeop coproc_movefrom_Translation_table_base_1;
define pcodeop coproc_movefrom_Translation_table_control;
@@ -2969,6 +2973,24 @@ ArmPCRelImmed12: reloff is U23=0 & immed & rotate
}
+:mcr^COND mcrOperands is
+ $(AMODE) & CRm=1 & c0404=1 & opc2=1 & cpn=15 & Rd & CRn=1 & c2020=0 & opc1=0 & c2427=14 & COND &
+ mcrOperands
+{
+ build COND;
+ coproc_moveto_Secure_Debug_Enable(Rd);
+}
+
+
+:mcr^COND mcrOperands is
+ $(AMODE) & CRm=1 & c0404=1 & opc2=2 & cpn=15 & Rd & CRn=1 & c2020=0 & opc1=0 & c2427=14 & COND &
+ mcrOperands
+{
+ build COND;
+ coproc_moveto_Non-Secure_Access_Control(Rd);
+}
+
+
:mcr^COND mcrOperands is
$(AMODE) & CRm=0 & c0404=1 & opc2=0 & cpn=15 & Rd & CRn=2 & c2020=0 & opc1=0 & c2427=14 & COND &
mcrOperands
@@ -3630,6 +3652,26 @@ ArmPCRelImmed12: reloff is U23=0 & immed & rotate
+:mrc^COND mcrOperands is
+ $(AMODE) & CRm=1 & c0404=1 & opc2=1 & cpn=15 & Rd & CRn=1 & c2020=1 & opc1=0 & c2427=14 & COND &
+ mcrOperands
+{
+ build COND;
+ Rd = coproc_movefrom_Secure_Debug_Enable();
+}
+
+
+
+:mrc^COND mcrOperands is
+ $(AMODE) & CRm=1 & c0404=1 & opc2=2 & cpn=15 & Rd & CRn=1 & c2020=1 & opc1=0 & c2427=14 & COND &
+ mcrOperands
+{
+ build COND;
+ Rd = coproc_movefrom_Non-Secure_Access_Control();
+}
+
+
+
:mrc^COND mcrOperands is
$(AMODE) & CRm=0 & c0404=1 & opc2=0 & cpn=15 & Rd & CRn=2 & c2020=1 & opc1=0 & c2427=14 & COND &
mcrOperands
From 6b145561d147e583648067247da9a6ced191423b Mon Sep 17 00:00:00 2001
From: Jeffrey
Date: Thu, 12 Nov 2020 01:46:25 +0100
Subject: [PATCH 006/140] Changed Non-Secure to NonSecure, because the dash
breaks the build
---
Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc b/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc
index 2a4651d775..3810576019 100644
--- a/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc
+++ b/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc
@@ -680,7 +680,7 @@ define pcodeop coproc_moveto_Auxiliary_Control;
define pcodeop coproc_moveto_Coprocessor_Access_Control;
define pcodeop coproc_moveto_Secure_Configuration;
define pcodeop coproc_moveto_Secure_Debug_Enable;
-define pcodeop coproc_moveto_Non-Secure_Access_Control;
+define pcodeop coproc_moveto_NonSecure_Access_Control;
define pcodeop coproc_moveto_Translation_table_base_0;
define pcodeop coproc_moveto_Translation_table_base_1;
define pcodeop coproc_moveto_Translation_table_control;
@@ -733,7 +733,7 @@ define pcodeop coproc_movefrom_Auxiliary_Control;
define pcodeop coproc_movefrom_Coprocessor_Access_Control;
define pcodeop coproc_movefrom_Secure_Configuration;
define pcodeop coproc_movefrom_Secure_Debug_Enable;
-define pcodeop coproc_movefrom_Non-Secure_Access_Control;
+define pcodeop coproc_movefrom_NonSecure_Access_Control;
define pcodeop coproc_movefrom_Translation_table_base_0;
define pcodeop coproc_movefrom_Translation_table_base_1;
define pcodeop coproc_movefrom_Translation_table_control;
@@ -2987,7 +2987,7 @@ ArmPCRelImmed12: reloff is U23=0 & immed & rotate
mcrOperands
{
build COND;
- coproc_moveto_Non-Secure_Access_Control(Rd);
+ coproc_moveto_NonSecure_Access_Control(Rd);
}
@@ -3667,7 +3667,7 @@ ArmPCRelImmed12: reloff is U23=0 & immed & rotate
mcrOperands
{
build COND;
- Rd = coproc_movefrom_Non-Secure_Access_Control();
+ Rd = coproc_movefrom_NonSecure_Access_Control();
}
From ad1c5d78196896b990271598725bc26d37024f12 Mon Sep 17 00:00:00 2001
From: Mike Walters
Date: Fri, 15 Jan 2021 19:24:45 +0000
Subject: [PATCH 007/140] 68000: fix SP postincrement/predecrement with byte
operands
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When the address register is the stack pointer and the operand size is
byte, the address is incremented/decremented by two to keep the stack
pointer aligned to a word boundary.
[M68000 Family Programmer’s Reference Manual; 2.2.4 & 2.2.5]
fixes #1709
---
Ghidra/Processors/68000/data/languages/68000.sinc | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/Ghidra/Processors/68000/data/languages/68000.sinc b/Ghidra/Processors/68000/data/languages/68000.sinc
index 773ee2c4c6..0a8a413d71 100644
--- a/Ghidra/Processors/68000/data/languages/68000.sinc
+++ b/Ghidra/Processors/68000/data/languages/68000.sinc
@@ -417,7 +417,9 @@ eaw: "#"^d16 is mode=7 & regan=4; d16 { export *[const]:2 d16; }
eab: regdnb is mode=0 & regdnb { export regdnb; }
eab: reganb is mode=1 & reganb { export reganb; }
eab: (regan) is mode=2 & regan { export *:1 regan; }
+eab: (regan)+ is mode=3 & regan & regan=7 { local tmp = regan; regan = regan + 2; export *:1 tmp; }
eab: (regan)+ is mode=3 & regan { local tmp = regan; regan = regan + 1; export *:1 tmp; }
+eab: -(regan) is mode=4 & regan & regan=7 { regan = regan - 2; export *:1 regan; }
eab: -(regan) is mode=4 & regan { regan = regan - 1; export *:1 regan; }
eab: (d16,regan) is mode=5 & regan; d16 { local tmp = regan + d16; export *:1 tmp; }
eab: (extw) is mode=6 & regan; extw [ pcmode=0; regtfan=regan; ] { build extw; export *:1 extw; }
@@ -488,11 +490,13 @@ e2w: (d32)".l" is savmod2=7 & regsan=1; d32 { export *:2 d32; }
e2w: "#"^d16 is savmod2=7 & regsan=4; d16 { export *[const]:2 d16; }
# size=byte
- # NB- TODO- Manual says that if in predecrement or postincrement mode and the res is the SP, then must inc/dec by 2, not by 1
+ # NB- Manual says that if in predecrement or postincrement mode and the res is the SP, then must inc/dec by 2, not by 1
e2b: regsdnb is savmod2=0 & regsdnb { export regsdnb; }
e2b: regsanb is savmod2=1 & regsanb { export regsanb; }
e2b: (regsan) is savmod2=2 & regsan { export *:1 regsan; }
+e2b: (regsan)+ is savmod2=3 & regsan & regsan=7 { local tmp = regsan; regsan = regsan + 2; export *:1 tmp; }
e2b: (regsan)+ is savmod2=3 & regsan { local tmp = regsan; regsan = regsan + 1; export *:1 tmp; }
+e2b: -(regsan) is savmod2=4 & regsan & regsan=7 { regsan = regsan - 2; export *:1 regsan; }
e2b: -(regsan) is savmod2=4 & regsan { regsan = regsan - 1; export *:1 regsan; }
e2b: (d16,regsan) is savmod2=5 & regsan; d16 { local tmp = regsan + d16; export *:1 tmp; }
e2b: (extw) is savmod2=6; extw [ pcmode=0; eanum=1; ] { build extw; export *:1 extw; }
From 4d03a1f05b195c65e155cee5dd88e1d80f848ad7 Mon Sep 17 00:00:00 2001
From: jmlagor <73651947+jmlagor@users.noreply.github.com>
Date: Wed, 25 Nov 2020 10:45:39 -0500
Subject: [PATCH 008/140] Initial commit of CustomAttrib blob processing
---
.../pe/cli/blobs/CliBlobCustomAttrib.java | 478 ++++++++++++++++++
.../format/pe/cli/streams/CliStreamBlob.java | 11 +-
.../pe/cli/streams/CliStreamMetadata.java | 2 +-
.../cli/tables/CliTableCustomAttribute.java | 69 ++-
4 files changed, 544 insertions(+), 16 deletions(-)
create mode 100644 Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
new file mode 100644
index 0000000000..66230ab4cb
--- /dev/null
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
@@ -0,0 +1,478 @@
+/* ###
+ * IP: GHIDRA
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package ghidra.app.util.bin.format.pe.cli.blobs;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+
+import ghidra.app.util.bin.BinaryReader;
+import ghidra.app.util.bin.format.pe.cli.blobs.CliAbstractSig.CliElementType;
+import ghidra.app.util.bin.format.pe.cli.blobs.CliAbstractSig.CliParam;
+import ghidra.app.util.bin.format.pe.cli.streams.CliStreamMetadata;
+import ghidra.app.util.bin.format.pe.cli.tables.CliTableCustomAttribute.CliCustomAttributeRow;
+import ghidra.app.util.bin.format.pe.cli.tables.CliTableMemberRef.CliMemberRefRow;
+import ghidra.app.util.bin.format.pe.cli.tables.CliTableMethodDef.CliMethodDefRow;
+import ghidra.app.util.bin.format.pe.cli.tables.CliTypeTable;
+import ghidra.app.util.bin.format.pe.cli.tables.indexes.CliIndexCustomAttributeType;
+import ghidra.program.model.data.*;
+import ghidra.util.Msg;
+import ghidra.util.exception.InvalidInputException;
+
+public class CliBlobCustomAttrib extends CliBlob {
+
+ private CliFixedArg[] fixedArgs;
+ private CliNamedArg[] namedArgs;
+ private short numNamed;
+
+ // Fixed constants for validating the structure
+ private final short CLIBLOBCUSTOMATTRIB_PROLOG = 0x0001;
+ private final byte CLIBLOBCUSTOMATTRIB_TYPE_FIELD = 0x53;
+ private final byte CLIBLOBCUSTOMATTRIB_TYPE_PROPERTY = 0x54;
+
+ // SerString processing constants to validate and convert the
+ // length of the string
+ private final int CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_64 = 0x40;
+ private final int CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_128 = 0x80;
+ private final int CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_192 = 0xC0;
+
+ // UTF-8 boundaries that help detect the end of a string where
+ // lengths aren't specified in FixedArg
+ private final int CLIBLOBCUSTOMATTRIB_UTF8_LOW = 0x1F;
+ private final int CLIBLOBCUSTOMATTRIB_UTF8_HIGH = 0x7F;
+
+ private class CliFixedArg {
+ private CliElementType elem;
+ private Object value;
+
+ public CliFixedArg(CliElementType elem, Object value) {
+ this.elem = elem;
+ this.value = value;
+ }
+
+ public CliElementType getElem() {
+ return elem;
+ }
+
+ public Object getValue() {
+ return value;
+ }
+ }
+
+ private class CliNamedArg {
+ private int fieldOrProp;
+ private CliElementType fieldOrPropType;
+ private String fieldOrPropName;
+
+ public CliNamedArg(int fieldOrProp, CliElementType fieldOrPropType,
+ String fieldOrPropName) {
+ this.fieldOrProp = fieldOrProp;
+ this.fieldOrPropType = fieldOrPropType;
+ this.fieldOrPropName = fieldOrPropName;
+ }
+
+ public int getFieldOrProp() {
+ return fieldOrProp;
+ }
+
+ public CliElementType getFieldOrPropType() {
+ return fieldOrPropType;
+ }
+
+ public String getFieldOrPropName() {
+ return fieldOrPropName;
+ }
+ }
+
+ public CliBlobCustomAttrib(CliBlob blob, CliCustomAttributeRow row,
+ CliStreamMetadata metadataStream) throws IOException {
+ super(blob);
+
+ BinaryReader reader = blob.getContentsReader();
+
+ // Validate the blob prolog
+ short prolog = reader.readNextShort();
+ if (prolog != CLIBLOBCUSTOMATTRIB_PROLOG) {
+ Msg.warn(this,
+ getName() + " had unexpected prolog (0x" + Integer.toHexString(prolog) + ")");
+ return;
+ }
+
+ // The location in the blob table for the actual CustomAttrib blob
+ int valueIndex = row.valueIndex;
+
+ // The entry in the MethodRef or MethodDef table that corresponds to the method
+ // This is a CustomAttributeType coded index
+ int typeIndex = row.typeIndex;
+
+ // The entry of the parent table index, also a CustomAttributeType coded index
+ int parentIndex = row.parentIndex;
+
+ // The FixedArg parameters in the CustomAttrib blob are stored concatenated
+ // against each other without delimeters or type indicators, so you have to look
+ // back to the originating method signature to figure out what's what.
+
+ CliParam[] params = null;
+ try {
+ // Get the table type and row for the attribute and depending on the type
+ // get the parameters
+ CliTypeTable tableType = CliIndexCustomAttributeType.getTableName(typeIndex);
+ int tableRow = CliIndexCustomAttributeType.getRowIndex(typeIndex);
+
+ if (tableType == CliTypeTable.MemberRef) {
+ CliMemberRefRow memberRefRow =
+ (CliMemberRefRow) metadataStream.getTable(tableType).getRow(tableRow);
+ CliBlob memberRefBlob =
+ metadataStream.getBlobStream().getBlob(memberRefRow.signatureIndex);
+ CliSigMethodRef methodRefSig = new CliSigMethodRef(memberRefBlob);
+ params = methodRefSig.getParams();
+ }
+ else if (tableType == CliTypeTable.MethodDef) {
+ CliMethodDefRow methodDefRow =
+ (CliMethodDefRow) metadataStream.getTable(tableType).getRow(tableRow);
+ CliBlob methodDefBlob =
+ metadataStream.getBlobStream().getBlob(methodDefRow.sigIndex);
+ CliSigMethodDef methodDefSig = new CliSigMethodDef(methodDefBlob);
+ params = methodDefSig.getParamTypes();
+ }
+ }
+ catch (InvalidInputException e) {
+ Msg.warn(this, "Unable to process the parameters in " + getName());
+ return;
+ }
+
+ // Process zero to multiple FixedArgs
+ if (params != null) {
+ ArrayList processFixedArgs = new ArrayList<>();
+ for (CliParam param : params) {
+ byte elemByte = reader.peekNextByte();
+ if (elemByte == CliElementType.ELEMENT_TYPE_I.id()) {
+ reader.readNextByte();
+
+ // IntPtr followed by a string of the name of the element, the
+ // length of which is not specified and must be read until a
+ // non-printable UTF-8 character is encountered to signal the
+ // end of the name
+
+ StringBuilder sb = new StringBuilder();
+ while ((reader.peekNextByte() > CLIBLOBCUSTOMATTRIB_UTF8_LOW) &&
+ (reader.peekNextByte() < CLIBLOBCUSTOMATTRIB_UTF8_HIGH)) {
+ sb.append((char) reader.readNextByte());
+ }
+
+ processFixedArgs
+ .add(new CliFixedArg(CliElementType.ELEMENT_TYPE_I, sb.toString()));
+ }
+ else {
+ // Process Elem types
+ switch (param.getType().baseTypeCode) {
+ case ELEMENT_TYPE_BOOLEAN:
+ processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
+ reader.readNextByte()));
+ break;
+
+ case ELEMENT_TYPE_CHAR:
+ processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
+ reader.readNextShort()));
+ break;
+
+ case ELEMENT_TYPE_I1:
+ processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
+ reader.readNextByte()));
+ break;
+
+ case ELEMENT_TYPE_U1:
+ processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
+ reader.readNextUnsignedByte()));
+ break;
+
+ case ELEMENT_TYPE_I2:
+ processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
+ reader.readNextShort()));
+ break;
+
+ case ELEMENT_TYPE_U2:
+ processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
+ reader.readNextUnsignedShort()));
+ break;
+
+ case ELEMENT_TYPE_I4:
+ processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
+ reader.readNextInt()));
+ break;
+
+ case ELEMENT_TYPE_U4:
+ processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
+ reader.readNextUnsignedInt()));
+ break;
+
+ case ELEMENT_TYPE_I8:
+ processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
+ reader.readNextLong()));
+ break;
+
+ case ELEMENT_TYPE_U8:
+ processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
+ reader.readNextByteArray(LongLongDataType.dataType.getLength())));
+ break;
+
+ case ELEMENT_TYPE_R4:
+ processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
+ reader.readNextByteArray(Float4DataType.dataType.getLength())));
+ break;
+
+ case ELEMENT_TYPE_R8:
+ processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
+ reader.readNextByteArray(Float8DataType.dataType.getLength())));
+ break;
+
+ case ELEMENT_TYPE_STRING:
+ int length = readSerStringLength(reader);
+ processFixedArgs
+ .add(new CliFixedArg(param.getType().baseTypeCode, new String(
+ reader.readNextByteArray(length), StandardCharsets.UTF_8)));
+ break;
+
+ case ELEMENT_TYPE_VALUETYPE:
+ processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
+ reader.readNextInt()));
+ break;
+
+ default:
+ Msg.info(this,
+ "Found a CustomAttrib with an unprocessed element type: " +
+ param.getRepresentation());
+ }
+ }
+ }
+
+ fixedArgs = new CliFixedArg[processFixedArgs.size()];
+ for (int i = 0; i < fixedArgs.length; i++) {
+ fixedArgs[i] = processFixedArgs.get(i);
+ }
+ }
+
+ // NumNamed
+ numNamed = reader.readNextShort();
+
+ // Process zero to multiple NamedArgs here
+ ArrayList processNamedArgs = new ArrayList<>();
+ for (int i = 0; i < numNamed; i++) {
+ byte fieldOrProp = reader.readNextByte();
+ if ((fieldOrProp != CLIBLOBCUSTOMATTRIB_TYPE_FIELD) &&
+ fieldOrProp != CLIBLOBCUSTOMATTRIB_TYPE_PROPERTY) {
+ Msg.warn(this, "Invalid FieldOrProp value in NamedArg #" + (i + 1) + ": 0x" +
+ Integer.toHexString(fieldOrProp));
+ continue;
+ }
+
+ CliElementType fieldOrPropType = CliElementType.fromInt(reader.readNextByte());
+
+ // Account for the null terminator
+ int nameLen = readSerStringLength(reader) + 1;
+ String fieldOrPropName =
+ new String(reader.readNextByteArray(nameLen), StandardCharsets.UTF_8);
+
+ processNamedArgs.add(new CliNamedArg(fieldOrProp, fieldOrPropType, fieldOrPropName));
+ }
+
+ if (processNamedArgs.size() > 0) {
+ namedArgs = new CliNamedArg[processNamedArgs.size()];
+ for (int i = 0; i < namedArgs.length; i++) {
+ namedArgs[i] = processNamedArgs.get(i);
+ }
+ }
+ }
+
+ @Override
+ public DataType getContentsDataType() {
+ StructureDataType struct = new StructureDataType(new CategoryPath(PATH), getName(), 0);
+ struct.add(WORD, "PROLOG", "Magic (0x0001)");
+
+ // Display the FixedArgs
+ if (fixedArgs != null) {
+ for (int i = 0; i < fixedArgs.length; i++) {
+ switch (fixedArgs[i].elem) {
+ case ELEMENT_TYPE_CHAR:
+ struct.add(UTF16, "FixedArg_" + i, "Elem (" + fixedArgs[i].getElem() + ")");
+ break;
+
+ case ELEMENT_TYPE_I1:
+ case ELEMENT_TYPE_U1:
+ case ELEMENT_TYPE_BOOLEAN:
+ struct.add(BYTE, "FixedArg_" + i, "Elem (" + fixedArgs[i].getElem() + ")");
+ break;
+
+ case ELEMENT_TYPE_I2:
+ case ELEMENT_TYPE_U2:
+ struct.add(WORD, "FixedArg_" + i, "Elem (" + fixedArgs[i].getElem() + ")");
+ break;
+
+ case ELEMENT_TYPE_I4:
+ case ELEMENT_TYPE_U4:
+ case ELEMENT_TYPE_R4:
+ case ELEMENT_TYPE_VALUETYPE:
+ struct.add(DWORD, "FixedArg_" + i, "Elem (" + fixedArgs[i].getElem() + ")");
+ break;
+
+ case ELEMENT_TYPE_I8:
+ case ELEMENT_TYPE_U8:
+ case ELEMENT_TYPE_R8:
+ struct.add(QWORD, "FixedArg_" + i, "Elem (" + fixedArgs[i].getElem() + ")");
+
+ case ELEMENT_TYPE_STRING:
+ String s = (String) fixedArgs[i].value;
+ int l = s.length();
+ if (l < CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_128) {
+ struct.add(BYTE, "PackedLen", "");
+ }
+ else if (l < CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_192) {
+ struct.add(WORD, "PackedLen", "");
+ }
+ else {
+ struct.add(DWORD, "PackedLen", "");
+
+ }
+ struct.add(UTF8, ((String) fixedArgs[i].value).length(), "FixedArg_" + i,
+ "");
+ break;
+
+ case ELEMENT_TYPE_I:
+ struct.add(BYTE, "ELEMENT_TYPE_I", "");
+ struct.add(UTF8, ((String) fixedArgs[i].value).length(), "FixedArg_" + i,
+ "");
+ break;
+
+ default:
+ Msg.warn(this, "Unprocessed FixedArg element type in CustomAttr #" +
+ (i + 1) + ": " + fixedArgs[i].getElem().name());
+ break;
+ }
+ }
+ }
+
+ struct.add(WORD, "NumNamed", "Number of NamedArgs to follow");
+
+ // Display the NamedArgs
+ if (namedArgs != null) {
+ for (int i = 0; i < numNamed; i++) {
+ if (namedArgs[i].getFieldOrProp() == CLIBLOBCUSTOMATTRIB_TYPE_FIELD) {
+ struct.add(BYTE, "FieldOrProp", "FIELD");
+ }
+ else if (namedArgs[i].getFieldOrProp() == CLIBLOBCUSTOMATTRIB_TYPE_PROPERTY) {
+ struct.add(BYTE, "FieldOrProp", "PROPERTY");
+ }
+ else {
+ struct.add(BYTE, "FieldOrProp", "Unknown value");
+ }
+
+ struct.add(BYTE, "FieldOrPropType", namedArgs[i].getFieldOrPropType().name());
+
+ int nameLen = namedArgs[i].getFieldOrPropName().length();
+ if (nameLen < CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_128) {
+ struct.add(BYTE, "PackedLen", "");
+ }
+ else if (nameLen < CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_192) {
+ struct.add(WORD, "PackedLen", "");
+ }
+ else {
+ struct.add(DWORD, "PackedLen", "");
+
+ }
+
+ struct.add(UTF8, nameLen, "FieldOrPropName", "");
+ }
+ }
+
+ return struct;
+ }
+
+ @Override
+ public String getContentsName() {
+ return "CustomAttrib";
+ }
+
+ @Override
+ public String getContentsComment() {
+ return "A CustomAttrib blob stores values of fixed or named parameters supplied when " +
+ "instantiating a custom attribute";
+ }
+
+ @Override
+ public String getRepresentation() {
+ return "Blob (" + getContentsDataType().getDisplayName() + ")";
+ }
+
+ // SerStrings ("serialized strings") have a length field that varies in size
+ // based on the length of the string. This measures and decodes the Byte, Word,
+ // or DWord length field and returns it.
+ private int readSerStringLength(BinaryReader reader) throws IOException {
+ byte[] length;
+ ByteBuffer buf;
+
+ // The first byte is either the size or an indicator that we have more
+ // size bytes ahead. Values contained in more than one bytes are stored
+ // big-endian.
+ byte firstByte = reader.readNextByte();
+
+ if (firstByte < CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_128) {
+ // A size less than 128 indicates this is the only size byte
+ return firstByte;
+ }
+ else if (firstByte < CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_192) {
+ // A value in the first byte in range [128 - 191] indicates the size
+ // is stored as a Word and the value in the highest bit must be unset
+ length = new byte[] { firstByte, reader.readNextByte() };
+
+ // Unset the highest bit if it's set
+ if ((length[1] &
+ CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_128) == CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_128) {
+ length[1] ^= CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_128;
+ }
+
+ // Convert from big-endian
+ buf = ByteBuffer.wrap(length);
+ buf.order(ByteOrder.BIG_ENDIAN);
+ return buf.getShort();
+ }
+ else {
+ // A value in the first byte > 128 indicates the size is stored as
+ // a DWord and the first two bits must be unset
+ length = new byte[4];
+ length[0] = firstByte;
+ length[1] = reader.readNextByte();
+ length[2] = reader.readNextByte();
+ length[3] = reader.readNextByte();
+
+ // Unset what will become the highest two bits if they're set
+ if ((length[3] &
+ CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_128) == CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_128) {
+ length[3] ^= CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_128;
+ }
+ if ((length[3] &
+ CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_64) == CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_64) {
+ length[3] ^= CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_64;
+ }
+
+ // Convert from big-endian
+ buf = ByteBuffer.wrap(length);
+ buf.order(ByteOrder.BIG_ENDIAN);
+ return buf.getInt();
+ }
+ }
+}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/streams/CliStreamBlob.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/streams/CliStreamBlob.java
index 1aa101521d..a5f065511a 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/streams/CliStreamBlob.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/streams/CliStreamBlob.java
@@ -16,11 +16,12 @@
package ghidra.app.util.bin.format.pe.cli.streams;
import java.io.IOException;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import java.util.*;
import ghidra.app.util.bin.BinaryReader;
+import ghidra.app.util.bin.format.pe.PeUtils;
import ghidra.app.util.bin.format.pe.cli.CliStreamHeader;
+import ghidra.app.util.bin.format.pe.cli.blobs.CliAbstractSig.CliCustomAttrib;
import ghidra.app.util.bin.format.pe.cli.blobs.CliBlob;
import ghidra.program.model.address.Address;
import ghidra.program.model.data.*;
@@ -123,15 +124,15 @@ public class CliStreamBlob extends CliAbstractStream {
DataType oldBlobDataType = oldBlobDataComponent.getDataType();
DataType newBlobDataType = updatedBlob.toDataType();
if (oldBlobDataType.getLength() != newBlobDataType.getLength()) {
- Msg.error(this, "Cannot replace existing blob at address " + addr + " with " +
- updatedBlob.getName() + " because they have different sizes.");
+ Msg.error(this, "Cannot replace existing " + updatedBlob.getName() + " at address " + addr + " with " +
+ updatedBlob.getName() + " because they have different sizes (old: " + oldBlobDataType.getLength() + ", new: " + newBlobDataType.getLength() + ").");
return false;
}
// Update the blob
containingStructure.replaceAtOffset(structureOffset, newBlobDataType, updatedBlob.getSize(),
updatedBlob.getName(), updatedBlob.getContentsComment());
-
+
return true;
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/streams/CliStreamMetadata.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/streams/CliStreamMetadata.java
index 65d8faf138..0644f3d572 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/streams/CliStreamMetadata.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/streams/CliStreamMetadata.java
@@ -435,7 +435,7 @@ public class CliStreamMetadata extends CliAbstractStream {
table.markup(program, isBinary, monitor, log, ntHeader);
}
catch (Exception e) {
- Msg.error(this, "Failed to markup " + table);
+ Msg.error(this, "Failed to markup " + table + ": " + e.toString());
}
}
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java
index 4f5bad550f..37387bdcce 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java
@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,22 +18,35 @@ package ghidra.app.util.bin.format.pe.cli.tables;
import java.io.IOException;
import ghidra.app.util.bin.BinaryReader;
+import ghidra.app.util.bin.format.pe.NTHeader;
+import ghidra.app.util.bin.format.pe.cli.blobs.CliBlobCustomAttrib;
+import ghidra.app.util.bin.format.pe.cli.streams.CliAbstractStream;
import ghidra.app.util.bin.format.pe.cli.streams.CliStreamMetadata;
import ghidra.app.util.bin.format.pe.cli.tables.indexes.CliIndexCustomAttributeType;
import ghidra.app.util.bin.format.pe.cli.tables.indexes.CliIndexHasCustomAttribute;
+import ghidra.app.util.importer.MessageLog;
+import ghidra.program.model.address.Address;
import ghidra.program.model.data.CategoryPath;
import ghidra.program.model.data.StructureDataType;
+import ghidra.program.model.listing.BookmarkType;
+import ghidra.program.model.listing.Program;
+import ghidra.program.model.util.CodeUnitInsertionException;
+import ghidra.util.exception.DuplicateNameException;
import ghidra.util.exception.InvalidInputException;
+import ghidra.util.task.TaskMonitor;
/**
- * Describes the CustomAttribute table.
+ * Describes the CustomAttribute table.
*/
public class CliTableCustomAttribute extends CliAbstractTable {
public class CliCustomAttributeRow extends CliAbstractTableRow {
public int parentIndex;
public int typeIndex;
public int valueIndex;
-
+
+ private final byte CLITABLECUSTOMATTRIBUTE_TYPE_METHODDEF = 0x02;
+ private final byte CLITABLECUSTOMATTRIBUTE_TYPE_METHODREF = 0x03;
+
public CliCustomAttributeRow(int parentIndex, int typeIndex, int valueIndex) {
super();
this.parentIndex = parentIndex;
@@ -45,13 +58,17 @@ public class CliTableCustomAttribute extends CliAbstractTable {
public String getRepresentation() {
String parentRep, typeRep;
try {
- parentRep = getRowRepresentationSafe(CliIndexHasCustomAttribute.getTableName(parentIndex), CliIndexHasCustomAttribute.getRowIndex(parentIndex));
+ parentRep =
+ getRowRepresentationSafe(CliIndexHasCustomAttribute.getTableName(parentIndex),
+ CliIndexHasCustomAttribute.getRowIndex(parentIndex));
}
catch (InvalidInputException e) {
parentRep = Integer.toHexString(parentIndex);
}
try {
- typeRep = getRowRepresentationSafe(CliIndexCustomAttributeType.getTableName(parentIndex), CliIndexCustomAttributeType.getRowIndex(parentIndex));
+ typeRep =
+ getRowRepresentationSafe(CliIndexCustomAttributeType.getTableName(parentIndex),
+ CliIndexCustomAttributeType.getRowIndex(parentIndex));
}
catch (InvalidInputException e) {
typeRep = Integer.toHexString(typeIndex);
@@ -59,23 +76,55 @@ public class CliTableCustomAttribute extends CliAbstractTable {
return String.format("Parent %s Type %s Value %x", parentRep, typeRep, valueIndex);
}
}
- public CliTableCustomAttribute(BinaryReader reader, CliStreamMetadata stream, CliTypeTable tableId) throws IOException {
+
+ public CliTableCustomAttribute(BinaryReader reader, CliStreamMetadata stream,
+ CliTypeTable tableId) throws IOException {
super(reader, stream, tableId);
for (int i = 0; i < this.numRows; i++) {
- CliCustomAttributeRow row = new CliCustomAttributeRow(CliIndexHasCustomAttribute.readCodedIndex(reader, stream),
+ CliCustomAttributeRow row = new CliCustomAttributeRow(
+ CliIndexHasCustomAttribute.readCodedIndex(reader, stream),
CliIndexCustomAttributeType.readCodedIndex(reader, stream), readBlobIndex(reader));
rows.add(row);
blobs.add(row.valueIndex);
}
reader.setPointerIndex(this.readerOffset);
}
-
+
@Override
public StructureDataType getRowDataType() {
- StructureDataType rowDt = new StructureDataType(new CategoryPath(PATH), "CustomAttribute Row", 0);
+ StructureDataType rowDt =
+ new StructureDataType(new CategoryPath(PATH), "CustomAttribute Row", 0);
rowDt.add(CliIndexHasCustomAttribute.toDataType(metadataStream), "Parent", null);
rowDt.add(CliIndexCustomAttributeType.toDataType(metadataStream), "Type", null);
rowDt.add(metadataStream.getBlobIndexDataType(), "Value", null);
return rowDt;
}
+
+ @Override
+ public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
+ NTHeader ntHeader)
+ throws DuplicateNameException, CodeUnitInsertionException, IOException {
+ for (CliAbstractTableRow row : rows) {
+ CliCustomAttributeRow customRow = (CliCustomAttributeRow) row;
+ Address addr = CliAbstractStream.getStreamMarkupAddress(program, isBinary, monitor, log,
+ ntHeader, metadataStream.getBlobStream(), customRow.valueIndex);
+
+ // Create CustomAttrib Blob object and bookmark it
+ CliBlobCustomAttrib blob = new CliBlobCustomAttrib(
+ metadataStream.getBlobStream().getBlob(customRow.valueIndex),
+ (CliCustomAttributeRow) row, metadataStream);
+ metadataStream.getBlobStream().updateBlob(blob, addr, program);
+
+ if (tableType != null) {
+ program.getBookmarkManager()
+ .setBookmark(addr, BookmarkType.INFO, "CLI Blob",
+ "CustomAttrib (" + tableType.name() + ")");
+ }
+ else {
+ program.getBookmarkManager()
+ .setBookmark(addr, BookmarkType.INFO, "CLI Blob",
+ "CustomAttrib (undefined)");
+ }
+ }
+ }
}
From efdc2da7f1816ad887bc725bf9d1d0b1b6cb89d0 Mon Sep 17 00:00:00 2001
From: jmlagor <73651947+jmlagor@users.noreply.github.com>
Date: Wed, 25 Nov 2020 11:16:07 -0500
Subject: [PATCH 009/140] Static, not just final, the constants
---
.../format/pe/cli/blobs/CliBlobCustomAttrib.java | 16 ++++++++--------
.../pe/cli/tables/CliTableCustomAttribute.java | 4 ++--
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
index 66230ab4cb..b43fe89b9f 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
@@ -41,20 +41,20 @@ public class CliBlobCustomAttrib extends CliBlob {
private short numNamed;
// Fixed constants for validating the structure
- private final short CLIBLOBCUSTOMATTRIB_PROLOG = 0x0001;
- private final byte CLIBLOBCUSTOMATTRIB_TYPE_FIELD = 0x53;
- private final byte CLIBLOBCUSTOMATTRIB_TYPE_PROPERTY = 0x54;
+ private static final short CLIBLOBCUSTOMATTRIB_PROLOG = 0x0001;
+ private static final byte CLIBLOBCUSTOMATTRIB_TYPE_FIELD = 0x53;
+ private static final byte CLIBLOBCUSTOMATTRIB_TYPE_PROPERTY = 0x54;
// SerString processing constants to validate and convert the
// length of the string
- private final int CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_64 = 0x40;
- private final int CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_128 = 0x80;
- private final int CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_192 = 0xC0;
+ private static final int CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_64 = 0x40;
+ private static final int CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_128 = 0x80;
+ private static final int CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_192 = 0xC0;
// UTF-8 boundaries that help detect the end of a string where
// lengths aren't specified in FixedArg
- private final int CLIBLOBCUSTOMATTRIB_UTF8_LOW = 0x1F;
- private final int CLIBLOBCUSTOMATTRIB_UTF8_HIGH = 0x7F;
+ private static final int CLIBLOBCUSTOMATTRIB_UTF8_LOW = 0x1F;
+ private static final int CLIBLOBCUSTOMATTRIB_UTF8_HIGH = 0x7F;
private class CliFixedArg {
private CliElementType elem;
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java
index 37387bdcce..34a5205564 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java
@@ -44,8 +44,8 @@ public class CliTableCustomAttribute extends CliAbstractTable {
public int typeIndex;
public int valueIndex;
- private final byte CLITABLECUSTOMATTRIBUTE_TYPE_METHODDEF = 0x02;
- private final byte CLITABLECUSTOMATTRIBUTE_TYPE_METHODREF = 0x03;
+ private static final byte CLITABLECUSTOMATTRIBUTE_TYPE_METHODDEF = 0x02;
+ private static final byte CLITABLECUSTOMATTRIBUTE_TYPE_METHODREF = 0x03;
public CliCustomAttributeRow(int parentIndex, int typeIndex, int valueIndex) {
super();
From 366b94329f96ef9c4a94aff5258c7157b47bd44b Mon Sep 17 00:00:00 2001
From: jmlagor <73651947+jmlagor@users.noreply.github.com>
Date: Mon, 30 Nov 2020 12:05:59 -0500
Subject: [PATCH 010/140] Remove the bookmarks for consistency with GP-327
branch
---
.../pe/cli/tables/CliTableCustomAttribute.java | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java
index 34a5205564..08afc94565 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java
@@ -28,7 +28,6 @@ import ghidra.app.util.importer.MessageLog;
import ghidra.program.model.address.Address;
import ghidra.program.model.data.CategoryPath;
import ghidra.program.model.data.StructureDataType;
-import ghidra.program.model.listing.BookmarkType;
import ghidra.program.model.listing.Program;
import ghidra.program.model.util.CodeUnitInsertionException;
import ghidra.util.exception.DuplicateNameException;
@@ -114,17 +113,6 @@ public class CliTableCustomAttribute extends CliAbstractTable {
metadataStream.getBlobStream().getBlob(customRow.valueIndex),
(CliCustomAttributeRow) row, metadataStream);
metadataStream.getBlobStream().updateBlob(blob, addr, program);
-
- if (tableType != null) {
- program.getBookmarkManager()
- .setBookmark(addr, BookmarkType.INFO, "CLI Blob",
- "CustomAttrib (" + tableType.name() + ")");
- }
- else {
- program.getBookmarkManager()
- .setBookmark(addr, BookmarkType.INFO, "CLI Blob",
- "CustomAttrib (undefined)");
- }
}
}
}
From b58e296b7c0b58ad61e64d023eec768b8852ad71 Mon Sep 17 00:00:00 2001
From: jmlagor <73651947+jmlagor@users.noreply.github.com>
Date: Mon, 30 Nov 2020 12:07:53 -0500
Subject: [PATCH 011/140] Comment fix
---
.../util/bin/format/pe/cli/tables/CliTableCustomAttribute.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java
index 08afc94565..0904a1ac5a 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java
@@ -108,7 +108,7 @@ public class CliTableCustomAttribute extends CliAbstractTable {
Address addr = CliAbstractStream.getStreamMarkupAddress(program, isBinary, monitor, log,
ntHeader, metadataStream.getBlobStream(), customRow.valueIndex);
- // Create CustomAttrib Blob object and bookmark it
+ // Create CustomAttrib Blob object
CliBlobCustomAttrib blob = new CliBlobCustomAttrib(
metadataStream.getBlobStream().getBlob(customRow.valueIndex),
(CliCustomAttributeRow) row, metadataStream);
From 45c64c565fd8f4b0f3617d0f36137332cc9a5e32 Mon Sep 17 00:00:00 2001
From: jmlagor <73651947+jmlagor@users.noreply.github.com>
Date: Thu, 3 Dec 2020 08:52:35 -0500
Subject: [PATCH 012/140] Fixes based on review
---
.../pe/cli/blobs/CliBlobCustomAttrib.java | 94 +++++++++----------
.../cli/tables/CliTableCustomAttribute.java | 16 ++--
2 files changed, 53 insertions(+), 57 deletions(-)
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
index b43fe89b9f..3d11780f2c 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
@@ -25,6 +25,7 @@ import ghidra.app.util.bin.BinaryReader;
import ghidra.app.util.bin.format.pe.cli.blobs.CliAbstractSig.CliElementType;
import ghidra.app.util.bin.format.pe.cli.blobs.CliAbstractSig.CliParam;
import ghidra.app.util.bin.format.pe.cli.streams.CliStreamMetadata;
+import ghidra.app.util.bin.format.pe.cli.tables.CliAbstractTableRow;
import ghidra.app.util.bin.format.pe.cli.tables.CliTableCustomAttribute.CliCustomAttributeRow;
import ghidra.app.util.bin.format.pe.cli.tables.CliTableMemberRef.CliMemberRefRow;
import ghidra.app.util.bin.format.pe.cli.tables.CliTableMethodDef.CliMethodDefRow;
@@ -132,19 +133,18 @@ public class CliBlobCustomAttrib extends CliBlob {
// Get the table type and row for the attribute and depending on the type
// get the parameters
CliTypeTable tableType = CliIndexCustomAttributeType.getTableName(typeIndex);
- int tableRow = CliIndexCustomAttributeType.getRowIndex(typeIndex);
+ int tableRowIndex = CliIndexCustomAttributeType.getRowIndex(typeIndex);
+ CliAbstractTableRow tableRow = metadataStream.getTable(tableType).getRow(tableRowIndex);
if (tableType == CliTypeTable.MemberRef) {
- CliMemberRefRow memberRefRow =
- (CliMemberRefRow) metadataStream.getTable(tableType).getRow(tableRow);
+ CliMemberRefRow memberRefRow = (CliMemberRefRow) tableRow;
CliBlob memberRefBlob =
metadataStream.getBlobStream().getBlob(memberRefRow.signatureIndex);
CliSigMethodRef methodRefSig = new CliSigMethodRef(memberRefBlob);
params = methodRefSig.getParams();
}
else if (tableType == CliTypeTable.MethodDef) {
- CliMethodDefRow methodDefRow =
- (CliMethodDefRow) metadataStream.getTable(tableType).getRow(tableRow);
+ CliMethodDefRow methodDefRow = (CliMethodDefRow) tableRow;
CliBlob methodDefBlob =
metadataStream.getBlobStream().getBlob(methodDefRow.sigIndex);
CliSigMethodDef methodDefSig = new CliSigMethodDef(methodDefBlob);
@@ -180,91 +180,83 @@ public class CliBlobCustomAttrib extends CliBlob {
}
else {
// Process Elem types
- switch (param.getType().baseTypeCode) {
+ CliElementType baseTypeCode = param.getType().baseTypeCode;
+ switch (baseTypeCode) {
case ELEMENT_TYPE_BOOLEAN:
- processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
- reader.readNextByte()));
+ addFixedArg(processFixedArgs, baseTypeCode, reader.readNextByte());
break;
case ELEMENT_TYPE_CHAR:
- processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
- reader.readNextShort()));
+ addFixedArg(processFixedArgs, baseTypeCode, reader.readNextShort());
break;
case ELEMENT_TYPE_I1:
- processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
- reader.readNextByte()));
+ addFixedArg(processFixedArgs, baseTypeCode, reader.readNextByte());
break;
case ELEMENT_TYPE_U1:
- processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
- reader.readNextUnsignedByte()));
+ addFixedArg(processFixedArgs, baseTypeCode,
+ reader.readNextUnsignedByte());
break;
case ELEMENT_TYPE_I2:
- processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
- reader.readNextShort()));
+ addFixedArg(processFixedArgs, baseTypeCode, reader.readNextShort());
break;
case ELEMENT_TYPE_U2:
- processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
- reader.readNextUnsignedShort()));
+ addFixedArg(processFixedArgs, baseTypeCode,
+ reader.readNextUnsignedShort());
break;
case ELEMENT_TYPE_I4:
- processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
- reader.readNextInt()));
+ addFixedArg(processFixedArgs, baseTypeCode, reader.readNextInt());
break;
case ELEMENT_TYPE_U4:
- processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
- reader.readNextUnsignedInt()));
+ addFixedArg(processFixedArgs, baseTypeCode,
+ reader.readNextUnsignedInt());
break;
case ELEMENT_TYPE_I8:
+ addFixedArg(processFixedArgs, baseTypeCode, reader.readNextByte());
processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
reader.readNextLong()));
break;
case ELEMENT_TYPE_U8:
- processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
- reader.readNextByteArray(LongLongDataType.dataType.getLength())));
+ addFixedArg(processFixedArgs, baseTypeCode,
+ reader.readNextByteArray(LongLongDataType.dataType.getLength()));
break;
case ELEMENT_TYPE_R4:
- processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
- reader.readNextByteArray(Float4DataType.dataType.getLength())));
+ addFixedArg(processFixedArgs, baseTypeCode,
+ reader.readNextByteArray(Float4DataType.dataType.getLength()));
break;
case ELEMENT_TYPE_R8:
- processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
- reader.readNextByteArray(Float8DataType.dataType.getLength())));
+ addFixedArg(processFixedArgs, baseTypeCode,
+ reader.readNextByteArray(Float8DataType.dataType.getLength()));
break;
case ELEMENT_TYPE_STRING:
int length = readSerStringLength(reader);
- processFixedArgs
- .add(new CliFixedArg(param.getType().baseTypeCode, new String(
- reader.readNextByteArray(length), StandardCharsets.UTF_8)));
+ addFixedArg(processFixedArgs, baseTypeCode, new String(
+ reader.readNextByteArray(length), StandardCharsets.UTF_8));
break;
case ELEMENT_TYPE_VALUETYPE:
- processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
- reader.readNextInt()));
+ addFixedArg(processFixedArgs, baseTypeCode, reader.readNextInt());
break;
default:
Msg.info(this,
- "Found a CustomAttrib with an unprocessed element type: " +
+ "A CustomAttrib with an unprocessed element type was deteceted: " +
param.getRepresentation());
}
}
}
- fixedArgs = new CliFixedArg[processFixedArgs.size()];
- for (int i = 0; i < fixedArgs.length; i++) {
- fixedArgs[i] = processFixedArgs.get(i);
- }
+ fixedArgs = processFixedArgs.toArray(CliFixedArg[]::new);
}
// NumNamed
@@ -291,12 +283,7 @@ public class CliBlobCustomAttrib extends CliBlob {
processNamedArgs.add(new CliNamedArg(fieldOrProp, fieldOrPropType, fieldOrPropName));
}
- if (processNamedArgs.size() > 0) {
- namedArgs = new CliNamedArg[processNamedArgs.size()];
- for (int i = 0; i < namedArgs.length; i++) {
- namedArgs[i] = processNamedArgs.get(i);
- }
- }
+ namedArgs = processNamedArgs.toArray(CliNamedArg[]::new);
}
@Override
@@ -307,7 +294,8 @@ public class CliBlobCustomAttrib extends CliBlob {
// Display the FixedArgs
if (fixedArgs != null) {
for (int i = 0; i < fixedArgs.length; i++) {
- switch (fixedArgs[i].elem) {
+ CliElementType elem = fixedArgs[i].elem;
+ switch (elem) {
case ELEMENT_TYPE_CHAR:
struct.add(UTF16, "FixedArg_" + i, "Elem (" + fixedArgs[i].getElem() + ")");
break;
@@ -370,20 +358,21 @@ public class CliBlobCustomAttrib extends CliBlob {
// Display the NamedArgs
if (namedArgs != null) {
- for (int i = 0; i < numNamed; i++) {
- if (namedArgs[i].getFieldOrProp() == CLIBLOBCUSTOMATTRIB_TYPE_FIELD) {
+ for (CliNamedArg cliNamedArg : namedArgs) {
+ int fieldOrProp = cliNamedArg.getFieldOrProp();
+ if (fieldOrProp == CLIBLOBCUSTOMATTRIB_TYPE_FIELD) {
struct.add(BYTE, "FieldOrProp", "FIELD");
}
- else if (namedArgs[i].getFieldOrProp() == CLIBLOBCUSTOMATTRIB_TYPE_PROPERTY) {
+ else if (fieldOrProp == CLIBLOBCUSTOMATTRIB_TYPE_PROPERTY) {
struct.add(BYTE, "FieldOrProp", "PROPERTY");
}
else {
struct.add(BYTE, "FieldOrProp", "Unknown value");
}
- struct.add(BYTE, "FieldOrPropType", namedArgs[i].getFieldOrPropType().name());
+ struct.add(BYTE, "FieldOrPropType", cliNamedArg.getFieldOrPropType().name());
- int nameLen = namedArgs[i].getFieldOrPropName().length();
+ int nameLen = cliNamedArg.getFieldOrPropName().length();
if (nameLen < CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_128) {
struct.add(BYTE, "PackedLen", "");
}
@@ -475,4 +464,9 @@ public class CliBlobCustomAttrib extends CliBlob {
return buf.getInt();
}
}
+
+ private void addFixedArg(ArrayList fixedArgs, CliElementType baseTypeCode,
+ Object value) {
+ fixedArgs.add(new CliFixedArg(baseTypeCode, value));
+ }
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java
index 0904a1ac5a..cdd7ffba0b 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java
@@ -20,8 +20,7 @@ import java.io.IOException;
import ghidra.app.util.bin.BinaryReader;
import ghidra.app.util.bin.format.pe.NTHeader;
import ghidra.app.util.bin.format.pe.cli.blobs.CliBlobCustomAttrib;
-import ghidra.app.util.bin.format.pe.cli.streams.CliAbstractStream;
-import ghidra.app.util.bin.format.pe.cli.streams.CliStreamMetadata;
+import ghidra.app.util.bin.format.pe.cli.streams.*;
import ghidra.app.util.bin.format.pe.cli.tables.indexes.CliIndexCustomAttributeType;
import ghidra.app.util.bin.format.pe.cli.tables.indexes.CliIndexHasCustomAttribute;
import ghidra.app.util.importer.MessageLog;
@@ -103,16 +102,19 @@ public class CliTableCustomAttribute extends CliAbstractTable {
public void markup(Program program, boolean isBinary, TaskMonitor monitor, MessageLog log,
NTHeader ntHeader)
throws DuplicateNameException, CodeUnitInsertionException, IOException {
+ CliStreamBlob blobStream = metadataStream.getBlobStream();
+
for (CliAbstractTableRow row : rows) {
CliCustomAttributeRow customRow = (CliCustomAttributeRow) row;
+ int valueIndex = customRow.valueIndex;
+
Address addr = CliAbstractStream.getStreamMarkupAddress(program, isBinary, monitor, log,
- ntHeader, metadataStream.getBlobStream(), customRow.valueIndex);
+ ntHeader, blobStream, valueIndex);
// Create CustomAttrib Blob object
- CliBlobCustomAttrib blob = new CliBlobCustomAttrib(
- metadataStream.getBlobStream().getBlob(customRow.valueIndex),
- (CliCustomAttributeRow) row, metadataStream);
- metadataStream.getBlobStream().updateBlob(blob, addr, program);
+ CliBlobCustomAttrib blob =
+ new CliBlobCustomAttrib(blobStream.getBlob(valueIndex), customRow, metadataStream);
+ blobStream.updateBlob(blob, addr, program);
}
}
}
From 8b73ffdea68ad8532fd49ec3ae68408eaf361971 Mon Sep 17 00:00:00 2001
From: jmlagor <73651947+jmlagor@users.noreply.github.com>
Date: Thu, 3 Dec 2020 12:27:23 -0500
Subject: [PATCH 013/140] Finished review comments
---
.../pe/cli/blobs/CliBlobCustomAttrib.java | 260 +++++++++---------
1 file changed, 135 insertions(+), 125 deletions(-)
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
index 3d11780f2c..7f8d5d7a04 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
@@ -157,133 +157,10 @@ public class CliBlobCustomAttrib extends CliBlob {
}
// Process zero to multiple FixedArgs
- if (params != null) {
- ArrayList processFixedArgs = new ArrayList<>();
- for (CliParam param : params) {
- byte elemByte = reader.peekNextByte();
- if (elemByte == CliElementType.ELEMENT_TYPE_I.id()) {
- reader.readNextByte();
-
- // IntPtr followed by a string of the name of the element, the
- // length of which is not specified and must be read until a
- // non-printable UTF-8 character is encountered to signal the
- // end of the name
-
- StringBuilder sb = new StringBuilder();
- while ((reader.peekNextByte() > CLIBLOBCUSTOMATTRIB_UTF8_LOW) &&
- (reader.peekNextByte() < CLIBLOBCUSTOMATTRIB_UTF8_HIGH)) {
- sb.append((char) reader.readNextByte());
- }
-
- processFixedArgs
- .add(new CliFixedArg(CliElementType.ELEMENT_TYPE_I, sb.toString()));
- }
- else {
- // Process Elem types
- CliElementType baseTypeCode = param.getType().baseTypeCode;
- switch (baseTypeCode) {
- case ELEMENT_TYPE_BOOLEAN:
- addFixedArg(processFixedArgs, baseTypeCode, reader.readNextByte());
- break;
-
- case ELEMENT_TYPE_CHAR:
- addFixedArg(processFixedArgs, baseTypeCode, reader.readNextShort());
- break;
-
- case ELEMENT_TYPE_I1:
- addFixedArg(processFixedArgs, baseTypeCode, reader.readNextByte());
- break;
-
- case ELEMENT_TYPE_U1:
- addFixedArg(processFixedArgs, baseTypeCode,
- reader.readNextUnsignedByte());
- break;
-
- case ELEMENT_TYPE_I2:
- addFixedArg(processFixedArgs, baseTypeCode, reader.readNextShort());
- break;
-
- case ELEMENT_TYPE_U2:
- addFixedArg(processFixedArgs, baseTypeCode,
- reader.readNextUnsignedShort());
- break;
-
- case ELEMENT_TYPE_I4:
- addFixedArg(processFixedArgs, baseTypeCode, reader.readNextInt());
- break;
-
- case ELEMENT_TYPE_U4:
- addFixedArg(processFixedArgs, baseTypeCode,
- reader.readNextUnsignedInt());
- break;
-
- case ELEMENT_TYPE_I8:
- addFixedArg(processFixedArgs, baseTypeCode, reader.readNextByte());
- processFixedArgs.add(new CliFixedArg(param.getType().baseTypeCode,
- reader.readNextLong()));
- break;
-
- case ELEMENT_TYPE_U8:
- addFixedArg(processFixedArgs, baseTypeCode,
- reader.readNextByteArray(LongLongDataType.dataType.getLength()));
- break;
-
- case ELEMENT_TYPE_R4:
- addFixedArg(processFixedArgs, baseTypeCode,
- reader.readNextByteArray(Float4DataType.dataType.getLength()));
- break;
-
- case ELEMENT_TYPE_R8:
- addFixedArg(processFixedArgs, baseTypeCode,
- reader.readNextByteArray(Float8DataType.dataType.getLength()));
- break;
-
- case ELEMENT_TYPE_STRING:
- int length = readSerStringLength(reader);
- addFixedArg(processFixedArgs, baseTypeCode, new String(
- reader.readNextByteArray(length), StandardCharsets.UTF_8));
- break;
-
- case ELEMENT_TYPE_VALUETYPE:
- addFixedArg(processFixedArgs, baseTypeCode, reader.readNextInt());
- break;
-
- default:
- Msg.info(this,
- "A CustomAttrib with an unprocessed element type was deteceted: " +
- param.getRepresentation());
- }
- }
- }
-
- fixedArgs = processFixedArgs.toArray(CliFixedArg[]::new);
- }
-
- // NumNamed
- numNamed = reader.readNextShort();
+ fixedArgs = processFixedArgs(reader, params).toArray(CliFixedArg[]::new);
// Process zero to multiple NamedArgs here
- ArrayList processNamedArgs = new ArrayList<>();
- for (int i = 0; i < numNamed; i++) {
- byte fieldOrProp = reader.readNextByte();
- if ((fieldOrProp != CLIBLOBCUSTOMATTRIB_TYPE_FIELD) &&
- fieldOrProp != CLIBLOBCUSTOMATTRIB_TYPE_PROPERTY) {
- Msg.warn(this, "Invalid FieldOrProp value in NamedArg #" + (i + 1) + ": 0x" +
- Integer.toHexString(fieldOrProp));
- continue;
- }
-
- CliElementType fieldOrPropType = CliElementType.fromInt(reader.readNextByte());
-
- // Account for the null terminator
- int nameLen = readSerStringLength(reader) + 1;
- String fieldOrPropName =
- new String(reader.readNextByteArray(nameLen), StandardCharsets.UTF_8);
-
- processNamedArgs.add(new CliNamedArg(fieldOrProp, fieldOrPropType, fieldOrPropName));
- }
-
- namedArgs = processNamedArgs.toArray(CliNamedArg[]::new);
+ namedArgs = processNamedArgs(reader).toArray(CliNamedArg[]::new);
}
@Override
@@ -295,6 +172,7 @@ public class CliBlobCustomAttrib extends CliBlob {
if (fixedArgs != null) {
for (int i = 0; i < fixedArgs.length; i++) {
CliElementType elem = fixedArgs[i].elem;
+
switch (elem) {
case ELEMENT_TYPE_CHAR:
struct.add(UTF16, "FixedArg_" + i, "Elem (" + fixedArgs[i].getElem() + ")");
@@ -465,8 +343,140 @@ public class CliBlobCustomAttrib extends CliBlob {
}
}
+ private ArrayList processFixedArgs(BinaryReader reader, CliParam[] params)
+ throws IOException {
+ ArrayList processFixedArgs = new ArrayList<>();
+ if (params == null) {
+ return processFixedArgs;
+ }
+
+ for (CliParam param : params) {
+ byte elemByte = reader.peekNextByte();
+ if (elemByte == CliElementType.ELEMENT_TYPE_I.id()) {
+ reader.readNextByte();
+
+ // IntPtr followed by a string of the name of the element, the
+ // length of which is not specified and must be read until a
+ // non-printable UTF-8 character is encountered to signal the
+ // end of the name
+
+ StringBuilder sb = new StringBuilder();
+ while ((reader.peekNextByte() > CLIBLOBCUSTOMATTRIB_UTF8_LOW) &&
+ (reader.peekNextByte() < CLIBLOBCUSTOMATTRIB_UTF8_HIGH)) {
+ sb.append((char) reader.readNextByte());
+ }
+
+ processFixedArgs.add(new CliFixedArg(CliElementType.ELEMENT_TYPE_I, sb.toString()));
+ }
+ else {
+ // Process Elem types
+ CliElementType baseTypeCode = param.getType().baseTypeCode;
+ switch (baseTypeCode) {
+ case ELEMENT_TYPE_BOOLEAN:
+ addFixedArg(processFixedArgs, baseTypeCode, reader.readNextByte());
+ break;
+
+ case ELEMENT_TYPE_CHAR:
+ addFixedArg(processFixedArgs, baseTypeCode, reader.readNextShort());
+ break;
+
+ case ELEMENT_TYPE_I1:
+ addFixedArg(processFixedArgs, baseTypeCode, reader.readNextByte());
+ break;
+
+ case ELEMENT_TYPE_U1:
+ addFixedArg(processFixedArgs, baseTypeCode, reader.readNextUnsignedByte());
+ break;
+
+ case ELEMENT_TYPE_I2:
+ addFixedArg(processFixedArgs, baseTypeCode, reader.readNextShort());
+ break;
+
+ case ELEMENT_TYPE_U2:
+ addFixedArg(processFixedArgs, baseTypeCode, reader.readNextUnsignedShort());
+ break;
+
+ case ELEMENT_TYPE_I4:
+ addFixedArg(processFixedArgs, baseTypeCode, reader.readNextInt());
+ break;
+
+ case ELEMENT_TYPE_U4:
+ addFixedArg(processFixedArgs, baseTypeCode, reader.readNextUnsignedInt());
+ break;
+
+ case ELEMENT_TYPE_I8:
+ addFixedArg(processFixedArgs, baseTypeCode, reader.readNextByte());
+ processFixedArgs.add(
+ new CliFixedArg(param.getType().baseTypeCode, reader.readNextLong()));
+ break;
+
+ case ELEMENT_TYPE_U8:
+ addFixedArg(processFixedArgs, baseTypeCode,
+ reader.readNextByteArray(LongLongDataType.dataType.getLength()));
+ break;
+
+ case ELEMENT_TYPE_R4:
+ addFixedArg(processFixedArgs, baseTypeCode,
+ reader.readNextByteArray(Float4DataType.dataType.getLength()));
+ break;
+
+ case ELEMENT_TYPE_R8:
+ addFixedArg(processFixedArgs, baseTypeCode,
+ reader.readNextByteArray(Float8DataType.dataType.getLength()));
+ break;
+
+ case ELEMENT_TYPE_STRING:
+ int length = readSerStringLength(reader);
+ if (length > 0) {
+ addFixedArg(processFixedArgs, baseTypeCode, new String(
+ reader.readNextByteArray(length), StandardCharsets.UTF_8));
+ }
+ break;
+
+ case ELEMENT_TYPE_VALUETYPE:
+ addFixedArg(processFixedArgs, baseTypeCode, reader.readNextInt());
+ break;
+
+ default:
+ Msg.info(this,
+ "A CustomAttrib with an unprocessed element type was deteceted: " +
+ param.getRepresentation());
+ }
+ }
+ }
+
+ return processFixedArgs;
+ }
+
private void addFixedArg(ArrayList fixedArgs, CliElementType baseTypeCode,
Object value) {
fixedArgs.add(new CliFixedArg(baseTypeCode, value));
}
+
+ private ArrayList processNamedArgs(BinaryReader reader) throws IOException {
+ numNamed = reader.readNextShort();
+
+ // Process zero to multiple NamedArgs here
+ ArrayList processNamedArgs = new ArrayList<>();
+ for (int i = 0; i < numNamed; i++) {
+ byte fieldOrProp = reader.readNextByte();
+ if ((fieldOrProp != CLIBLOBCUSTOMATTRIB_TYPE_FIELD) &&
+ fieldOrProp != CLIBLOBCUSTOMATTRIB_TYPE_PROPERTY) {
+ Msg.warn(this, "Invalid FieldOrProp value in NamedArg #" + (i + 1) + ": 0x" +
+ Integer.toHexString(fieldOrProp));
+ continue;
+ }
+
+ CliElementType fieldOrPropType = CliElementType.fromInt(reader.readNextByte());
+
+ // +1 to account for the null terminator
+ int nameLen = readSerStringLength(reader) + 1;
+ String fieldOrPropName =
+ new String(reader.readNextByteArray(nameLen), StandardCharsets.UTF_8);
+
+ processNamedArgs.add(new CliNamedArg(fieldOrProp, fieldOrPropType, fieldOrPropName));
+ }
+
+ return processNamedArgs;
+ }
}
From fd940aa265a24e9c89e6b95cc5f7ed37f858c93e Mon Sep 17 00:00:00 2001
From: jmlagor <73651947+jmlagor@users.noreply.github.com>
Date: Thu, 3 Dec 2020 12:31:20 -0500
Subject: [PATCH 014/140] Remove unused constants
---
.../util/bin/format/pe/cli/tables/CliTableCustomAttribute.java | 3 ---
1 file changed, 3 deletions(-)
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java
index cdd7ffba0b..be591fbfe5 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java
@@ -42,9 +42,6 @@ public class CliTableCustomAttribute extends CliAbstractTable {
public int typeIndex;
public int valueIndex;
- private static final byte CLITABLECUSTOMATTRIBUTE_TYPE_METHODDEF = 0x02;
- private static final byte CLITABLECUSTOMATTRIBUTE_TYPE_METHODREF = 0x03;
-
public CliCustomAttributeRow(int parentIndex, int typeIndex, int valueIndex) {
super();
this.parentIndex = parentIndex;
From 490d2fb507ffa607fea29f1a1eb4210bdd1cd23d Mon Sep 17 00:00:00 2001
From: jmlagor <73651947+jmlagor@users.noreply.github.com>
Date: Tue, 26 Jan 2021 18:46:02 +0000
Subject: [PATCH 015/140] GP-414 fixing signing issues
---
.../pe/cli/blobs/CliBlobCustomAttrib.java | 69 +++++++++++--------
.../format/pe/cli/streams/CliStreamBlob.java | 33 ++++-----
2 files changed, 56 insertions(+), 46 deletions(-)
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
index 7f8d5d7a04..5d621c5f83 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
@@ -52,6 +52,15 @@ public class CliBlobCustomAttrib extends CliBlob {
private static final int CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_128 = 0x80;
private static final int CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_192 = 0xC0;
+ private static final int CLIBLOBCUSTOMATTRIB_STRING_SIZE_ONE = 0x01;
+ private static final int CLIBLOBCUSTOMATTRIB_STRING_SIZE_TWO = 0x02;
+ private static final int CLIBLOBCUSTOMATTRIB_STRING_SIZE_TWO_BITMASK = 0x7F;
+ private static final int CLIBLOBCUSTOMATTRIB_STRING_SIZE_FOUR = 0x03;
+ private static final int CLIBLOBCUSTOMATTRIB_STRING_SIZE_FOUR_BITMASK = 0x3F;
+
+ private static final int CLIBLOBCUSTOMATTRIB_STRING_SIZE_SHIFT = 0x06;
+ private static final int CLIBLOBCUSTOMATTRIB_STRING_SIZE_BITMASK = 0x03;
+
// UTF-8 boundaries that help detect the end of a string where
// lengths aren't specified in FixedArg
private static final int CLIBLOBCUSTOMATTRIB_UTF8_LOW = 0x1F;
@@ -289,7 +298,8 @@ public class CliBlobCustomAttrib extends CliBlob {
// based on the length of the string. This measures and decodes the Byte, Word,
// or DWord length field and returns it.
private int readSerStringLength(BinaryReader reader) throws IOException {
- byte[] length;
+ byte[] lengthBytes;
+ int length = 0;
ByteBuffer buf;
// The first byte is either the size or an indicator that we have more
@@ -297,50 +307,47 @@ public class CliBlobCustomAttrib extends CliBlob {
// big-endian.
byte firstByte = reader.readNextByte();
- if (firstByte < CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_128) {
+ // Shift the highest two bits to the bottom and mask off to detect the
+ // size of the field holding the size of the string (1, 2, or 4 bytes)
+ byte stringSizeIndicator = (byte) (firstByte >> CLIBLOBCUSTOMATTRIB_STRING_SIZE_SHIFT &
+ CLIBLOBCUSTOMATTRIB_STRING_SIZE_BITMASK);
+
+ if (stringSizeIndicator <= CLIBLOBCUSTOMATTRIB_STRING_SIZE_ONE) {
// A size less than 128 indicates this is the only size byte
- return firstByte;
+ length = firstByte;
}
- else if (firstByte < CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_192) {
+ else if (stringSizeIndicator == CLIBLOBCUSTOMATTRIB_STRING_SIZE_TWO) {
// A value in the first byte in range [128 - 191] indicates the size
// is stored as a Word and the value in the highest bit must be unset
- length = new byte[] { firstByte, reader.readNextByte() };
+ lengthBytes = new byte[] { firstByte, reader.readNextByte() };
- // Unset the highest bit if it's set
- if ((length[1] &
- CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_128) == CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_128) {
- length[1] ^= CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_128;
- }
+ // Unset what will become the highest bit if it's set
+ lengthBytes[1] = (byte) (lengthBytes[1] & CLIBLOBCUSTOMATTRIB_STRING_SIZE_TWO_BITMASK);
// Convert from big-endian
- buf = ByteBuffer.wrap(length);
+ buf = ByteBuffer.wrap(lengthBytes);
buf.order(ByteOrder.BIG_ENDIAN);
- return buf.getShort();
+ length = buf.getShort();
}
- else {
+ else if (stringSizeIndicator == CLIBLOBCUSTOMATTRIB_STRING_SIZE_FOUR) {
// A value in the first byte > 128 indicates the size is stored as
// a DWord and the first two bits must be unset
- length = new byte[4];
- length[0] = firstByte;
- length[1] = reader.readNextByte();
- length[2] = reader.readNextByte();
- length[3] = reader.readNextByte();
+ lengthBytes = new byte[Integer.BYTES];
+ lengthBytes[0] = firstByte;
+ lengthBytes[1] = reader.readNextByte();
+ lengthBytes[2] = reader.readNextByte();
+ lengthBytes[3] = reader.readNextByte();
// Unset what will become the highest two bits if they're set
- if ((length[3] &
- CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_128) == CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_128) {
- length[3] ^= CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_128;
- }
- if ((length[3] &
- CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_64) == CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_64) {
- length[3] ^= CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_64;
- }
+ lengthBytes[3] = (byte) (lengthBytes[3] & CLIBLOBCUSTOMATTRIB_STRING_SIZE_FOUR_BITMASK);
// Convert from big-endian
- buf = ByteBuffer.wrap(length);
+ buf = ByteBuffer.wrap(lengthBytes);
buf.order(ByteOrder.BIG_ENDIAN);
- return buf.getInt();
+ length = buf.getInt();
}
+
+ return length;
}
private ArrayList processFixedArgs(BinaryReader reader, CliParam[] params)
@@ -361,8 +368,10 @@ public class CliBlobCustomAttrib extends CliBlob {
// end of the name
StringBuilder sb = new StringBuilder();
- while ((reader.peekNextByte() > CLIBLOBCUSTOMATTRIB_UTF8_LOW) &&
- (reader.peekNextByte() < CLIBLOBCUSTOMATTRIB_UTF8_HIGH)) {
+ while (((reader.peekNextByte() &
+ CLIBLOBCUSTOMATTRIB_UTF8_HIGH) > CLIBLOBCUSTOMATTRIB_UTF8_LOW) &&
+ ((reader.peekNextByte() &
+ CLIBLOBCUSTOMATTRIB_UTF8_HIGH) < CLIBLOBCUSTOMATTRIB_UTF8_HIGH)) {
sb.append((char) reader.readNextByte());
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/streams/CliStreamBlob.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/streams/CliStreamBlob.java
index a5f065511a..d658fa8d1e 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/streams/CliStreamBlob.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/streams/CliStreamBlob.java
@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,12 +16,11 @@
package ghidra.app.util.bin.format.pe.cli.streams;
import java.io.IOException;
-import java.util.*;
+import java.util.LinkedHashMap;
+import java.util.Map;
import ghidra.app.util.bin.BinaryReader;
-import ghidra.app.util.bin.format.pe.PeUtils;
import ghidra.app.util.bin.format.pe.cli.CliStreamHeader;
-import ghidra.app.util.bin.format.pe.cli.blobs.CliAbstractSig.CliCustomAttrib;
import ghidra.app.util.bin.format.pe.cli.blobs.CliBlob;
import ghidra.program.model.address.Address;
import ghidra.program.model.data.*;
@@ -41,7 +40,7 @@ public class CliStreamBlob extends CliAbstractStream {
/**
* Gets the name of this stream.
- *
+ *
* @return The name of this stream.
*/
public static String getName() {
@@ -50,9 +49,9 @@ public class CliStreamBlob extends CliAbstractStream {
/**
* Creates a new Blob stream.
- *
+ *
* @param header The stream header associated with this stream.
- * @param offset The reader offset where this stream starts.
+ * @param offset The reader offset where this stream starts.
* @param rva The relative virtual address where this stream starts.
* @param reader A reader that is used to read the stream.
* @throws IOException if there is a problem reading the stream.
@@ -85,7 +84,7 @@ public class CliStreamBlob extends CliAbstractStream {
/**
* Gets the blob at the given index.
- *
+ *
* @param index The index of the blob to get.
* @return The blob at the given index. Could be null if the index was invalid or
* there was a problem reading the blob.
@@ -96,7 +95,7 @@ public class CliStreamBlob extends CliAbstractStream {
/**
* Updates the blob at the given address with the new blob.
- *
+ *
* @param updatedBlob The updated blob.
* @param addr The address of the blob to update.
* @param program The program that will get the update.
@@ -114,25 +113,28 @@ public class CliStreamBlob extends CliAbstractStream {
// Make sure there is an old blob at the given address
int structureOffset = (int) addr.subtract(containingData.getAddress());
- DataTypeComponent oldBlobDataComponent = containingStructure.getComponentAt(structureOffset);
+ DataTypeComponent oldBlobDataComponent =
+ containingStructure.getComponentAt(structureOffset);
if (oldBlobDataComponent == null) {
Msg.error(this, "Existing blob at address " + addr + " was not found.");
return false;
}
-
+
// Make sure the old blob has the same size as the new blob
DataType oldBlobDataType = oldBlobDataComponent.getDataType();
DataType newBlobDataType = updatedBlob.toDataType();
if (oldBlobDataType.getLength() != newBlobDataType.getLength()) {
- Msg.error(this, "Cannot replace existing " + updatedBlob.getName() + " at address " + addr + " with " +
- updatedBlob.getName() + " because they have different sizes (old: " + oldBlobDataType.getLength() + ", new: " + newBlobDataType.getLength() + ").");
+ Msg.error(this,
+ "Cannot replace existing " + updatedBlob.getName() + " at address " + addr +
+ " with " + updatedBlob.getName() + " because they have different sizes (old: " +
+ oldBlobDataType.getLength() + ", new: " + newBlobDataType.getLength() + ").");
return false;
}
// Update the blob
containingStructure.replaceAtOffset(structureOffset, newBlobDataType, updatedBlob.getSize(),
updatedBlob.getName(), updatedBlob.getContentsComment());
-
+
return true;
}
@@ -149,4 +151,3 @@ public class CliStreamBlob extends CliAbstractStream {
return struct;
}
}
-
From ec19b5cdc3b31a5dad94347a35ea9d0e303fd246 Mon Sep 17 00:00:00 2001
From: jmlagor <73651947+jmlagor@users.noreply.github.com>
Date: Tue, 26 Jan 2021 18:56:28 +0000
Subject: [PATCH 016/140] GP-414 Fixing signing issues
---
.../app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java | 4 ++--
.../app/util/bin/format/pe/cli/streams/CliStreamBlob.java | 4 ++--
.../bin/format/pe/cli/tables/CliTableCustomAttribute.java | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
index 5d621c5f83..ded0ec4a33 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/streams/CliStreamBlob.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/streams/CliStreamBlob.java
index d658fa8d1e..b14ffd1ec8 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/streams/CliStreamBlob.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/streams/CliStreamBlob.java
@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java
index be591fbfe5..6323c15a43 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/tables/CliTableCustomAttribute.java
@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
From 317a8a7f68c4adfe5f0a45e09f869d785be90471 Mon Sep 17 00:00:00 2001
From: jmlagor <73651947+jmlagor@users.noreply.github.com>
Date: Wed, 10 Feb 2021 16:41:23 +0000
Subject: [PATCH 017/140] Changes to simplify length calculation
---
.../pe/cli/blobs/CliBlobCustomAttrib.java | 40 ++++++-------------
1 file changed, 12 insertions(+), 28 deletions(-)
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
index ded0ec4a33..0814299b0f 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -46,20 +46,16 @@ public class CliBlobCustomAttrib extends CliBlob {
private static final byte CLIBLOBCUSTOMATTRIB_TYPE_FIELD = 0x53;
private static final byte CLIBLOBCUSTOMATTRIB_TYPE_PROPERTY = 0x54;
- // SerString processing constants to validate and convert the
- // length of the string
- private static final int CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_64 = 0x40;
private static final int CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_128 = 0x80;
private static final int CLIBLOBCUSTOMATTRIB_STRING_BOUNDARY_192 = 0xC0;
private static final int CLIBLOBCUSTOMATTRIB_STRING_SIZE_ONE = 0x01;
private static final int CLIBLOBCUSTOMATTRIB_STRING_SIZE_TWO = 0x02;
- private static final int CLIBLOBCUSTOMATTRIB_STRING_SIZE_TWO_BITMASK = 0x7F;
private static final int CLIBLOBCUSTOMATTRIB_STRING_SIZE_FOUR = 0x03;
- private static final int CLIBLOBCUSTOMATTRIB_STRING_SIZE_FOUR_BITMASK = 0x3F;
+ private static final int CLIBLOBCUSTOMATTRIB_STRING_SIZE_BITMASK = 0x3F;
- private static final int CLIBLOBCUSTOMATTRIB_STRING_SIZE_SHIFT = 0x06;
- private static final int CLIBLOBCUSTOMATTRIB_STRING_SIZE_BITMASK = 0x03;
+ private static final int CLIBLOBCUSTOMATTRIB_STRING_INDICATOR_SHIFT = 0x06;
+ private static final int CLIBLOBCUSTOMATTRIB_STRING_INDICATOR_BITMASK = 0x03;
// UTF-8 boundaries that help detect the end of a string where
// lengths aren't specified in FixedArg
@@ -308,38 +304,26 @@ public class CliBlobCustomAttrib extends CliBlob {
byte firstByte = reader.readNextByte();
// Shift the highest two bits to the bottom and mask off to detect the
- // size of the field holding the size of the string (1, 2, or 4 bytes)
- byte stringSizeIndicator = (byte) (firstByte >> CLIBLOBCUSTOMATTRIB_STRING_SIZE_SHIFT &
- CLIBLOBCUSTOMATTRIB_STRING_SIZE_BITMASK);
+ // size of the field holding the size of the string (1, 2, or 4 bytes),
+ // then cut the indicator bits off the first byte of the length.
+ byte stringSizeIndicator = (byte) (firstByte >> CLIBLOBCUSTOMATTRIB_STRING_INDICATOR_SHIFT &
+ CLIBLOBCUSTOMATTRIB_STRING_INDICATOR_BITMASK);
+ firstByte = (byte) (firstByte & CLIBLOBCUSTOMATTRIB_STRING_SIZE_BITMASK);
if (stringSizeIndicator <= CLIBLOBCUSTOMATTRIB_STRING_SIZE_ONE) {
- // A size less than 128 indicates this is the only size byte
length = firstByte;
}
else if (stringSizeIndicator == CLIBLOBCUSTOMATTRIB_STRING_SIZE_TWO) {
- // A value in the first byte in range [128 - 191] indicates the size
- // is stored as a Word and the value in the highest bit must be unset
lengthBytes = new byte[] { firstByte, reader.readNextByte() };
- // Unset what will become the highest bit if it's set
- lengthBytes[1] = (byte) (lengthBytes[1] & CLIBLOBCUSTOMATTRIB_STRING_SIZE_TWO_BITMASK);
-
// Convert from big-endian
buf = ByteBuffer.wrap(lengthBytes);
buf.order(ByteOrder.BIG_ENDIAN);
length = buf.getShort();
}
else if (stringSizeIndicator == CLIBLOBCUSTOMATTRIB_STRING_SIZE_FOUR) {
- // A value in the first byte > 128 indicates the size is stored as
- // a DWord and the first two bits must be unset
- lengthBytes = new byte[Integer.BYTES];
- lengthBytes[0] = firstByte;
- lengthBytes[1] = reader.readNextByte();
- lengthBytes[2] = reader.readNextByte();
- lengthBytes[3] = reader.readNextByte();
-
- // Unset what will become the highest two bits if they're set
- lengthBytes[3] = (byte) (lengthBytes[3] & CLIBLOBCUSTOMATTRIB_STRING_SIZE_FOUR_BITMASK);
+ lengthBytes = new byte[] { firstByte, reader.readNextByte(), reader.readNextByte(),
+ reader.readNextByte() };
// Convert from big-endian
buf = ByteBuffer.wrap(lengthBytes);
From 6d97ccee649c39caad258e6e2a7b16ed6780d2bb Mon Sep 17 00:00:00 2001
From: Hyunjin Song
Date: Fri, 12 Feb 2021 13:50:37 +0900
Subject: [PATCH 018/140] Fix ARM Neon VMRS instruction for little endian
---
Ghidra/Processors/ARM/data/languages/ARMneon.sinc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Ghidra/Processors/ARM/data/languages/ARMneon.sinc b/Ghidra/Processors/ARM/data/languages/ARMneon.sinc
index 5c2470ae85..aff8f018f7 100644
--- a/Ghidra/Processors/ARM/data/languages/ARMneon.sinc
+++ b/Ghidra/Processors/ARM/data/languages/ARMneon.sinc
@@ -3049,7 +3049,7 @@ define pcodeop VectorCopyNarrow;
@if defined(VFPv2) || defined(VFPv3) || defined(SIMD)
-:vmrs^COND VRd,fpscr is COND & ( ($(AMODE) & c1627=0xef1 & c0011=0xa10) | ($(TMODE_E) & c1627=0xef1 & c0011=0xa10)) & fpscr & VRd
+:vmrs^COND VRd,fpscr is COND & ( ($(AMODE) & c1627=0xef1 & c0011=0xa10) | ($(TMODE_E) & thv_c1627=0xef1 & thv_c0011=0xa10)) & fpscr & VRd
{
VRd = fpscr;
}
From 1fbb8a330a17daafdb37d61b5094ab2af8877281 Mon Sep 17 00:00:00 2001
From: Xiaoyin Liu
Date: Sat, 18 Jul 2020 18:53:03 +0800
Subject: [PATCH 019/140] Add more non-return functions
Add more functions to PEFunctionsThatDoNotReturn.
---
Ghidra/Features/Base/data/PEFunctionsThatDoNotReturn | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Ghidra/Features/Base/data/PEFunctionsThatDoNotReturn b/Ghidra/Features/Base/data/PEFunctionsThatDoNotReturn
index e8ed7404f4..51c5089410 100644
--- a/Ghidra/Features/Base/data/PEFunctionsThatDoNotReturn
+++ b/Ghidra/Features/Base/data/PEFunctionsThatDoNotReturn
@@ -1,7 +1,15 @@
+abort
CxxThrowException
CxxThrowException@8
CxxFrameHandler3
crtExitProcess
ExitProcess
+ExitThread
exit
+FreeLibraryAndExitThread
+invalid_parameter_noinfo_noreturn
+invoke_watson
longjmp
+quick_exit
+RpcRaiseException
+terminate
From 849504cda6f78a054e89418d32ed1089d1d9106d Mon Sep 17 00:00:00 2001
From: ghidra007
Date: Fri, 12 Feb 2021 18:48:37 +0000
Subject: [PATCH 020/140] GP-688 RTTI Util improved getVftableCount method to
not just rely on pseudoDissasembler but also check if existing function.
---
.../src/main/java/ghidra/app/cmd/data/rtti/RttiUtil.java | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/Ghidra/Features/MicrosoftCodeAnalyzer/src/main/java/ghidra/app/cmd/data/rtti/RttiUtil.java b/Ghidra/Features/MicrosoftCodeAnalyzer/src/main/java/ghidra/app/cmd/data/rtti/RttiUtil.java
index 4fd197d895..864953dbf8 100644
--- a/Ghidra/Features/MicrosoftCodeAnalyzer/src/main/java/ghidra/app/cmd/data/rtti/RttiUtil.java
+++ b/Ghidra/Features/MicrosoftCodeAnalyzer/src/main/java/ghidra/app/cmd/data/rtti/RttiUtil.java
@@ -25,8 +25,7 @@ import ghidra.app.util.PseudoDisassembler;
import ghidra.app.util.datatype.microsoft.MSDataTypeUtils;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSetView;
-import ghidra.program.model.listing.GhidraClass;
-import ghidra.program.model.listing.Program;
+import ghidra.program.model.listing.*;
import ghidra.program.model.mem.Memory;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.program.model.symbol.*;
@@ -166,7 +165,10 @@ public class RttiUtil {
break;
}
- if (!pseudoDisassembler.isValidSubroutine(referencedAddress, true, false)) {
+ Function function = program.getFunctionManager().getFunctionAt(referencedAddress);
+
+ if (function == null &&
+ !pseudoDisassembler.isValidSubroutine(referencedAddress, true, false)) {
break; // Not pointing to possible function.
}
From 4904a0e7b549d40fa8f9c8fa9a13af960b2288c9 Mon Sep 17 00:00:00 2001
From: Mike Walters
Date: Sat, 13 Feb 2021 02:08:02 +0000
Subject: [PATCH 021/140] 68000: fix disassembly of fmove with dynamic k-factor
---
Ghidra/Processors/68000/data/languages/68000.sinc | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Ghidra/Processors/68000/data/languages/68000.sinc b/Ghidra/Processors/68000/data/languages/68000.sinc
index 773ee2c4c6..1979794163 100644
--- a/Ghidra/Processors/68000/data/languages/68000.sinc
+++ b/Ghidra/Processors/68000/data/languages/68000.sinc
@@ -1747,7 +1747,7 @@ fcc: "sne" is fcode=0x1e { tmp:1 = $(Z_FP); clearflags_fp(); export tmp; }
@define FormatByteWordLongSimple "( ffmt=0 | ffmt=1 | ffmt=4 | ffmt=6 )"
-# The following constraint should be used when using fprec (ffmt=7 is not valid)
+# The following constraint should be used when using fprec
@define FPREC_BWLS "fprec & ( ffmt=0 | ffmt=1 | ffmt=4 | ffmt=6 )" # Byte,Word,Long,Simple only
@define FPREC_DXP "fprec & ( ffmt=2 | ffmt=3 | ffmt=5)" # Double,Extended,Packed only
@define FPREC_XP "fprec & ( ffmt=2 | ffmt=3)" # Extended,Packed only
@@ -1764,6 +1764,7 @@ fprec: "p" is ffmt=3 {}
fprec: "w" is ffmt=4 {}
fprec: "d" is ffmt=5 {}
fprec: "b" is ffmt=6 {}
+fprec: "p" is ffmt=7 {}
:fabs.^fprec e2l, fdst is op=15 & $(FP_COP) & op68=0 & $(DAT_ALTER_ADDR_MODES); frm=1 & f1515=0 & f1313=0 & fdst & $(FPREC_BWLS) & fopmode=0x18; e2l
From b0769bd805b494b4d06d213180d565170ab2ed0a Mon Sep 17 00:00:00 2001
From: dragonmacher <48328597+dragonmacher@users.noreply.github.com>
Date: Thu, 11 Feb 2021 13:29:14 -0500
Subject: [PATCH 022/140] GP-672 - fixed 'wait forever' bug
---
.../visualization/DefaultGraphDisplay.java | 23 +----
.../graph/visualization/SetLayoutTask.java | 43 +++++++---
.../docking/action/ToggleDockingAction.java | 5 +-
.../builder/MultiStateActionBuilder.java | 29 ++++---
.../docking/menu/MultiStateDockingAction.java | 83 ++++++++++++++-----
.../MultipleActionDockingToolbarButton.java | 13 ++-
6 files changed, 120 insertions(+), 76 deletions(-)
diff --git a/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/visualization/DefaultGraphDisplay.java b/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/visualization/DefaultGraphDisplay.java
index 41a21ce1e2..d2d345fcc9 100644
--- a/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/visualization/DefaultGraphDisplay.java
+++ b/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/visualization/DefaultGraphDisplay.java
@@ -379,7 +379,7 @@ public class DefaultGraphDisplay implements GraphDisplay {
new MultiStateActionBuilder("Arrangement", ACTION_OWNER)
.description("Arrangement: " + layoutActionStates.get(0).getName())
.toolBarIcon(DefaultDisplayGraphIcons.LAYOUT_ALGORITHM_ICON)
- .fireFirstAction(false)
+ .useCheckboxForIcons(true)
.onActionStateChanged((s, t) -> layoutChanged(s.getName()))
.addStates(layoutActionStates)
.buildAndInstallLocal(componentProvider);
@@ -701,11 +701,6 @@ public class DefaultGraphDisplay implements GraphDisplay {
}
}
- /**
- * get a {@code List} of {@code ActionState} buttons for the
- * configured layout algorithms
- * @return a {@code List} of {@code ActionState} buttons
- */
private List> getLayoutActionStates() {
String[] names = layoutTransitionManager.getLayoutNames();
List> actionStates = new ArrayList<>();
@@ -718,20 +713,10 @@ public class DefaultGraphDisplay implements GraphDisplay {
return actionStates;
}
- /**
- * respond to a change in the layout name
- * @param layoutName the name of the layout algorithm to apply
- */
private void layoutChanged(String layoutName) {
- if (layoutTransitionManager != null) {
- new TaskLauncher(new SetLayoutTask(viewer, layoutTransitionManager, layoutName), null,
- 1000);
- }
+ TaskLauncher.launch(new SetLayoutTask(viewer, layoutTransitionManager, layoutName));
}
- /**
- * show the dialog with generated filters
- */
private void showFilterDialog() {
if (filterDialog == null) {
if (vertexFilters == null) {
@@ -743,10 +728,6 @@ public class DefaultGraphDisplay implements GraphDisplay {
componentProvider.getTool().showDialog(filterDialog);
}
- /**
- * add or remove the satellite viewer
- * @param context information about the event
- */
private void toggleSatellite(ActionContext context) {
boolean selected = ((AbstractButton) context.getSourceObject()).isSelected();
graphDisplayProvider.setDefaultSatelliteState(selected);
diff --git a/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/visualization/SetLayoutTask.java b/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/visualization/SetLayoutTask.java
index a3745d21f7..dbf54fc9ed 100644
--- a/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/visualization/SetLayoutTask.java
+++ b/Ghidra/Features/GraphServices/src/main/java/ghidra/graph/visualization/SetLayoutTask.java
@@ -17,6 +17,7 @@ package ghidra.graph.visualization;
import java.util.concurrent.CountDownLatch;
+import org.jgrapht.Graph;
import org.jungrapht.visualization.VisualizationModel;
import org.jungrapht.visualization.VisualizationViewer;
import org.jungrapht.visualization.layout.event.LayoutStateChange.*;
@@ -24,6 +25,7 @@ import org.jungrapht.visualization.layout.model.LayoutModel;
import ghidra.service.graph.AttributedEdge;
import ghidra.service.graph.AttributedVertex;
+import ghidra.util.Msg;
import ghidra.util.Swing;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.*;
@@ -48,8 +50,8 @@ public class SetLayoutTask extends Task {
@Override
public void run(TaskMonitor monitor) throws CancelledException {
- // add a callback for when/if the user cancels the layout, use a variable cause
- // monitor uses a weak listener list and it would othewise get garbage collected.
+ // add a callback for when/if the user cancels the layout, use a variable because
+ // monitor uses a weak listener list and it would otherwise get garbage collected.
CancelledListener cancelListener = this::taskCancelled;
monitor.addCancelledListener(cancelListener);
@@ -60,16 +62,32 @@ public class SetLayoutTask extends Task {
Listener listener = this::layoutStateChanged;
support.addLayoutStateChangeListener(listener);
- // start the layout - needs to be done on swing thread to prevent issues and intermediate
+ // start the layout - needs to be done on swing thread to prevent issues and intermediate
// paints - should be changed in the future to not require it to be on the swing thread.
Swing.runNow(() -> layoutTransitionManager.setLayout(layoutName));
- // some of the layouts are done on the calling thread and some aren't. If they are on
+ waitForLayoutTransition(model);
+
+ support.removeLayoutStateChangeListener(listener);
+ monitor.removeCancelledListener(cancelListener);
+ }
+
+ private void waitForLayoutTransition(
+ VisualizationModel model) {
+
+ Graph graph = model.getGraph();
+ if (graph.vertexSet().isEmpty()) {
+ // note: the underlying graph API will not notify us of the layout state change if the
+ // graph is empty, so do not wait.
+ return;
+ }
+
+ // some of the layouts are done on the calling thread and some aren't. If they are on
// the calling thread, then by now, we already got the "done" callback and the "taskDone"
// countdown latch has been triggered and won't wait. If, however, the layout has been
// diverted to another thread, we want to wait until the layout is completed
// There are two ways the latch will be triggered, the layout is completed or the user
- // cancles the layout.
+ // cancels the layout.
try {
taskDone.await();
}
@@ -77,17 +95,17 @@ public class SetLayoutTask extends Task {
model.getLayoutAlgorithm().cancel();
}
- // clean up the listeners
- support.removeLayoutStateChangeListener(listener);
- monitor.removeCancelledListener(cancelListener);
}
/**
- * Notfication when the layout algorithm starts and stops.
- * @param e the event. If the event.active is true, then the
- * algorithm is starting, if false, the algorithm is done.
+ * Notification when the layout algorithm starts and stops
+ * @param e the event. If the event.active is true, then the algorithm is starting, if false,
+ * the algorithm is done.
*/
private void layoutStateChanged(Event e) {
+
+ Msg.debug(this, "layoutStatechanged(): " + e);
+
if (!e.active) {
// algorithm is done, release the latch
taskDone.countDown();
@@ -98,6 +116,9 @@ public class SetLayoutTask extends Task {
* Callback if the user cancels the layout
*/
private void taskCancelled() {
+
+ Msg.debug(this, "taskCancelled()");
+
// release the latch and tell the layout algorithm to cancel.
taskDone.countDown();
viewer.getVisualizationModel().getLayoutAlgorithm().cancel();
diff --git a/Ghidra/Framework/Docking/src/main/java/docking/action/ToggleDockingAction.java b/Ghidra/Framework/Docking/src/main/java/docking/action/ToggleDockingAction.java
index e16802706e..9b7c1e9ecf 100644
--- a/Ghidra/Framework/Docking/src/main/java/docking/action/ToggleDockingAction.java
+++ b/Ghidra/Framework/Docking/src/main/java/docking/action/ToggleDockingAction.java
@@ -19,7 +19,6 @@ import javax.swing.JButton;
import javax.swing.JMenuItem;
import docking.*;
-import docking.menu.DockingCheckboxMenuItemUI;
public abstract class ToggleDockingAction extends DockingAction implements ToggleDockingActionIf {
private boolean isSelected;
@@ -59,9 +58,7 @@ public abstract class ToggleDockingAction extends DockingAction implements Toggl
@Override
protected JMenuItem doCreateMenuItem() {
- DockingCheckBoxMenuItem menuItem = new DockingCheckBoxMenuItem(isSelected);
- menuItem.setUI((DockingCheckboxMenuItemUI) DockingCheckboxMenuItemUI.createUI(menuItem));
- return menuItem;
+ return new DockingCheckBoxMenuItem(isSelected);
}
@Override
diff --git a/Ghidra/Framework/Docking/src/main/java/docking/action/builder/MultiStateActionBuilder.java b/Ghidra/Framework/Docking/src/main/java/docking/action/builder/MultiStateActionBuilder.java
index 783c9fdea8..86d8f9806c 100644
--- a/Ghidra/Framework/Docking/src/main/java/docking/action/builder/MultiStateActionBuilder.java
+++ b/Ghidra/Framework/Docking/src/main/java/docking/action/builder/MultiStateActionBuilder.java
@@ -34,8 +34,8 @@ public class MultiStateActionBuilder extends
AbstractActionBuilder, ActionContext, MultiStateActionBuilder> {
private BiConsumer, EventTrigger> actionStateChangedCallback;
+ private boolean useCheckboxForIcons;
private boolean performActionOnButtonClick = false;
- private boolean fireFirstAction = true;
private List> states = new ArrayList<>();
@@ -80,6 +80,20 @@ public class MultiStateActionBuilder extends
return self();
}
+ /**
+ * Overrides the default icons for actions shown in popup menu of the multi-state action. By
+ * default, the popup menu items will use the icons as provided by the {@link ActionState}.
+ * By passing true to this method, icons will not be used in the popup menu. Instead, a
+ * checkbox icon will be used to show the active action state.
+ *
+ * @param b true to use a checkbox
+ * @return this MultiActionDockingActionBuilder (for chaining)
+ */
+ public MultiStateActionBuilder useCheckboxForIcons(boolean b) {
+ this.useCheckboxForIcons = b;
+ return self();
+ }
+
/**
* Add an action state
*
@@ -115,17 +129,6 @@ public class MultiStateActionBuilder extends
return self();
}
- /**
- * controls whether the first action added will automatically fire an event or not
- *
- * @param fireFirstAction do fire an action on the first action. Defaults to {@code true}
- * @return this MultiActionDockingActionBuilder (for chaining)
- */
- public MultiStateActionBuilder fireFirstAction(boolean fireFirstAction) {
- this.fireFirstAction = fireFirstAction;
- return self();
- }
-
@Override
public MultiStateDockingAction build() {
validate();
@@ -145,7 +148,6 @@ public class MultiStateActionBuilder extends
}
}
};
- action.setFireFirstEvent(fireFirstAction);
for (ActionState actionState : states) {
action.addActionState(actionState);
@@ -153,6 +155,7 @@ public class MultiStateActionBuilder extends
decorateAction(action);
action.setPerformActionOnPrimaryButtonClick(performActionOnButtonClick);
+ action.setUseCheckboxForIcons(useCheckboxForIcons);
return action;
}
diff --git a/Ghidra/Framework/Docking/src/main/java/docking/menu/MultiStateDockingAction.java b/Ghidra/Framework/Docking/src/main/java/docking/menu/MultiStateDockingAction.java
index b7e4e15321..4fc055dff0 100644
--- a/Ghidra/Framework/Docking/src/main/java/docking/menu/MultiStateDockingAction.java
+++ b/Ghidra/Framework/Docking/src/main/java/docking/menu/MultiStateDockingAction.java
@@ -53,9 +53,9 @@ public abstract class MultiStateDockingAction extends DockingAction {
private int currentStateIndex = 0;
private MultiActionDockingActionIf multiActionGenerator;
private MultipleActionDockingToolbarButton multipleButton;
- private boolean fireFirstEvent = true;
private boolean performActionOnPrimaryButtonClick = true;
+ private boolean useCheckboxForIcons;
// A listener that will get called when the button (not the popup) is clicked. Toolbar
// actions do not use this listener.
@@ -127,6 +127,18 @@ public abstract class MultiStateDockingAction extends DockingAction {
}
}
+ /**
+ * Overrides the default icons for actions shown in popup menu of the multi-state action. By
+ * default, the popup menu items will use the icons as provided by the {@link ActionState}.
+ * By passing true to this method, icons will not be used in the popup menu. Instead, a
+ * checkbox icon will be used to show the active action state.
+ *
+ * @param useCheckboxForIcons true to use a checkbox
+ */
+ public void setUseCheckboxForIcons(boolean useCheckboxForIcons) {
+ this.useCheckboxForIcons = useCheckboxForIcons;
+ }
+
@Override
public final void actionPerformed(ActionContext context) {
if (!performActionOnPrimaryButtonClick) {
@@ -137,21 +149,6 @@ public abstract class MultiStateDockingAction extends DockingAction {
doActionPerformed(context);
}
- /**
- * @return {@code true} if the first action automatically fire its event
- */
- public boolean isFireFirstEvent() {
- return fireFirstEvent;
- }
-
- /**
- * set the flag to fire an event on the first action
- * @param fireFirstEvent whether to fire the event
- */
- public void setFireFirstEvent(boolean fireFirstEvent) {
- this.fireFirstEvent = fireFirstEvent;
- }
-
/**
* This is the callback to be overridden when the child wishes to respond to user button
* presses that are on the button and not the drop-down. This will only be called if
@@ -175,9 +172,17 @@ public abstract class MultiStateDockingAction extends DockingAction {
}
protected List getStateActions() {
+ ActionState selectedState = actionStates.get(currentStateIndex);
List actions = new ArrayList<>(actionStates.size());
for (ActionState actionState : actionStates) {
- actions.add(new ActionStateAction(actionState));
+
+ //@formatter:off
+ boolean isSelected = actionState == selectedState;
+ DockingActionIf a = useCheckboxForIcons ?
+ new ActionStateToggleAction(actionState, isSelected) :
+ new ActionStateAction(actionState, isSelected);
+ actions.add(a);
+ //@formatter:on
}
return actions;
}
@@ -199,7 +204,7 @@ public abstract class MultiStateDockingAction extends DockingAction {
*/
public void addActionState(ActionState actionState) {
actionStates.add(actionState);
- if (actionStates.size() == 1 && fireFirstEvent) {
+ if (actionStates.size() == 1) {
setCurrentActionState(actionState);
}
}
@@ -209,9 +214,7 @@ public abstract class MultiStateDockingAction extends DockingAction {
throw new IllegalArgumentException("You must provide at least one ActionState");
}
actionStates = new ArrayList<>(newStates);
- if (fireFirstEvent) {
- setCurrentActionState(actionStates.get(0));
- }
+ setCurrentActionState(actionStates.get(0));
}
public T getCurrentUserData() {
@@ -235,7 +238,7 @@ public abstract class MultiStateDockingAction extends DockingAction {
}
throw new AssertException(
- "Attempted to set an action state by a user type not " + "contained herein: " + t);
+ "Attempted to set an action state by a user type not contained herein: " + t);
}
public void setCurrentActionState(ActionState actionState) {
@@ -318,13 +321,47 @@ public abstract class MultiStateDockingAction extends DockingAction {
//==================================================================================================
// Inner Classes
//==================================================================================================
+
+ private class ActionStateToggleAction extends ToggleDockingAction {
+
+ private final ActionState actionState;
+
+ private ActionStateToggleAction(ActionState actionState, boolean isSelected) {
+ super(actionState.getName(), "multiStateAction");
+
+ this.actionState = actionState;
+
+ setSelected(isSelected);
+
+ setMenuBarData(
+ new MenuData(new String[] { actionState.getName() }));
+ HelpLocation helpLocation = actionState.getHelpLocation();
+ if (helpLocation != null) {
+ setHelpLocation(helpLocation);
+ }
+ }
+
+ @Override
+ public String getInceptionInformation() {
+ // we want the debug info for these internal actions to be that of the outer class
+ return MultiStateDockingAction.this.getInceptionInformation();
+ }
+
+ @Override
+ public void actionPerformed(ActionContext context) {
+ setCurrentActionStateWithTrigger(actionState, EventTrigger.GUI_ACTION);
+ }
+
+ }
+
private class ActionStateAction extends DockingAction {
private final ActionState actionState;
- private ActionStateAction(ActionState actionState) {
+ private ActionStateAction(ActionState actionState, boolean isSelected) {
super(actionState.getName(), "multiStateAction");
this.actionState = actionState;
+
setMenuBarData(
new MenuData(new String[] { actionState.getName() }, actionState.getIcon()));
HelpLocation helpLocation = actionState.getHelpLocation();
diff --git a/Ghidra/Framework/Docking/src/main/java/docking/menu/MultipleActionDockingToolbarButton.java b/Ghidra/Framework/Docking/src/main/java/docking/menu/MultipleActionDockingToolbarButton.java
index 8409488aed..ceef1a3092 100644
--- a/Ghidra/Framework/Docking/src/main/java/docking/menu/MultipleActionDockingToolbarButton.java
+++ b/Ghidra/Framework/Docking/src/main/java/docking/menu/MultipleActionDockingToolbarButton.java
@@ -30,7 +30,7 @@ import docking.*;
import docking.action.*;
import docking.widgets.EmptyBorderButton;
import docking.widgets.label.GDHtmlLabel;
-import ghidra.util.SystemUtilities;
+import ghidra.util.Swing;
import resources.ResourceManager;
public class MultipleActionDockingToolbarButton extends EmptyBorderButton {
@@ -80,7 +80,8 @@ public class MultipleActionDockingToolbarButton extends EmptyBorderButton {
* method will effectively let the user click anywhere on the button or its drop-down arrow
* to show the popup menu. During normal operation, the user can only show the popup by
* clicking the drop-down arrow.
- *
+ *
+ * @param performActionOnButtonClick true to perform the action when the button is clicked
*/
public void setPerformActionOnButtonClick(boolean performActionOnButtonClick) {
entireButtonShowsPopupMenu = !performActionOnButtonClick;
@@ -160,7 +161,11 @@ public class MultipleActionDockingToolbarButton extends EmptyBorderButton {
return manager.getActiveComponentProvider();
}
- /** Show a popup containing all the actions below the button */
+ /**
+ * Show a popup containing all the actions below the button
+ * @param listener for the created popup menu
+ * @return the popup menu that was shown
+ */
JPopupMenu showPopup(PopupMenuListener listener) {
JPopupMenu menu = new JPopupMenu();
List actionList = multipleAction.getActionList(getActionContext());
@@ -307,7 +312,7 @@ public class MultipleActionDockingToolbarButton extends EmptyBorderButton {
// will update the focused window after we click. We need the focus to be
// correct before we show, since our menu is built with actions based upon the
// focused dude.
- SystemUtilities.runSwingLater(() -> popupMenu = showPopup(PopupMouseListener.this));
+ Swing.runLater(() -> popupMenu = showPopup(PopupMouseListener.this));
e.consume();
model.setPressed(false);
From 303208aa660f51c6a3c9962f510890970b2351e5 Mon Sep 17 00:00:00 2001
From: dragonmacher <48328597+dragonmacher@users.noreply.github.com>
Date: Thu, 18 Feb 2021 13:07:18 -0500
Subject: [PATCH 023/140] Program Graph - fixed tooltip line wrapping bug when
showing code
---
.../src/main/java/ghidra/service/graph/Attributed.java | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/Ghidra/Framework/Graph/src/main/java/ghidra/service/graph/Attributed.java b/Ghidra/Framework/Graph/src/main/java/ghidra/service/graph/Attributed.java
index af8962e0a1..4b940d78b8 100644
--- a/Ghidra/Framework/Graph/src/main/java/ghidra/service/graph/Attributed.java
+++ b/Ghidra/Framework/Graph/src/main/java/ghidra/service/graph/Attributed.java
@@ -20,6 +20,8 @@ import java.util.Map.Entry;
import org.apache.commons.text.StringEscapeUtils;
+import com.google.common.base.Splitter;
+
public class Attributed {
/**
* cache of the html rendering of the vertex attributes
@@ -84,7 +86,7 @@ public class Attributed {
/**
* Returns the number of attributes defined
- *
+ *
* @return the number of attributes defined
*/
public int size() {
@@ -162,7 +164,9 @@ public class Attributed {
for (Map.Entry entry : entries) {
buf.append(entry.getKey());
buf.append(":");
- buf.append(StringEscapeUtils.escapeHtml4(entry.getValue()));
+ String value = StringEscapeUtils.escapeHtml4(entry.getValue());
+ String split = String.join(" ", Splitter.on('\n').split(value));
+ buf.append(split);
buf.append(" ");
}
htmlString = buf.toString();
From 4602ff464621f03b42bb56808860b6ea9abf49b5 Mon Sep 17 00:00:00 2001
From: Xiaoyin Liu
Date: Wed, 8 Apr 2020 19:29:39 +0800
Subject: [PATCH 024/140] Add missing quotes in launch.bat
When set Windows environment variables, they need to be quoted if
special characters like & exists in path.
Fixes #1726
---
.../RuntimeScripts/Windows/support/launch.bat | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/Ghidra/RuntimeScripts/Windows/support/launch.bat b/Ghidra/RuntimeScripts/Windows/support/launch.bat
index 9bee1566cf..0fc913c731 100644
--- a/Ghidra/RuntimeScripts/Windows/support/launch.bat
+++ b/Ghidra/RuntimeScripts/Windows/support/launch.bat
@@ -36,7 +36,7 @@ for /f "tokens=2" %%# in ("%cmdcmdline%") do if /i "%%#" equ "/c" set DOUBLE_CLI
:: '% ~' dereferences the value in param 0
:: 'd' - drive
:: 'p' - path (without filename)
-set SUPPORT_DIR=%~dp0
+set "SUPPORT_DIR=%~dp0"
::
:: Parse arguments
@@ -63,20 +63,20 @@ goto showUsage
::
:: Production Environment
::
-set INSTALL_DIR=%SUPPORT_DIR%..\
-set CPATH=%INSTALL_DIR%Ghidra\Framework\Utility\lib\Utility.jar
-set LS_CPATH=%SUPPORT_DIR%LaunchSupport.jar
-set DEBUG_LOG4J=%SUPPORT_DIR%debug.log4j.xml
+set "INSTALL_DIR=%SUPPORT_DIR%..\"
+set "CPATH=%INSTALL_DIR%Ghidra\Framework\Utility\lib\Utility.jar"
+set "LS_CPATH=%SUPPORT_DIR%LaunchSupport.jar"
+set "DEBUG_LOG4J=%SUPPORT_DIR%debug.log4j.xml"
if exist "%INSTALL_DIR%Ghidra" goto continue2
::
:: Development Environment
::
-set INSTALL_DIR=%INSTALL_DIR%..\..\..\
-set CPATH=%INSTALL_DIR%Ghidra\Framework\Utility\bin\main
-set LS_CPATH=%INSTALL_DIR%GhidraBuild\LaunchSupport\bin\main
-set DEBUG_LOG4J=%INSTALL_DIR%Ghidra\RuntimeScripts\Common\support\debug.log4j.xml
+set "INSTALL_DIR=%INSTALL_DIR%..\..\..\"
+set "CPATH=%INSTALL_DIR%Ghidra\Framework\Utility\bin\main"
+set "LS_CPATH=%INSTALL_DIR%GhidraBuild\LaunchSupport\bin\main"
+set "DEBUG_LOG4J=%INSTALL_DIR%Ghidra\RuntimeScripts\Common\support\debug.log4j.xml"
:continue2
From 61096c5fdff1b28790bd19a8e72db28fb1ace44d Mon Sep 17 00:00:00 2001
From: Xiaoyin Liu
Date: Fri, 10 Apr 2020 16:44:33 +0800
Subject: [PATCH 025/140] Add one more missing quote around JAVA_CMD
---
Ghidra/RuntimeScripts/Windows/support/launch.bat | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Ghidra/RuntimeScripts/Windows/support/launch.bat b/Ghidra/RuntimeScripts/Windows/support/launch.bat
index 0fc913c731..5621f4e895 100644
--- a/Ghidra/RuntimeScripts/Windows/support/launch.bat
+++ b/Ghidra/RuntimeScripts/Windows/support/launch.bat
@@ -108,7 +108,7 @@ if "%JAVA_HOME%" == "" (
goto exit1
)
)
-set JAVA_CMD=%JAVA_HOME%\bin\java
+set "JAVA_CMD=%JAVA_HOME%\bin\java"
:: Get the configurable VM arguments from the launch properties
for /f "delims=*" %%i in ('java -cp "%LS_CPATH%" LaunchSupport "%INSTALL_DIR%\" -vmargs') do set VMARG_LIST=%VMARG_LIST% %%i
From 143f4a0ba14bc717825d1a08682fc863df3da850 Mon Sep 17 00:00:00 2001
From: ghizard <50744617+ghizard@users.noreply.github.com>
Date: Thu, 18 Feb 2021 19:51:12 -0500
Subject: [PATCH 026/140] GP-698 check-in of ANALYZED flag fix
---
.../app/plugin/core/analysis/AutoAnalysisManager.java | 8 +++++++-
.../app/plugin/core/analysis/AutoAnalysisPlugin.java | 7 ++++++-
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AutoAnalysisManager.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AutoAnalysisManager.java
index 01838c2ed7..0ff7a1f3a9 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AutoAnalysisManager.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AutoAnalysisManager.java
@@ -1110,7 +1110,13 @@ public class AutoAnalysisManager implements DomainObjectListener, DomainObjectCl
int answer = OptionDialog.showYesNoDialog(tool.getToolFrame(), "Analyze",
"" + HTMLUtilities.escapeHTML(program.getDomainFile().getName()) +
" has not been analyzed. Would you like to analyze it now?");
- return answer == OptionDialog.OPTION_ONE; // Analyze
+ boolean analyze = answer == OptionDialog.OPTION_ONE;
+ if (!analyze) {
+ // Must set this to false at each fall-out location. Setting it true too early
+ // results in false positives. It is set true only at the beginning of analysis.
+ GhidraProgramUtilities.setAnalyzedFlag(program, false);
+ }
+ return analyze;
}
return false;
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AutoAnalysisPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AutoAnalysisPlugin.java
index 13e4f68cfa..96cfa1e16f 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AutoAnalysisPlugin.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AutoAnalysisPlugin.java
@@ -188,12 +188,17 @@ public class AutoAnalysisPlugin extends Plugin implements AutoAnalysisManagerLis
analysisMgr.initializeOptions(); // get initial options
if (!showOptionsDialog(program)) {
+ // Must set this to false at each fall-out location. Setting it true too early
+ // results in false positives. It is set true only at the beginning of analysis.
+ GhidraProgramUtilities.setAnalyzedFlag(program, false);
return;
}
- GhidraProgramUtilities.setAnalyzedFlag(program, true);
analysisMgr.initializeOptions(); // options may have changed
+ // At this point, any analysis that is done is consider to be true for analyzed.
+ GhidraProgramUtilities.setAnalyzedFlag(program, true);
+
// start analysis to set the flag, but it probably won't do more. A bit goofy but better
// than the way it was
//TODO simplify all this after creating a taskManager per program instead of per tool.
From 95b37d2ce1495f8524c89fe829d9a0d7f9ef7e59 Mon Sep 17 00:00:00 2001
From: Ryan Kurtz
Date: Fri, 19 Feb 2021 10:46:20 -0500
Subject: [PATCH 027/140] GP-693: Fixed additional issues with Ghidra and its
supporting launch scripts not being able to run correctly on Windows when an
ampersand was in the path. Also fixed an issue with svrAdmin.bat and
buildGhidraJar.bat not working if the Ghidra path contained a space.
---
.../java/ghidra/util/GhidraJarBuilder.java | 16 +++-----
.../main/java/ghidra/server/ServerAdmin.java | 26 +++++-------
.../Windows/server/ghidraSvr.bat | 40 ++++++++-----------
.../Windows/server/svrAdmin.bat | 10 ++---
.../Windows/server/svrInstall.bat | 2 +-
.../Windows/server/svrUninstall.bat | 2 +-
.../Windows/support/analyzeHeadless.bat | 2 +-
.../Windows/support/buildGhidraJar.bat | 4 +-
.../Windows/support/createPdbXmlFiles.bat | 8 ++--
.../Windows/support/pythonRun.bat | 2 +-
10 files changed, 47 insertions(+), 65 deletions(-)
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/util/GhidraJarBuilder.java b/Ghidra/Features/Base/src/main/java/ghidra/util/GhidraJarBuilder.java
index 7ded06d9a2..3805428083 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/util/GhidraJarBuilder.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/util/GhidraJarBuilder.java
@@ -20,6 +20,7 @@ import java.nio.file.Path;
import java.util.*;
import java.util.jar.*;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
import java.util.zip.*;
import generic.jar.*;
@@ -44,7 +45,6 @@ public class GhidraJarBuilder implements GhidraLaunchable {
private static final String LIBS_FILE_MODULE_KEY = "Module: ";
// this is set in the buildGhidraJar batch/script files
- private static final String GHIDRA_DIR = "Ghidra.Install.Root.Dir";
private static final String INVOCATION_NAME_PROPERTY = "GhidraJarBuilder.Name";
private static HashMap> libsMap = new HashMap<>();
private List rootGhidraDirs = new ArrayList<>();
@@ -961,14 +961,10 @@ public class GhidraJarBuilder implements GhidraLaunchable {
System.err.println("arg " + i + ": " + args[i]);
}
String invocationName = System.getProperty(INVOCATION_NAME_PROPERTY);
- String property = System.getProperty(GHIDRA_DIR);
StringBuffer buf = new StringBuffer();
buf.append("\nUsage: ");
buf.append(invocationName != null ? invocationName : "GhidraJarBuilder ");
- if (property == null) {
- buf.append(" [ ...] ");
- }
buf.append(
" [-output
From 24891974e15a88652ccf34382b4fd7e1da8f6388 Mon Sep 17 00:00:00 2001
From: ghidra1
Date: Mon, 22 Feb 2021 11:31:18 -0500
Subject: [PATCH 034/140] Corrected conflict
---
.../app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
index 0814299b0f..f27e125b47 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/cli/blobs/CliBlobCustomAttrib.java
@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
From 01b6027c771ab85a2278624fc1ba8e93bd62159f Mon Sep 17 00:00:00 2001
From: emteere <47253321+emteere@users.noreply.github.com>
Date: Mon, 22 Feb 2021 13:55:34 +0000
Subject: [PATCH 035/140] GP-697_emteere delayed reading of symbol names to
improve memory read performance
---
.../app/util/bin/format/elf/ElfSymbol.java | 155 +++++++++++-------
.../util/bin/format/elf/ElfSymbolTable.java | 34 ++--
2 files changed, 122 insertions(+), 67 deletions(-)
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfSymbol.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfSymbol.java
index 297dedfd3b..170c317d97 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfSymbol.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfSymbol.java
@@ -103,11 +103,24 @@ public class ElfSymbol implements ByteArrayConverter {
private String nameAsString;
+ /**
+ * create an ElfSymbol()
+ * Warning! the routine initSymbolName() must be called on the symbol later
+ * to initialize the string name. This is a performance enhancement.
+ *
+ * @param reader to read symbol from
+ * @param symbolIndex index of the symbol to read
+ * @param symbolTable symbol table to associate the symbol to
+ * @param stringTable string table to read symbols from
+ * @param header else header
+ * @return newly created ElfSymbol
+ *
+ * @throws IOException if an issue with reading occurs
+ */
public static ElfSymbol createElfSymbol(FactoryBundledWithBinaryReader reader, int symbolIndex,
- ElfSymbolTable symbolTable, ElfStringTable stringTable, ElfHeader header)
- throws IOException {
+ ElfSymbolTable symbolTable, ElfHeader header) throws IOException {
ElfSymbol elfSymbol = (ElfSymbol) reader.getFactory().create(ElfSymbol.class);
- elfSymbol.initElfSymbol(reader, symbolIndex, symbolTable, stringTable, header);
+ elfSymbol.initElfSymbol(reader, symbolIndex, symbolTable, header);
return elfSymbol;
}
@@ -117,49 +130,6 @@ public class ElfSymbol implements ByteArrayConverter {
public ElfSymbol() {
}
- private void initElfSymbol(FactoryBundledWithBinaryReader reader, int symbolIndex,
- ElfSymbolTable symbolTable, ElfStringTable stringTable, ElfHeader header)
- throws IOException {
- this.header = header;
- this.symbolTable = symbolTable;
- this.symbolTableIndex = symbolIndex;
-
- if (header.is32Bit()) {
- st_name = reader.readNextInt();
- st_value = reader.readNextInt() & Conv.INT_MASK;
- st_size = reader.readNextInt() & Conv.INT_MASK;
- st_info = reader.readNextByte();
- st_other = reader.readNextByte();
- st_shndx = reader.readNextShort();
- }
- else {
- st_name = reader.readNextInt();
- st_info = reader.readNextByte();
- st_other = reader.readNextByte();
- st_shndx = reader.readNextShort();
- st_value = reader.readNextLong();
- st_size = reader.readNextLong();
- }
-
- if (st_name == 0) {
- if (getType() == STT_SECTION) {
- ElfSectionHeader[] sections = header.getSections();
- if (st_shndx < 0 || st_shndx >= sections.length) {
- //invalid section reference...
- //this is a bug in objcopy, whereby sections are removed
- //but the corresponding section symbols are left behind.
- }
- else {
- ElfSectionHeader section = sections[st_shndx];
- nameAsString = section.getNameAsString();
- }
- }
- }
- else {
- nameAsString = stringTable.readString(reader, st_name);
- }
- }
-
/**
* Creates a new section symbol.
* @param header the corresponding ELF header
@@ -209,6 +179,69 @@ public class ElfSymbol implements ByteArrayConverter {
this.symbolTableIndex = symbolIndex;
}
+ private void initElfSymbol(FactoryBundledWithBinaryReader reader, int symbolIndex,
+ ElfSymbolTable symbolTable, ElfHeader header) throws IOException {
+ this.header = header;
+ this.symbolTable = symbolTable;
+ this.symbolTableIndex = symbolIndex;
+
+ if (header.is32Bit()) {
+ st_name = reader.readNextInt();
+ st_value = reader.readNextInt() & Conv.INT_MASK;
+ st_size = reader.readNextInt() & Conv.INT_MASK;
+ st_info = reader.readNextByte();
+ st_other = reader.readNextByte();
+ st_shndx = reader.readNextShort();
+ }
+ else {
+ st_name = reader.readNextInt();
+ st_info = reader.readNextByte();
+ st_other = reader.readNextByte();
+ st_shndx = reader.readNextShort();
+ st_value = reader.readNextLong();
+ st_size = reader.readNextLong();
+ }
+
+ if (st_name == 0) {
+ if (getType() == STT_SECTION) {
+ ElfSectionHeader[] sections = header.getSections();
+ if (st_shndx < 0 || st_shndx >= sections.length) {
+ //invalid section reference...
+ //this is a bug in objcopy, whereby sections are removed
+ //but the corresponding section symbols are left behind.
+ }
+ else {
+ ElfSectionHeader section = sections[st_shndx];
+ nameAsString = section.getNameAsString();
+ }
+ }
+ }
+ else {
+ // The string name will be initialized later
+ // in a call to initSymbolName()
+ }
+ }
+
+ /**
+ * Initialize the string name of the symbol.
+ *
+ * NOTE: This routine MUST be called for each
+ * ELFSymbol after the elf symbols have been created.
+ *
+ * This is done separately from the initial symbol entry read because
+ * the string names are in a separate location. If they are read
+ * at the same time the reading buffer will jump around and significantly
+ * degrade reading performance.
+ *
+ * @param reader to read from
+ * @param stringTable stringTable to initialize symbol name
+ */
+ public void initSymbolName(FactoryBundledWithBinaryReader reader, ElfStringTable stringTable) {
+ if (nameAsString == null) {
+ nameAsString = stringTable.readString(reader, st_name);
+ }
+ }
+
/**
* Get the symbol table containing this symbol
* @return symbol table
@@ -249,27 +282,37 @@ public class ElfSymbol implements ByteArrayConverter {
@Override
public boolean equals(Object obj) {
- if (this == obj)
+ if (this == obj) {
return true;
- if (obj == null)
+ }
+ if (obj == null) {
return false;
- if (getClass() != obj.getClass())
+ }
+ if (getClass() != obj.getClass()) {
return false;
+ }
ElfSymbol other = (ElfSymbol) obj;
- if (st_info != other.st_info)
+ if (st_info != other.st_info) {
return false;
- if (st_name != other.st_name)
+ }
+ if (st_name != other.st_name) {
return false;
- if (st_other != other.st_other)
+ }
+ if (st_other != other.st_other) {
return false;
- if (st_shndx != other.st_shndx)
+ }
+ if (st_shndx != other.st_shndx) {
return false;
- if (st_size != other.st_size)
+ }
+ if (st_size != other.st_size) {
return false;
- if (st_value != other.st_value)
+ }
+ if (st_value != other.st_value) {
return false;
- if (symbolTableIndex != other.symbolTableIndex)
+ }
+ if (symbolTableIndex != other.symbolTableIndex) {
return false;
+ }
return true;
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfSymbolTable.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfSymbolTable.java
index 09eea496c9..fcb4631af9 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfSymbolTable.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/elf/ElfSymbolTable.java
@@ -18,6 +18,7 @@ package ghidra.app.util.bin.format.elf;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import java.util.stream.Collectors;
import ghidra.app.util.bin.ByteArrayConverter;
import ghidra.app.util.bin.format.FactoryBundledWithBinaryReader;
@@ -96,15 +97,26 @@ public class ElfSymbolTable implements ElfFileSection, ByteArrayConverter {
long entryPos = reader.getPointerIndex();
+ // load the all the symbol entries first, don't initialize the string name
+ // that will be done later to help localize memory access
for (int i = 0; i < symbolCount; i++) {
// Reposition reader to start of symbol element since ElfSymbol object
// may not consume all symbol element data
reader.setPointerIndex(entryPos);
- ElfSymbol sym = ElfSymbol.createElfSymbol(reader, i, this, stringTable, header);
+ ElfSymbol sym = ElfSymbol.createElfSymbol(reader, i, this, header);
symbolList.add(sym);
entryPos += entrySize;
}
+ // sort the entries by the index in the string table, so don't jump around reading
+ List sortedList = symbolList.stream().sorted(
+ (o1, o2) -> Integer.compare(o1.getName(), o2.getName())).collect(Collectors.toList());
+
+ // initialize the Symbol string names from string table
+ for (ElfSymbol sym : sortedList) {
+ sym.initSymbolName(reader, stringTable);
+ }
+
reader.setPointerIndex(ptr);
symbols = new ElfSymbol[symbolList.size()];
@@ -163,9 +175,9 @@ public class ElfSymbolTable implements ElfFileSection, ByteArrayConverter {
* @return the symbol at the specified address
*/
public ElfSymbol getSymbolAt(long addr) {
- for (int i = 0; i < symbols.length; i++) {
- if (symbols[i].getValue() == addr) {
- return symbols[i];
+ for (ElfSymbol symbol : symbols) {
+ if (symbol.getValue() == addr) {
+ return symbol;
}
}
return null;
@@ -177,9 +189,9 @@ public class ElfSymbolTable implements ElfFileSection, ByteArrayConverter {
*/
public ElfSymbol[] getGlobalSymbols() {
List list = new ArrayList<>();
- for (int i = 0; i < symbols.length; i++) {
- if (symbols[i].getBind() == ElfSymbol.STB_GLOBAL) {
- list.add(symbols[i]);
+ for (ElfSymbol symbol : symbols) {
+ if (symbol.getBind() == ElfSymbol.STB_GLOBAL) {
+ list.add(symbol);
}
}
ElfSymbol[] array = new ElfSymbol[list.size()];
@@ -193,11 +205,11 @@ public class ElfSymbolTable implements ElfFileSection, ByteArrayConverter {
*/
public String[] getSourceFiles() {
List list = new ArrayList<>();
- for (int j = 0; j < symbols.length; j++) {
- if (symbols[j].getType() == ElfSymbol.STT_FILE) {
- String name = symbols[j].getNameAsString();
+ for (ElfSymbol symbol : symbols) {
+ if (symbol.getType() == ElfSymbol.STT_FILE) {
+ String name = symbol.getNameAsString();
if (name != null) {
- list.add(symbols[j].getNameAsString());
+ list.add(symbol.getNameAsString());
}
}
}
From 3d36d914bea71cd65ae621cc671ac69cea2c4d8c Mon Sep 17 00:00:00 2001
From: dev747368 <48332326+dev747368@users.noreply.github.com>
Date: Fri, 5 Feb 2021 13:22:26 -0500
Subject: [PATCH 036/140] GP-667 fix XmlImport bookmark overwrite existing
---
.../ghidra/app/util/xml/BookmarksXmlMgr.java | 28 +++++++++++--------
1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/xml/BookmarksXmlMgr.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/xml/BookmarksXmlMgr.java
index be4bb67b8f..99db7273cb 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/xml/BookmarksXmlMgr.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/xml/BookmarksXmlMgr.java
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
- * REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +15,18 @@
*/
package ghidra.app.util.xml;
+import org.xml.sax.SAXParseException;
+
import ghidra.app.util.importer.MessageLog;
-import ghidra.program.model.address.*;
-import ghidra.program.model.listing.*;
+import ghidra.program.model.address.Address;
+import ghidra.program.model.address.AddressFactory;
+import ghidra.program.model.address.AddressFormatException;
+import ghidra.program.model.address.AddressIterator;
+import ghidra.program.model.address.AddressSetView;
+import ghidra.program.model.listing.Bookmark;
+import ghidra.program.model.listing.BookmarkManager;
+import ghidra.program.model.listing.BookmarkType;
+import ghidra.program.model.listing.Program;
import ghidra.util.XmlProgramUtilities;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
@@ -27,8 +35,6 @@ import ghidra.util.xml.XmlWriter;
import ghidra.xml.XmlElement;
import ghidra.xml.XmlPullParser;
-import org.xml.sax.SAXParseException;
-
class BookmarksXmlMgr {
private BookmarkManager bookmarkMgr;
private AddressFactory factory;
@@ -97,13 +103,13 @@ class BookmarksXmlMgr {
}
try {
- if (!overwrite) {
- if (bookmarkMgr.getBookmark(addr, type, category) != null) {
- log.appendMsg("Conflicting '" + type + "' BOOKMARK ignored at: " + addr);
- return;
- }
+ boolean hasExistingBookmark = bookmarkMgr.getBookmark(addr, type, category) != null;
+ if (overwrite || !hasExistingBookmark) {
+ bookmarkMgr.setBookmark(addr, type, category, comment);
+ }
+ if (!overwrite && hasExistingBookmark) {
+ log.appendMsg("Conflicting '" + type + "' BOOKMARK ignored at: " + addr);
}
- bookmarkMgr.setBookmark(addr, type, category, comment);
}
catch (Exception e) {
log.appendException(e);
From 7868dbc4f992311dcce012bf284f9f6be953347a Mon Sep 17 00:00:00 2001
From: Ryan Kurtz
Date: Mon, 22 Feb 2021 11:40:32 -0500
Subject: [PATCH 037/140] GP-702: Fixed an exception that occurred when
importing Mach-O files that define zero LC_BUILD_VERSION tool entries
---
.../util/bin/format/macho/commands/BuildVersionCommand.java | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/BuildVersionCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/BuildVersionCommand.java
index 45d8b4b115..fa918132d3 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/BuildVersionCommand.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/BuildVersionCommand.java
@@ -80,8 +80,10 @@ public class BuildVersionCommand extends LoadCommand {
struct.add(DWORD, "minos", null);
struct.add(DWORD, "sdk", null);
struct.add(DWORD, "ntools", null);
- struct.add(new ArrayDataType(buildToolVersionDataType, ntools,
- buildToolVersionDataType.getLength()), "build_tool_version[]", null);
+ if (ntools > 0) {
+ struct.add(new ArrayDataType(buildToolVersionDataType, ntools,
+ buildToolVersionDataType.getLength()), "build_tool_version[]", null);
+ }
struct.setCategoryPath(new CategoryPath(MachConstants.DATA_TYPE_CATEGORY));
return struct;
}
From 1c0ad2c8df09549cc0f891dd13f4aa5f019a00b4 Mon Sep 17 00:00:00 2001
From: dragonmacher <48328597+dragonmacher@users.noreply.github.com>
Date: Mon, 22 Feb 2021 16:19:19 -0500
Subject: [PATCH 038/140] GP-705 - Gnu Demangler speed improvement
---
.../analysis/AbstractDemanglerAnalyzer.java | 27 ++++++++++++++-----
.../demangler/gnu/GnuDemanglerParser.java | 6 +++--
.../ghidra/util/classfinder/ClassPackage.java | 2 +-
.../main/datatree/LocalTreeNodeHandler.java | 2 +-
4 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AbstractDemanglerAnalyzer.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AbstractDemanglerAnalyzer.java
index 6722672bfa..7763217f21 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AbstractDemanglerAnalyzer.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AbstractDemanglerAnalyzer.java
@@ -57,19 +57,38 @@ public abstract class AbstractDemanglerAnalyzer extends AbstractAnalyzer {
public boolean added(Program program, AddressSetView set, TaskMonitor monitor, MessageLog log)
throws CancelledException {
+ try {
+ monitor.setIndeterminate(true);
+ return doAdded(program, set, monitor, log);
+ }
+ finally {
+ monitor.setIndeterminate(false);
+ }
+ }
+
+ private boolean doAdded(Program program, AddressSetView set, TaskMonitor monitor,
+ MessageLog log)
+ throws CancelledException {
+
DemanglerOptions options = getOptions();
if (!validateOptions(options, log)) {
log.appendMsg(getName(), "Invalid demangler options--cannot demangle");
return false;
}
- monitor.initialize(100);
+ int count = 0;
+
+ String defaultMessage = monitor.getMessage();
SymbolTable symbolTable = program.getSymbolTable();
SymbolIterator it = symbolTable.getPrimarySymbolIterator(set, true);
while (it.hasNext()) {
monitor.checkCanceled();
+ if (++count % 100 == 0) {
+ monitor.setMessage(defaultMessage + " - " + count + " symbols");
+ }
+
Symbol symbol = it.next();
if (skipSymbol(symbol)) {
continue;
@@ -81,12 +100,6 @@ public abstract class AbstractDemanglerAnalyzer extends AbstractAnalyzer {
if (demangled != null) {
apply(program, address, demangled, options, log, monitor);
}
-
- Address min = set.getMinAddress();
- Address max = set.getMaxAddress();
- int distance = (int) (address.getOffset() - min.getOffset());
- int percent = (int) ((distance / max.getOffset()) * 100);
- monitor.setProgress(percent);
}
return true;
diff --git a/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemanglerParser.java b/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemanglerParser.java
index 0a8e286903..171b061ecf 100644
--- a/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemanglerParser.java
+++ b/Ghidra/Features/GnuDemangler/src/main/java/ghidra/app/util/demangler/gnu/GnuDemanglerParser.java
@@ -244,6 +244,8 @@ public class GnuDemanglerParser {
*
* Parts:
* -required text (capture group 2)
+ * --note: this uses '++', a possessive quantifier, to help keep the
+ * backtracking to a minimum
* -a space
* -'for' or 'to' (capture group 3)
* -a space
@@ -262,7 +264,7 @@ public class GnuDemanglerParser {
* non-virtual thunk to
*/
private static final Pattern DESCRIPTIVE_PREFIX_PATTERN =
- Pattern.compile("((.+ )+(for|to) )(.+)");
+ Pattern.compile("((.+ )(for|to) )(.+)");
/**
* The c 'decltype' keyword pattern
@@ -307,7 +309,7 @@ public class GnuDemanglerParser {
// note: this capture group seems to fail with excessive templating
String operatorTemplates = "(<.+>){0,1}";
String operatorPrefix =
- ".*(.*" + OPERATOR + "(" + alternated + ")\\s*" + operatorTemplates + ".*)\\s*";
+ "(.*" + OPERATOR + "(" + alternated + ")\\s*" + operatorTemplates + ")\\s*";
String parameters = "(\\(.*\\))";
String trailing = "(.*)";
diff --git a/Ghidra/Framework/Generic/src/main/java/ghidra/util/classfinder/ClassPackage.java b/Ghidra/Framework/Generic/src/main/java/ghidra/util/classfinder/ClassPackage.java
index ddadfa431e..2a03c777e8 100644
--- a/Ghidra/Framework/Generic/src/main/java/ghidra/util/classfinder/ClassPackage.java
+++ b/Ghidra/Framework/Generic/src/main/java/ghidra/util/classfinder/ClassPackage.java
@@ -78,7 +78,7 @@ class ClassPackage extends ClassLocation {
pkg = packageName + "." + pkg;
}
- monitor.setMessage("scanning package: " + pkg);
+ monitor.setMessage("Scanning package: " + pkg);
children.add(new ClassPackage(rootDir, pkg, monitor));
}
}
diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/LocalTreeNodeHandler.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/LocalTreeNodeHandler.java
index bcc70cdd84..b91a7d08d6 100644
--- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/LocalTreeNodeHandler.java
+++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/datatree/LocalTreeNodeHandler.java
@@ -222,7 +222,7 @@ public final class LocalTreeNodeHandler
GTreeNode copyNode = toCopy.get(i);
monitor.setMessage(
- "Processing file " + i + " of " + size + ": " + copyNode.getName());
+ "Processing file " + (i + 1) + " of " + size + ": " + copyNode.getName());
add(destination, copyNode, dropAction, subMonitors[i]);
monitor.setProgress(i);
From 0ed83875fcb25b57ce16d2fb8a23f307c950140e Mon Sep 17 00:00:00 2001
From: dragonmacher <48328597+dragonmacher@users.noreply.github.com>
Date: Tue, 23 Feb 2021 12:33:16 -0500
Subject: [PATCH 039/140] GP-696 Raised ProgramDB version to 23 (upgrade not
required). Implement BigRefList for from-refs
---
.../ghidra/program/database/ProgramDB.java | 4 +++-
.../database/references/BigRefListV0.java | 21 ++++++++++++-------
.../database/references/FromAdapterV0.java | 3 +++
.../references/ReferenceDBManager.java | 1 +
4 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/ProgramDB.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/ProgramDB.java
index 331393df72..237f44302d 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/ProgramDB.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/ProgramDB.java
@@ -96,8 +96,10 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
* 19-Jun-2020 - version 22 - Corrected fixed length indexing implementation causing
* change in index table low-level storage for newly
* created tables.
+ * 18-Feb-2021 - version 23 Added support for Big Reflist for tracking FROM references.
+ * Primarily used for large numbers of Entry Point references.
*/
- static final int DB_VERSION = 22;
+ static final int DB_VERSION = 23;
/**
* UPGRADE_REQUIRED_BFORE_VERSION should be changed to DB_VERSION anytime the
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/BigRefListV0.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/BigRefListV0.java
index e4b5b67c75..4f8e5f2dda 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/BigRefListV0.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/BigRefListV0.java
@@ -62,17 +62,17 @@ class BigRefListV0 extends RefList {
* @param address address associated with this list
* @param adapter entry record storage adapter
* @param addrMap address map for encoding/decoding addresses
- * @param program
+ * @param program associated Program
* @param cache RefList object cache
* @param isFrom true for from-adapter use, false for to-adapter use
- * @throws IOException
+ * @throws IOException if database IO error occurs
*/
BigRefListV0(Address address, RecordAdapter adapter, AddressMap addrMap, ProgramDB program,
DBObjectCache cache, boolean isFrom) throws IOException {
super(addrMap.getKey(address, true), address, adapter, addrMap, program, cache, isFrom);
record = ToAdapter.TO_REFS_SCHEMA.createRecord(key);
- table = program.getDBHandle().createTable(BASE_TABLE_NAME + Long.toHexString(key),
- BIG_REFS_SCHEMA, new int[] { ADDRESS_COL });
+ table = program.getDBHandle()
+ .createTable(getTableName(), BIG_REFS_SCHEMA, new int[] { ADDRESS_COL });
}
/**
@@ -80,9 +80,10 @@ class BigRefListV0 extends RefList {
* @param rec existing refList record
* @param adapter entry record storage adapter
* @param addrMap address map for encoding/decoding addresses
- * @param program
+ * @param program associated Program
* @param cache RefList object cache
* @param isFrom true for from-adapter use, false for to-adapter use
+ * @throws IOException if database IO error occurs
*/
BigRefListV0(DBRecord rec, RecordAdapter adapter, AddressMap addrMap, ProgramDB program,
DBObjectCache cache, boolean isFrom) throws IOException {
@@ -91,11 +92,10 @@ class BigRefListV0 extends RefList {
if (rec.getBinaryData(ToAdapter.REF_DATA_COL) != null) {
throw new IllegalArgumentException("Invalid reference record");
}
- String tableName = BASE_TABLE_NAME + Long.toHexString(rec.getKey());
- table = program.getDBHandle().getTable(tableName);
+ table = program.getDBHandle().getTable(getTableName());
if (table == null) {
throw new IOException(
- "BigRefList table not found for " + address + " (" + tableName + ")");
+ "BigRefList table not found for " + address + " (" + getTableName() + ")");
}
if (!isFrom) {
refLevel = rec.getByteValue(ToAdapter.REF_LEVEL_COL);
@@ -103,6 +103,11 @@ class BigRefListV0 extends RefList {
record = rec;
}
+ private String getTableName() {
+ String prefix = isFrom ? "From" : "";
+ return prefix + BASE_TABLE_NAME + Long.toHexString(key);
+ }
+
@Override
public RefList checkRefListSize(DBObjectCache cache, int newSpaceRequired) {
return this;
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/FromAdapterV0.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/FromAdapterV0.java
index f1597d3dbc..e05b0cf90f 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/FromAdapterV0.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/FromAdapterV0.java
@@ -60,6 +60,9 @@ class FromAdapterV0 extends FromAdapter {
long fromAddr) throws IOException {
DBRecord rec = table.getRecord(fromAddr);
if (rec != null) {
+ if (rec.getBinaryData(REF_DATA_COL) == null) {
+ return new BigRefListV0(rec, this, addrMap, program, cache, true);
+ }
return new RefListV0(rec, this, addrMap, program, cache, true);
}
return null;
diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/ReferenceDBManager.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/ReferenceDBManager.java
index 867e454da0..f3f47f5be9 100644
--- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/ReferenceDBManager.java
+++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/references/ReferenceDBManager.java
@@ -382,6 +382,7 @@ public class ReferenceDBManager implements ReferenceManager, ManagerDB, ErrorHan
if (fromRefs == null) {
fromRefs = fromAdapter.createRefList(program, fromCache, fromAddr);
}
+ fromRefs = fromRefs.checkRefListSize(fromCache, 1);
fromRefs.addRef(fromAddr, toAddr, type, opIndex, -1, isPrimary, sourceType, isOffset,
isShifted, offsetOrShift);
From 9c1fed6a133c3e2a39bf57e97d9f4c4c457d534b Mon Sep 17 00:00:00 2001
From: ghidra1
Date: Tue, 23 Feb 2021 12:27:48 -0500
Subject: [PATCH 040/140] GP-710 Added support for additional PIC30 ELF
relocations (closes #2792)
---
.../elf/relocation/PIC30_ElfRelocationHandler.java | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/Ghidra/Processors/PIC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PIC30_ElfRelocationHandler.java b/Ghidra/Processors/PIC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PIC30_ElfRelocationHandler.java
index 6059bd0968..915ad21d31 100644
--- a/Ghidra/Processors/PIC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PIC30_ElfRelocationHandler.java
+++ b/Ghidra/Processors/PIC/src/main/java/ghidra/app/util/bin/format/elf/relocation/PIC30_ElfRelocationHandler.java
@@ -155,15 +155,25 @@ public class PIC30_ElfRelocationHandler extends ElfRelocationHandler {
if (elf.e_machine() == ElfConstants.EM_DSPIC30F) {
switch (type) {
case R_PIC30_16: // 2
- newValue = (symbolValue + addend + oldShortValue) & 0xffff;
+ case R_PIC30_FILE_REG_WORD: // 6
+ newValue = (symbolValue + addend + oldShortValue);
memory.setShort(relocationAddress, (short) newValue);
break;
case R_PIC30_32: // 3
newValue = symbolValue + addend + oldValue;
memory.setInt(relocationAddress, newValue);
break;
+ case R_PIC30_FILE_REG_BYTE: // 4 short
+ case R_PIC30_FILE_REG: // 5 short
+ int reloc = symbolValue;
+ reloc += addend;
+ reloc += oldShortValue;
+ reloc &= 0x1fff;
+ newValue = reloc | (oldShortValue & ~0x1fff);
+ memory.setShort(relocationAddress, (short) newValue);
+ break;
case R_PIC30_FILE_REG_WORD_WITH_DST: // 7
- int reloc = symbolValue >> 1;
+ reloc = symbolValue >> 1;
reloc += addend;
reloc += oldValue >> 4;
reloc &= 0x7fff;
From 446ade9e0296ec31216f0c4e1adbae44a11218e3 Mon Sep 17 00:00:00 2001
From: dragonmacher <48328597+dragonmacher@users.noreply.github.com>
Date: Tue, 23 Feb 2021 13:31:08 -0500
Subject: [PATCH 041/140] Test fix
---
.../app/plugin/core/data/ApplyDataTypeToBrowserTest.java | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/data/ApplyDataTypeToBrowserTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/data/ApplyDataTypeToBrowserTest.java
index 4d6ffa774f..768eb98099 100644
--- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/data/ApplyDataTypeToBrowserTest.java
+++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/data/ApplyDataTypeToBrowserTest.java
@@ -167,7 +167,7 @@ public class ApplyDataTypeToBrowserTest extends AbstractGhidraHeadedIntegrationT
@Test
public void testChooseDataTypeOnDefinedDts() throws Exception {
- //
+ //
// Test that apply data on an existing type will offer to clear that type
//
@@ -206,8 +206,6 @@ public class ApplyDataTypeToBrowserTest extends AbstractGhidraHeadedIntegrationT
public void testChooseDataTypeWhereDoesNotFit() throws Exception {
goTo("004027e0");
- showDataTypeChooser();
-
showDataTypeChooser();
chooseInDialog("_person");
@@ -790,8 +788,7 @@ public class ApplyDataTypeToBrowserTest extends AbstractGhidraHeadedIntegrationT
assertEquals(expectedText, statusText);
}
- private void dragNDropDataTypeToCurrentBrowserLocation(
- final DataType dataType) {
+ private void dragNDropDataTypeToCurrentBrowserLocation(final DataType dataType) {
executeOnSwingWithoutBlocking(() -> {
// Simulate the drag-n-drop of the data type onto the location.
ProgramLocation programLocation = codeViewerProvider.getLocation();
From 33435048dea3e4b767a42ea0bf6e1da7d26f8686 Mon Sep 17 00:00:00 2001
From: dev747368 <48332326+dev747368@users.noreply.github.com>
Date: Tue, 23 Feb 2021 15:11:04 -0500
Subject: [PATCH 042/140] GP-695 Improve DWARF analyzer's runOnce, remove
parsing of raw Elf
---
.../ghidra_scripts/DWARF_ExtractorScript.java | 2 +-
.../plugin/core/analysis/DWARFAnalyzer.java | 33 +++++--
.../bin/format/dwarf4/next/DWARFProgram.java | 18 ++--
.../DWARFSectionProviderFactory.java | 7 +-
.../sectionprovider/ElfSectionProvider.java | 95 -------------------
5 files changed, 34 insertions(+), 121 deletions(-)
delete mode 100644 Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/sectionprovider/ElfSectionProvider.java
diff --git a/Ghidra/Features/Base/ghidra_scripts/DWARF_ExtractorScript.java b/Ghidra/Features/Base/ghidra_scripts/DWARF_ExtractorScript.java
index 6b4f87803f..59885a6062 100644
--- a/Ghidra/Features/Base/ghidra_scripts/DWARF_ExtractorScript.java
+++ b/Ghidra/Features/Base/ghidra_scripts/DWARF_ExtractorScript.java
@@ -63,7 +63,7 @@ public class DWARF_ExtractorScript extends GhidraScript {
@Override
public void run() throws Exception {
- if (!DWARFProgram.isDWARF(currentProgram, monitor)) {
+ if (!DWARFProgram.isDWARF(currentProgram)) {
popup("Unable to find DWARF information, aborting");
return;
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/DWARFAnalyzer.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/DWARFAnalyzer.java
index 45627bfbdf..6a501ea5e1 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/DWARFAnalyzer.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/DWARFAnalyzer.java
@@ -34,6 +34,8 @@ import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
public class DWARFAnalyzer extends AbstractAnalyzer {
+ private static final String DWARF_LOADED_OPTION_NAME = "DWARF Loaded";
+
private static final String OPTION_IMPORT_DATATYPES = "Import data types";
private static final String OPTION_IMPORT_DATATYPES_DESC =
"Import data types defined in the DWARF debug info.";
@@ -84,6 +86,7 @@ public class DWARFAnalyzer extends AbstractAnalyzer {
"Automatically extracts DWARF info from an ELF file.";
private DWARFImportOptions importOptions = new DWARFImportOptions();
+ private long lastTxId = -1;
public DWARFAnalyzer() {
super(DWARF_ANALYZER_NAME, DWARF_ANALYZER_DESCRIPTION, AnalyzerType.BYTE_ANALYZER);
@@ -105,22 +108,24 @@ public class DWARFAnalyzer extends AbstractAnalyzer {
public boolean added(Program program, AddressSetView set, TaskMonitor monitor, MessageLog log)
throws CancelledException {
- if (!canAnalyze(program)) {
- // Check again because external DWARF data (ie. dSYM files) could have been moved
- // between the time canAnalyze() was called the first time and when this method
- // is called
- log.appendMsg("Unable to find DWARF information, skipping DWARF analysis");
- return false;
+ long txId = program.getCurrentTransaction().getID();
+ if (txId == lastTxId) {
+ // Only run once per analysis session - as denoted by being in the same transaction
+ return true;
}
+ lastTxId = txId;
- if (DWARFProgram.alreadyDWARFImported(program)) {
- Msg.warn(this, "DWARF already imported, skipping. (Detected DWARF program module)");
+ Options propList = program.getOptions(Program.PROGRAM_INFO);
+ boolean alreadyLoaded = propList.getBoolean(DWARF_LOADED_OPTION_NAME, false) ||
+ oldCheckIfDWARFImported(program);
+ if (alreadyLoaded) {
+ Msg.info(this, "DWARF already imported, skipping.");
return false;
}
DWARFSectionProvider dsp = DWARFSectionProviderFactory.createSectionProviderFor(program);
if (dsp == null) {
- // silently return, canAnalyze() was false positive
+ log.appendMsg("Unable to find DWARF information, skipping DWARF analysis");
return false;
}
@@ -139,6 +144,7 @@ public class DWARFAnalyzer extends AbstractAnalyzer {
DWARFImportSummary parseResults = dp.parse();
parseResults.logSummaryResults();
}
+ propList.setBoolean(DWARF_LOADED_OPTION_NAME, true);
return true;
}
catch (CancelledException ce) {
@@ -157,9 +163,16 @@ public class DWARFAnalyzer extends AbstractAnalyzer {
return false;
}
+ private boolean oldCheckIfDWARFImported(Program prog) {
+ // this was the old way of checking if the DWARF analyzer had already been run. Keep
+ // it around for a little bit so existing programs that have already imported DWARF data
+ // don't get re-run. Remove after a release or two.
+ return DWARFFunctionImporter.hasDWARFProgModule(prog, DWARFProgram.DWARF_ROOT_NAME);
+ }
+
@Override
public boolean canAnalyze(Program program) {
- return DWARFProgram.isDWARF(program, null);
+ return DWARFProgram.isDWARF(program);
}
@Override
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFProgram.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFProgram.java
index 6462efea8e..afd2246961 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFProgram.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/DWARFProgram.java
@@ -54,12 +54,8 @@ public class DWARFProgram implements Closeable {
private static final int NAME_HASH_REPLACEMENT_SIZE = 8 + 2 + 2;
private static final String ELLIPSES_STR = "...";
- public static boolean alreadyDWARFImported(Program prog) {
- return DWARFFunctionImporter.hasDWARFProgModule(prog, DWARF_ROOT_NAME);
- }
-
/**
- * Returns true if the {@link Program program} probably DWARF information.
+ * Returns true if the {@link Program program} probably has DWARF information.
*
* If the program is an Elf binary, it must have (at least) ".debug_info" and ".debug_abbr" program sections.
*
@@ -67,17 +63,17 @@ public class DWARFProgram implements Closeable {
* original binary file on the native filesystem. (ie. outside of Ghidra). See the DSymSectionProvider
* for more info.
*
- * @param program
- * @param monitor
- * @return
+ * @param program {@link Program} to test
+ * @return boolean true if program has DWARF info, false if not
*/
- public static boolean isDWARF(Program program, TaskMonitor monitor) {
+ public static boolean isDWARF(Program program) {
String format = program.getExecutableFormat();
- if (ElfLoader.ELF_NAME.equals(format)) {
+ if (ElfLoader.ELF_NAME.equals(format) &&
+ DWARFSectionProviderFactory.createSectionProviderFor(program) != null) {
return true;
}
- else if (MachoLoader.MACH_O_NAME.equals(format) &&
+ if (MachoLoader.MACH_O_NAME.equals(format) &&
DSymSectionProvider.getDSYMForProgram(program) != null) {
return true;
}
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/sectionprovider/DWARFSectionProviderFactory.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/sectionprovider/DWARFSectionProviderFactory.java
index 7ea6cdce59..7cb75f4a24 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/sectionprovider/DWARFSectionProviderFactory.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/sectionprovider/DWARFSectionProviderFactory.java
@@ -15,14 +15,14 @@
*/
package ghidra.app.util.bin.format.dwarf4.next.sectionprovider;
-import ghidra.program.model.listing.Program;
-import ghidra.util.Msg;
-
import java.io.Closeable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
+import ghidra.program.model.listing.Program;
+import ghidra.util.Msg;
+
/**
* Auto-detects which {@link DWARFSectionProvider} matches a Ghidra program.
*/
@@ -44,7 +44,6 @@ public class DWARFSectionProviderFactory {
static {
sectionProviderFactoryFuncs.add(BaseSectionProvider::createSectionProviderFor);
sectionProviderFactoryFuncs.add(DSymSectionProvider::createSectionProviderFor);
- sectionProviderFactoryFuncs.add(ElfSectionProvider::createSectionProviderFor);
}
/**
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/sectionprovider/ElfSectionProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/sectionprovider/ElfSectionProvider.java
deleted file mode 100644
index 4eb692cabc..0000000000
--- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf4/next/sectionprovider/ElfSectionProvider.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/* ###
- * IP: GHIDRA
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package ghidra.app.util.bin.format.dwarf4.next.sectionprovider;
-
-import ghidra.app.util.bin.*;
-import ghidra.app.util.bin.format.elf.*;
-import ghidra.app.util.opinion.ElfLoader;
-import ghidra.program.model.listing.Program;
-
-import java.io.File;
-import java.io.IOException;
-
-import generic.continues.RethrowContinuesFactory;
-
-/**
- * Fetches DWARF section data from ELF files, directly, without going through
- * the Ghidra memory block api. This section provider usually isn't needed as
- * ELF sections are normally provided as Ghidra memory blocks. In case of extra-
- * large binaries, Ghidra may not be able to map the debug sections into memory
- * and this section provider will allow the DWARF analyzer to still function.
- */
-public class ElfSectionProvider implements DWARFSectionProvider {
-
- private ElfHeader header;
- private RandomAccessByteProvider provider;
-
- public static ElfSectionProvider createSectionProviderFor(Program program) {
- if (ElfLoader.ELF_NAME.equals(program.getExecutableFormat())) {
- try {
- File exePath = new File(program.getExecutablePath());
- return new ElfSectionProvider(exePath);
- }
- catch (IOException ioe) {
- // ignore
- }
- }
- return null;
- }
-
- public ElfSectionProvider(File exeFile) throws IOException {
- provider = new RandomAccessByteProvider(exeFile);
- try {
- // Parse the ELF header to get the sections
- header = ElfHeader.createElfHeader(RethrowContinuesFactory.INSTANCE, provider);
- header.parse();
- }
- catch (ElfException e) {
- provider.close();
- throw new IOException("Error parsing ELF", e);
- }
- }
-
- @Override
- public ByteProvider getSectionAsByteProvider(String sectionName) throws IOException {
-
- ElfSectionHeader section = header.getSection("." + sectionName);
-
- return (section != null) ? new ByteProviderWrapper(section.getReader().getByteProvider(),
- section.getOffset(), section.getSize()) : null;
- }
-
- @Override
- public void close() {
- try {
- provider.close();
- }
- catch (IOException e) {
- // ignore
- }
- }
-
- @Override
- public boolean hasSection(String... sectionNames) {
- for (String sectionName : sectionNames) {
- if (header.getSection("." + sectionName) == null) {
- return false;
- }
- }
- return true;
- }
-
-}
From c545a6fb5a3a1cc1f1c090546d8e24e80363fc7f Mon Sep 17 00:00:00 2001
From: ghidra1
Date: Tue, 23 Feb 2021 16:06:02 -0500
Subject: [PATCH 043/140] GP-710 Added register symbol processing to ELF PIC30
import processing. Improved code unit operand format to render memory
register name when no reference is present.
---
.../program/model/listing/CodeUnitFormat.java | 18 +++++++++++-
.../format/elf/extend/PIC30_ElfExtension.java | 28 +++++++++++++++++++
2 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/model/listing/CodeUnitFormat.java b/Ghidra/Features/Base/src/main/java/ghidra/program/model/listing/CodeUnitFormat.java
index 2bf413cddd..4124eeec9a 100644
--- a/Ghidra/Features/Base/src/main/java/ghidra/program/model/listing/CodeUnitFormat.java
+++ b/Ghidra/Features/Base/src/main/java/ghidra/program/model/listing/CodeUnitFormat.java
@@ -493,7 +493,8 @@ public class CodeUnitFormat {
InstructionScalarInfo info = new InstructionScalarInfo(representations, primaryRef);
if (info.hasSingleAddressWithNoScalars()) {
int addressIndex = info.getAddressIndex();
- return markupAddressAsScalar(inst, primaryRef, representations, addressIndex);
+ return markupAddressAsRegister(inst, primaryRef, representations, addressIndex) ||
+ markupAddressAsScalar(inst, primaryRef, representations, addressIndex);
}
if (info.hasNoScalars()) {
@@ -564,6 +565,21 @@ public class CodeUnitFormat {
return primaryRef == null;
}
+ private boolean markupAddressAsRegister(Instruction instr, Reference primaryRef,
+ List