diff --git a/Ghidra/Debug/Debugger-agent-lldb/src/main/help/help/topics/lldb/lldb.html b/Ghidra/Debug/Debugger-agent-lldb/src/main/help/help/topics/lldb/lldb.html index 654d58ffe2..33e9057262 100644 --- a/Ghidra/Debug/Debugger-agent-lldb/src/main/help/help/topics/lldb/lldb.html +++ b/Ghidra/Debug/Debugger-agent-lldb/src/main/help/help/topics/lldb/lldb.html @@ -43,6 +43,9 @@ python3 -m pip install psutil protobuf==3.20.3 +

If you're using lldb from the Android NDK and do not have Pip, see Setup for Android NDK

+

If you are offline, or would like to use our provided packages, we still use Pip, but with a more complicated invocation:

@@ -205,5 +208,63 @@ perl -i -pe 's/(?<=pendingNMI\x00{4})\x00/\x01/' macOS_15-1234567.vmss

This has the same options as the LLDB via SSH launcher, which are necessary for connecting to the Android debugger, but executes via the normal lldb mechanism.

+ +

Setup for Android NDK

+ +

If you're using the copy of lldb included with the Android NDK (Native Development + Kit), it may not include pip. Notably, this is the case on Windows at the time of + writing. Fortunately, you can retrieve the components to install Pip into the NDK from an + official Python distribution.

+ +
    +
  1. + First, figure out the version of Python that is embedded in the NDK's build of LLDB, and + get its path. (If you know the path to lldb, you probably already know the path to its + Python.) From a Windows Command Prompt or Powershell: +
    +PS> C:\path\to\android-ndk\...\lldb
    +(lldb) script
    +>>> import sys
    +>>> sys.version
    +[copy down the version indicated]
    +>>> sys.path
    +[look for the paths ending with Lib and DLLs, and copy them down]
    +
    +
  2. + +
  3. Now, obtain the same version of Python from the official Python website, and install or + unpack it.
  4. + +
  5. Locate your new installation of Python. If you don't already know where it landed, this + can be found by examining the Properties of the Python shortcut in your Start Menu.
  6. + +
  7. There should be a Lib\ensurepip directory in the official Python installation. + Copy this into the same place in the Android NDK's build of Python.
  8. + +
  9. + There are also three native modules that need to be copied from the official Python's + DLLs\ directory to the same in the NDK's build. This is to support SSL for + downloading packages from PyPI: (Substitue the ??'s appropriately.) + + +
  10. + +
  11. + We should now have enough to bootstrap the NDK's Python with Pip. Again at the Windows + Command Prompt or Powershell: +
    +PS> C:\path\to\android-ndk\...\python -m ensurepip
    +PS> C:\path\to\android-ndk\...\python -m pip install ...
    +
    + See the Setup section for the arguments to pass to pip install + .... +
  12. +
diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/tree/DtFilterDialog.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/tree/DtFilterDialog.java index dcdc8ba196..f4af227db3 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/tree/DtFilterDialog.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/tree/DtFilterDialog.java @@ -178,7 +178,7 @@ public class DtFilterDialog extends DialogComponentProvider { this.type = type; this.typeCb = new GCheckBox(type); this.typeDefCb = new GCheckBox(); - this.typeDefCb.setName(type + "Typedefs"); + this.typeDefCb.setName(type + "TypeDefs"); } JComponent getLeft() { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/tree/DtFilterState.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/tree/DtFilterState.java index 235d892e45..6727b2cb30 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/tree/DtFilterState.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/datamgr/tree/DtFilterState.java @@ -137,40 +137,38 @@ public class DtFilterState { DataType baseDt = DataTypeUtils.getBaseDataType(dt); if (dt instanceof Array) { - return passes(arraysFilter, dt, baseDt); + return passes(arraysFilter, dt); } if (dt instanceof Pointer) { - return passes(pointersFilter, dt, baseDt); + return passes(pointersFilter, dt); } if (baseDt instanceof Enum) { - return passes(enumsFilter, dt, baseDt); + return passes(enumsFilter, dt); } if (baseDt instanceof Function) { - return passes(functionsFilter, dt, baseDt); + return passes(functionsFilter, dt); } if (baseDt instanceof Structure) { - return passes(structuresFilter, dt, baseDt); + return passes(structuresFilter, dt); } if (baseDt instanceof Union) { - return passes(unionsFilter, dt, baseDt); + return passes(unionsFilter, dt); } return true; } - private boolean passes(DtTypeFilter filter, DataType dt, DataType baseDt) { - if (filter.isTypeActive()) { - return true; + private boolean passes(DtTypeFilter filter, DataType dt) { + if (dt instanceof TypeDef) { + return filter.isTypeDefActive(); } - if (filter.isTypeDefActive() && dt instanceof TypeDef) { - return true; - } - return false; + + return filter.isTypeActive(); } public void save(SaveState parentSaveState) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoLoader.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoLoader.java index 75a7e99987..8c51c0ecc9 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoLoader.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoLoader.java @@ -65,50 +65,57 @@ public class MachoLoader extends AbstractLibrarySupportLoader { return loadSpecs; } - // Efficient check to fail fast - byte[] magicBytes = provider.readBytes(0, 4); - if (!MachConstants.isMagic(LittleEndianDataConverter.INSTANCE.getInt(magicBytes))) { - return loadSpecs; + // This loader can handle both Mach-O files as well as Universal Binary files. If it's a + // Universal Binary, each Mach-O it contains will be presented as a single "preferred" + // load spec, forcing the user to have to select the desired processor from the import + // dialog. + List allProviders = new ArrayList<>(); + boolean onlyPreferred; + if (isUniveralBinary(provider)) { + allProviders.addAll(getUniveralBinaryProviders(provider)); + onlyPreferred = true; + } + else { + allProviders.add(provider); + onlyPreferred = false; } - try { - MachHeader machHeader = new MachHeader(provider); - String magic = - CpuTypes.getMagicString(machHeader.getCpuType(), machHeader.getCpuSubType()); - String compiler = detectCompilerName(machHeader); - List results = QueryOpinionService.query(MACH_O_NAME, magic, compiler); - for (QueryResult result : results) { - loadSpecs.add(new LoadSpec(this, machHeader.getImageBase(), result)); + for (ByteProvider machoProvider : allProviders) { + byte[] magicBytes = machoProvider.readBytes(0, 4); + if (!MachConstants.isMagic(LittleEndianDataConverter.INSTANCE.getInt(magicBytes))) { + continue; } - if (loadSpecs.isEmpty()) { - loadSpecs.add(new LoadSpec(this, machHeader.getImageBase(), true)); + try { + MachHeader machHeader = new MachHeader(machoProvider); + String magic = + CpuTypes.getMagicString(machHeader.getCpuType(), machHeader.getCpuSubType()); + String compiler = detectCompilerName(machHeader); + List results = QueryOpinionService.query(MACH_O_NAME, magic, compiler); + for (QueryResult result : results) { + if (!onlyPreferred || result.preferred) { + loadSpecs.add(new LoadSpec(this, machHeader.getImageBase(), result)); + } + } + if (loadSpecs.isEmpty() && !onlyPreferred) { + loadSpecs.add(new LoadSpec(this, machHeader.getImageBase(), true)); + } + } + catch (MachException e) { + // not a problem, just don't add it } } - catch (MachException e) { - // not a problem, just don't add it - } + return loadSpecs; } - private String detectCompilerName(MachHeader machHeader) throws IOException { - List sectionNames = machHeader.parseSegments() - .stream() - .flatMap(seg -> seg.getSections().stream()) - .map(section -> section.getSectionName()) - .toList(); - if (SwiftUtils.isSwift(sectionNames)) { - return SwiftUtils.SWIFT_COMPILER; - } - if (GoRttiMapper.hasGolangSections(sectionNames)) { - return GoConstants.GOLANG_CSPEC_NAME; - } - return null; - } - @Override public void load(ByteProvider provider, LoadSpec loadSpec, List