mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 17:59:46 +02:00
GP-5677: Ghidra now writes a "lastrun" file that PyGhidra can look for
to help find the Ghidra installation dir
This commit is contained in:
parent
7b01e2a595
commit
189117e7d4
4 changed files with 55 additions and 7 deletions
|
@ -16,6 +16,8 @@
|
|||
package ghidra;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
||||
import javax.swing.ToolTipManager;
|
||||
|
||||
|
@ -23,6 +25,7 @@ import org.apache.logging.log4j.LogManager;
|
|||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import docking.framework.SplashScreen;
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.base.help.GhidraHelpService;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.GhidraApplicationConfiguration;
|
||||
|
@ -77,6 +80,8 @@ public class GhidraRun implements GhidraLaunchable {
|
|||
log.info("User temp directory: " + Application.getUserTempDirectory());
|
||||
log.info("User cache directory: " + Application.getUserCacheDirectory());
|
||||
|
||||
writeLastRun();
|
||||
|
||||
initializeTooltips();
|
||||
|
||||
updateSplashScreenStatusMessage("Populating Ghidra help...");
|
||||
|
@ -99,6 +104,22 @@ public class GhidraRun implements GhidraLaunchable {
|
|||
mainThread.start();
|
||||
}
|
||||
|
||||
private void writeLastRun() {
|
||||
// Write the Ghidra installation location to the "lastrun" file
|
||||
File settingsDir = Application.getUserSettingsDirectory();
|
||||
ResourceFile rootDir = Application.getApplicationRootDirectory();
|
||||
if (settingsDir != null && rootDir != null) {
|
||||
File lastRunFile = new File(settingsDir.getParentFile(), "lastrun");
|
||||
try {
|
||||
Files.writeString(lastRunFile.toPath(),
|
||||
rootDir.getParentFile().getCanonicalPath() + "\n");
|
||||
}
|
||||
catch (IOException e) {
|
||||
log.error("Failed to write 'lastrun' file", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String processArguments(String[] args) {
|
||||
//TODO remove this special handling when possible
|
||||
if (args.length == 1 && (args[0].startsWith("-D") || args[0].indexOf(" -D") >= 0)) {
|
||||
|
|
|
@ -55,7 +55,7 @@ def start(verbose=False, *, install_dir: Path = None) -> "PyGhidraLauncher":
|
|||
|
||||
:param verbose: Enable verbose output during JVM startup (Defaults to False)
|
||||
:param install_dir: The path to the Ghidra installation directory.
|
||||
(Defaults to the GHIDRA_INSTALL_DIR environment variable)
|
||||
(Defaults to the GHIDRA_INSTALL_DIR environment variable or "lastrun" file)
|
||||
:return: The PyGhidraLauncher used to start the JVM
|
||||
"""
|
||||
```
|
||||
|
@ -222,7 +222,7 @@ def run_script(
|
|||
This may be either a Java class or its path. (Defaults to None)
|
||||
:param install_dir: The path to the Ghidra installation directory. This parameter is only
|
||||
used if Ghidra has not been started yet.
|
||||
(Defaults to the GHIDRA_INSTALL_DIR environment variable)
|
||||
(Defaults to the GHIDRA_INSTALL_DIR environment variable or "lastrun" file)
|
||||
:param program_name: The name of the program to open in Ghidra.
|
||||
(Defaults to None, which results in the name being derived from "binary_path")
|
||||
:param nested_project_location: If True, assumes "project_location" contains an extra nested
|
||||
|
@ -330,6 +330,10 @@ __2.2.0:__
|
|||
[`pyghidra.run_script()`](#pyghidrarun_script) now accept a `nested_project_location` parameter
|
||||
which can be set to `False` to open existing Ghidra projects that were created with the
|
||||
Ghidra GUI.
|
||||
* If a Ghidra installation directory is not specified by the `install_dir` parameter or
|
||||
`GHIDRA_INSTALL_DIR` environment variable, PyGhidra will look for a `lastrun` file in the
|
||||
Ghidra user settings parent directory, and use the installation directory it specifies. The
|
||||
`lastrun` file is created by Ghidra 11.4 and later.
|
||||
|
||||
__2.1.0:__
|
||||
* [`pyghidra.open_program()`](#pyghidraopen_program) now accepts a `program_name` parameter, which
|
||||
|
|
|
@ -33,7 +33,7 @@ def start(verbose=False, *, install_dir: Path = None) -> "PyGhidraLauncher":
|
|||
|
||||
:param verbose: Enable verbose output during JVM startup (Defaults to False)
|
||||
:param install_dir: The path to the Ghidra installation directory.
|
||||
(Defaults to the GHIDRA_INSTALL_DIR environment variable)
|
||||
(Defaults to the GHIDRA_INSTALL_DIR environment variable or "lastrun" file)
|
||||
:return: The PyGhidraLauncher used to start the JVM
|
||||
"""
|
||||
from pyghidra.launcher import HeadlessPyGhidraLauncher
|
||||
|
@ -302,7 +302,7 @@ def _flat_api(
|
|||
This may be either a Java class or its path. (Defaults to None)
|
||||
:param install_dir: The path to the Ghidra installation directory. This parameter is only
|
||||
used if Ghidra has not been started yet.
|
||||
(Defaults to the GHIDRA_INSTALL_DIR environment variable)
|
||||
(Defaults to the GHIDRA_INSTALL_DIR environment variable or "lastrun" file)
|
||||
:raises ValueError: If the provided language, compiler or loader is invalid.
|
||||
:raises TypeError: If the provided loader does not implement `ghidra.app.util.opinion.Loader`.
|
||||
"""
|
||||
|
@ -378,7 +378,7 @@ def run_script(
|
|||
This may be either a Java class or its path. (Defaults to None)
|
||||
:param install_dir: The path to the Ghidra installation directory. This parameter is only
|
||||
used if Ghidra has not been started yet.
|
||||
(Defaults to the GHIDRA_INSTALL_DIR environment variable)
|
||||
(Defaults to the GHIDRA_INSTALL_DIR environment variable or "lastrun" file)
|
||||
:param program_name: The name of the program to open in Ghidra.
|
||||
(Defaults to None, which results in the name being derived from "binary_path")
|
||||
:param nested_project_location: If True, assumes "project_location" contains an extra nested
|
||||
|
|
|
@ -152,6 +152,29 @@ def _plugin_lock():
|
|||
# it will be removed by said process when done
|
||||
pass
|
||||
|
||||
def _lastrun() -> Path:
|
||||
|
||||
lastrun_file: Path = None
|
||||
lastrun_rel: Path = Path('ghidra/lastrun')
|
||||
|
||||
# Check for XDG_CONFIG_HOME environment variable
|
||||
xdg_config_home: str = os.environ.get('XDG_CONFIG_HOME')
|
||||
if xdg_config_home:
|
||||
lastrun_file = Path(xdg_config_home) / lastrun_rel
|
||||
else:
|
||||
# Default to platform-specific locations
|
||||
if platform.system() == 'Windows':
|
||||
lastrun_file = Path(os.environ['APPDATA']) / lastrun_rel
|
||||
elif platform.system() == 'Darwin':
|
||||
lastrun_file = Path.home() / 'Library' / lastrun_rel
|
||||
else:
|
||||
lastrun_file = Path.home() / '.config' / lastrun_rel
|
||||
|
||||
if lastrun_file is not None and lastrun_file.is_file():
|
||||
with open(lastrun_file, "r") as file:
|
||||
return Path(file.readline().strip())
|
||||
|
||||
return None
|
||||
|
||||
class PyGhidraLauncher:
|
||||
"""
|
||||
|
@ -164,7 +187,7 @@ class PyGhidraLauncher:
|
|||
|
||||
:param verbose: True to enable verbose output when starting Ghidra.
|
||||
:param install_dir: Ghidra installation directory.
|
||||
(Defaults to the GHIDRA_INSTALL_DIR environment variable)
|
||||
(Defaults to the GHIDRA_INSTALL_DIR environment variable or "lastrun" file)
|
||||
:raises ValueError: If the Ghidra installation directory is invalid.
|
||||
"""
|
||||
self._layout = None
|
||||
|
@ -173,7 +196,7 @@ class PyGhidraLauncher:
|
|||
self._dev_mode = False
|
||||
self._extension_path = None
|
||||
|
||||
install_dir = install_dir or os.getenv("GHIDRA_INSTALL_DIR")
|
||||
install_dir = install_dir or os.getenv("GHIDRA_INSTALL_DIR") or _lastrun()
|
||||
self._install_dir = self._validate_install_dir(install_dir)
|
||||
|
||||
java_home_override = os.getenv("JAVA_HOME_OVERRIDE")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue