Renaming Pyhidra to PyGhidra

This commit is contained in:
Ryan Kurtz
2024-09-05 10:35:28 -04:00
committed by DC3-TSD
parent 92d0f1dacf
commit 5b81139197
78 changed files with 370 additions and 629 deletions
@@ -65,7 +65,7 @@ public class VSCodeProjectScript extends GhidraScript {
writeSettings(installDir, projectDir, classpathSourceMap); writeSettings(installDir, projectDir, classpathSourceMap);
writeLaunch(installDir, projectDir, classpathSourceMap); writeLaunch(installDir, projectDir, classpathSourceMap);
writeSampleScriptJava(projectDir); writeSampleScriptJava(projectDir);
writeSampleScriptPyhidra(projectDir); writeSampleScriptPyGhidra(projectDir);
writeSampleModule(installDir, projectDir); writeSampleModule(installDir, projectDir);
println("Successfully created VSCode project directory at: " + projectDir); println("Successfully created VSCode project directory at: " + projectDir);
@@ -228,13 +228,13 @@ public class VSCodeProjectScript extends GhidraScript {
FileUtils.writeStringToFile(scriptFile, sampleScript, StandardCharsets.UTF_8); FileUtils.writeStringToFile(scriptFile, sampleScript, StandardCharsets.UTF_8);
} }
private void writeSampleScriptPyhidra(File projectDir) throws IOException { private void writeSampleScriptPyGhidra(File projectDir) throws IOException {
File scriptsDir = new File(projectDir, "ghidra_scripts"); File scriptsDir = new File(projectDir, "ghidra_scripts");
File scriptFile = new File(scriptsDir, "sample_script.py"); File scriptFile = new File(scriptsDir, "sample_script.py");
String sampleScript = """ String sampleScript = """
# Sample Pyhidra GhidraScript # Sample PyGhidra GhidraScript
# @category Examples # @category Examples
# @runtime Pyhidra # @runtime PyGhidra
from java.util import LinkedList from java.util import LinkedList
java_list = LinkedList([1,2,3]) java_list = LinkedList([1,2,3])
@@ -2,7 +2,7 @@
<launchConfiguration type="org.eclipse.jdt.launching.remoteJavaApplication"> <launchConfiguration type="org.eclipse.jdt.launching.remoteJavaApplication">
<booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/> <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/Features Pyhidra"/> <listEntry value="/Features PyGhidra"/>
</listAttribute> </listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/> <listEntry value="4"/>
@@ -12,6 +12,6 @@
<mapEntry key="hostname" value="localhost"/> <mapEntry key="hostname" value="localhost"/>
<mapEntry key="port" value="18001"/> <mapEntry key="port" value="18001"/>
</mapAttribute> </mapAttribute>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="Features Pyhidra"/> <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="Features PyGhidra"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_CONNECTOR_ID" value="org.eclipse.jdt.launching.socketAttachConnector"/> <stringAttribute key="org.eclipse.jdt.launching.VM_CONNECTOR_ID" value="org.eclipse.jdt.launching.socketAttachConnector"/>
</launchConfiguration> </launchConfiguration>
@@ -5,7 +5,7 @@
<booleanAttribute key="org.eclipse.debug.core.launchGroup.0.adoptIfRunning" value="false"/> <booleanAttribute key="org.eclipse.debug.core.launchGroup.0.adoptIfRunning" value="false"/>
<booleanAttribute key="org.eclipse.debug.core.launchGroup.0.enabled" value="true"/> <booleanAttribute key="org.eclipse.debug.core.launchGroup.0.enabled" value="true"/>
<stringAttribute key="org.eclipse.debug.core.launchGroup.0.mode" value="debug"/> <stringAttribute key="org.eclipse.debug.core.launchGroup.0.mode" value="debug"/>
<stringAttribute key="org.eclipse.debug.core.launchGroup.0.name" value="_Pyhidra GUI Debug"/> <stringAttribute key="org.eclipse.debug.core.launchGroup.0.name" value="_PyGhidra GUI Debug"/>
<stringAttribute key="org.eclipse.debug.core.launchGroup.1.action" value="NONE"/> <stringAttribute key="org.eclipse.debug.core.launchGroup.1.action" value="NONE"/>
<booleanAttribute key="org.eclipse.debug.core.launchGroup.1.adoptIfRunning" value="true"/> <booleanAttribute key="org.eclipse.debug.core.launchGroup.1.adoptIfRunning" value="true"/>
<booleanAttribute key="org.eclipse.debug.core.launchGroup.1.enabled" value="true"/> <booleanAttribute key="org.eclipse.debug.core.launchGroup.1.enabled" value="true"/>
@@ -2,7 +2,7 @@
<launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType"> <launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType">
<booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/> <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/Features Pyhidra/src/main/py/src/pyhidra"/> <listEntry value="/Features PyGhidra/src/main/py/src/pyghidra"/>
</listAttribute> </listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="2"/> <listEntry value="2"/>
@@ -14,11 +14,11 @@
<listAttribute key="org.eclipse.debug.ui.favoriteGroups"> <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/> <listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
</listAttribute> </listAttribute>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:Features Pyhidra/src/main/py/src/pyhidra}"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:Features PyGhidra/src/main/py/src/pyghidra}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value="${workspace_loc:Features Pyhidra/src/main/py/src/pyhidra}"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value="${workspace_loc:Features PyGhidra/src/main/py/src/pyghidra}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-v&#13;&#10;-g"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-v&#13;&#10;-g"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:Features Pyhidra/src/main/py/src/pyhidra}"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:Features PyGhidra/src/main/py/src/pyghidra}"/>
<stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/> <stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/>
<stringAttribute key="org.python.pydev.debug.ATTR_PROJECT" value="Features Pyhidra"/> <stringAttribute key="org.python.pydev.debug.ATTR_PROJECT" value="Features PyGhidra"/>
<stringAttribute key="process_factory_id" value="org.python.pydev.debug.processfactory.PyProcessFactory"/> <stringAttribute key="process_factory_id" value="org.python.pydev.debug.processfactory.PyProcessFactory"/>
</launchConfiguration> </launchConfiguration>
@@ -5,7 +5,7 @@
<booleanAttribute key="org.eclipse.debug.core.launchGroup.0.adoptIfRunning" value="false"/> <booleanAttribute key="org.eclipse.debug.core.launchGroup.0.adoptIfRunning" value="false"/>
<booleanAttribute key="org.eclipse.debug.core.launchGroup.0.enabled" value="true"/> <booleanAttribute key="org.eclipse.debug.core.launchGroup.0.enabled" value="true"/>
<stringAttribute key="org.eclipse.debug.core.launchGroup.0.mode" value="debug"/> <stringAttribute key="org.eclipse.debug.core.launchGroup.0.mode" value="debug"/>
<stringAttribute key="org.eclipse.debug.core.launchGroup.0.name" value="_Pyhidra Interpreter Debug"/> <stringAttribute key="org.eclipse.debug.core.launchGroup.0.name" value="_PyGhidra Interpreter Debug"/>
<stringAttribute key="org.eclipse.debug.core.launchGroup.1.action" value="NONE"/> <stringAttribute key="org.eclipse.debug.core.launchGroup.1.action" value="NONE"/>
<booleanAttribute key="org.eclipse.debug.core.launchGroup.1.adoptIfRunning" value="true"/> <booleanAttribute key="org.eclipse.debug.core.launchGroup.1.adoptIfRunning" value="true"/>
<booleanAttribute key="org.eclipse.debug.core.launchGroup.1.enabled" value="true"/> <booleanAttribute key="org.eclipse.debug.core.launchGroup.1.enabled" value="true"/>
@@ -2,7 +2,7 @@
<launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType"> <launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType">
<booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/> <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/Features Pyhidra/src/main/py/src/pyhidra"/> <listEntry value="/Features PyGhidra/src/main/py/src/pyghidra"/>
</listAttribute> </listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="2"/> <listEntry value="2"/>
@@ -14,11 +14,11 @@
<listAttribute key="org.eclipse.debug.ui.favoriteGroups"> <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/> <listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
</listAttribute> </listAttribute>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:Features Pyhidra/src/main/py/src/pyhidra}"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:Features PyGhidra/src/main/py/src/pyghidra}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value="${workspace_loc:Features Pyhidra/src/main/py/src/pyhidra}"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value="${workspace_loc:Features PyGhidra/src/main/py/src/pyghidra}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-v"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-v"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:Features Pyhidra/src/main/py/src/pyhidra}"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:Features PyGhidra/src/main/py/src/pyghidra}"/>
<stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/> <stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/>
<stringAttribute key="org.python.pydev.debug.ATTR_PROJECT" value="Features Pyhidra"/> <stringAttribute key="org.python.pydev.debug.ATTR_PROJECT" value="Features PyGhidra"/>
<stringAttribute key="process_factory_id" value="org.python.pydev.debug.processfactory.PyProcessFactory"/> <stringAttribute key="process_factory_id" value="org.python.pydev.debug.processfactory.PyProcessFactory"/>
</launchConfiguration> </launchConfiguration>
@@ -2,7 +2,7 @@
<launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType"> <launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType">
<booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/> <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/Features Pyhidra/src/main/py/src/pyhidra"/> <listEntry value="/Features PyGhidra/src/main/py/src/pyghidra"/>
</listAttribute> </listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="2"/> <listEntry value="2"/>
@@ -10,13 +10,13 @@
<mapAttribute key="org.eclipse.debug.core.environmentVariables"> <mapAttribute key="org.eclipse.debug.core.environmentVariables">
<mapEntry key="GHIDRA_INSTALL_DIR" value="${project_loc:/___root}"/> <mapEntry key="GHIDRA_INSTALL_DIR" value="${project_loc:/___root}"/>
<mapEntry key="JAVA_HOME_OVERRIDE" value="${ee_home:JavaSE-21}"/> <mapEntry key="JAVA_HOME_OVERRIDE" value="${ee_home:JavaSE-21}"/>
<mapEntry key="PYHIDRA_DEBUG" value="1"/> <mapEntry key="PYGHIDRA_DEBUG" value="1"/>
</mapAttribute> </mapAttribute>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:Features Pyhidra/src/main/py/src/pyhidra}"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:Features PyGhidra/src/main/py/src/pyghidra}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value="${workspace_loc:Features Pyhidra/src/main/py/src/pyhidra}"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value="${workspace_loc:Features PyGhidra/src/main/py/src/pyghidra}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-v&#13;&#10;-g"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-v&#13;&#10;-g"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:Features Pyhidra/src/main/py/src/pyhidra}"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:Features PyGhidra/src/main/py/src/pyghidra}"/>
<stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/> <stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/>
<stringAttribute key="org.python.pydev.debug.ATTR_PROJECT" value="Features Pyhidra"/> <stringAttribute key="org.python.pydev.debug.ATTR_PROJECT" value="Features PyGhidra"/>
<stringAttribute key="process_factory_id" value="org.python.pydev.debug.processfactory.PyProcessFactory"/> <stringAttribute key="process_factory_id" value="org.python.pydev.debug.processfactory.PyProcessFactory"/>
</launchConfiguration> </launchConfiguration>
@@ -2,7 +2,7 @@
<launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType"> <launchConfiguration type="org.python.pydev.debug.regularLaunchConfigurationType">
<booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/> <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/Features Pyhidra/src/main/py/src/pyhidra"/> <listEntry value="/Features PyGhidra/src/main/py/src/pyghidra"/>
</listAttribute> </listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="2"/> <listEntry value="2"/>
@@ -10,13 +10,13 @@
<mapAttribute key="org.eclipse.debug.core.environmentVariables"> <mapAttribute key="org.eclipse.debug.core.environmentVariables">
<mapEntry key="GHIDRA_INSTALL_DIR" value="${project_loc:/___root}"/> <mapEntry key="GHIDRA_INSTALL_DIR" value="${project_loc:/___root}"/>
<mapEntry key="JAVA_HOME_OVERRIDE" value="${ee_home:JavaSE-21}"/> <mapEntry key="JAVA_HOME_OVERRIDE" value="${ee_home:JavaSE-21}"/>
<mapEntry key="PYHIDRA_DEBUG" value="1"/> <mapEntry key="PYGHIDRA_DEBUG" value="1"/>
</mapAttribute> </mapAttribute>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:Features Pyhidra/src/main/py/src/pyhidra}"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:Features PyGhidra/src/main/py/src/pyghidra}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value="${workspace_loc:Features Pyhidra/src/main/py/src/pyhidra}"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_OTHER_WORKING_DIRECTORY" value="${workspace_loc:Features PyGhidra/src/main/py/src/pyghidra}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-v"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-v"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:Features Pyhidra/src/main/py/src/pyhidra}"/> <stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:Features PyGhidra/src/main/py/src/pyghidra}"/>
<stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/> <stringAttribute key="org.python.pydev.debug.ATTR_INTERPRETER" value="__default"/>
<stringAttribute key="org.python.pydev.debug.ATTR_PROJECT" value="Features Pyhidra"/> <stringAttribute key="org.python.pydev.debug.ATTR_PROJECT" value="Features PyGhidra"/>
<stringAttribute key="process_factory_id" value="org.python.pydev.debug.processfactory.PyProcessFactory"/> <stringAttribute key="process_factory_id" value="org.python.pydev.debug.processfactory.PyProcessFactory"/>
</launchConfiguration> </launchConfiguration>
@@ -22,7 +22,7 @@ apply from: "$rootProject.projectDir/gradle/javadoc.gradle"
apply from: "${rootProject.projectDir}/gradle/hasPythonPackage.gradle" apply from: "${rootProject.projectDir}/gradle/hasPythonPackage.gradle"
apply plugin: 'eclipse' apply plugin: 'eclipse'
eclipse.project.name = 'Features Pyhidra' eclipse.project.name = 'Features PyGhidra'
dependencies { dependencies {
@@ -53,28 +53,28 @@ distributePyDep("setuptools-68.0.0-py3-none-any.whl")
task installJPype(type: Exec) { task installJPype(type: Exec) {
dependsOn(":createPythonVirtualEnvironment") dependsOn(":createPythonVirtualEnvironment")
File depsDir = file("${DEPS_DIR}/Pyhidra") File depsDir = file("${DEPS_DIR}/PyGhidra")
File binRepoDir = file("${BIN_REPO}/Ghidra/Features/Pyhidra") File binRepoDir = file("${BIN_REPO}/Ghidra/Features/PyGhidra")
def dir = depsDir.exists() ? depsDir : binRepoDir def dir = depsDir.exists() ? depsDir : binRepoDir
commandLine "$PYTHON3_VENV", "-m", "pip", "install", "--no-index", "-f", "$dir", "JPype1" commandLine "$PYTHON3_VENV", "-m", "pip", "install", "--no-index", "-f", "$dir", "JPype1"
} }
// Install Pyhidra in editable mode to the development virtual environment // Install PyGhidra in editable mode to the development virtual environment
task installEditablePyhidra(type: Exec) { task installEditablePyGhidra(type: Exec) {
dependsOn("installJPype") dependsOn("installJPype")
commandLine "$PYTHON3_VENV", "-m", "pip", "install", "-e", "src/main/py" commandLine "$PYTHON3_VENV", "-m", "pip", "install", "-e", "src/main/py"
} }
rootProject.prepDev.dependsOn installEditablePyhidra rootProject.prepDev.dependsOn installEditablePyGhidra
// Add pyhidraLauncher.py to the release // Add pyghidra_launcher.py to the release
rootProject.assembleDistribution { rootProject.assembleDistribution {
dependsOn(buildPyPackage) dependsOn(buildPyPackage)
def p = this.project def p = this.project
def zipPath = getZipPath(p) def zipPath = getZipPath(p)
from (this.project.projectDir.toString()) { from (this.project.projectDir.toString()) {
include "pyhidraLauncher.py" include "pyghidra_launcher.py"
into { zipPath } into { zipPath }
} }
} }
@@ -3,5 +3,5 @@
Module.manifest||GHIDRA||||END| Module.manifest||GHIDRA||||END|
data/python.theme.properties||GHIDRA||||END| data/python.theme.properties||GHIDRA||||END|
src/main/help/help/TOC_Source.xml||GHIDRA||||END| src/main/help/help/TOC_Source.xml||GHIDRA||||END|
src/main/help/help/topics/Pyhidra/interpreter.html||GHIDRA||||END| src/main/help/help/topics/PyGhidra/interpreter.html||GHIDRA||||END|
src/main/resources/images/python.png||GHIDRA||||END| src/main/resources/images/python.png||GHIDRA||||END|
@@ -1,6 +1,6 @@
# Examples of Pyhidra-specific functionality # Examples of PyGhidra-specific functionality
# @category: Examples.Python # @category: Examples.Python
# @runtime Pyhidra # @runtime PyGhidra
# we can import java libraries just as if they were python libraries # we can import java libraries just as if they were python libraries
@@ -6,16 +6,16 @@ from pathlib import Path
from typing import List from typing import List
from sys import stderr from sys import stderr
def upgrade(pip_args: List[str], dist_dir: Path, current_pyhidra_version: str) -> bool: def upgrade(pip_args: List[str], dist_dir: Path, current_pyghidra_version: str) -> bool:
from packaging.version import Version # if pyhidra imported, we know we have packaging from packaging.version import Version # if pyghidra imported, we know we have packaging
included_pyhidra: Path = next(dist_dir.glob('pyhidra-*.whl'), None) included_pyghidra: Path = next(dist_dir.glob('pyghidra-*.whl'), None)
if included_pyhidra is None: if included_pyghidra is None:
print('Warning: included pyhidra wheel was not found', file=sys.stderr) print('Warning: included pyghidra wheel was not found', file=sys.stderr)
return return
included_version: Version = Version(included_pyhidra.name.split('-')[1]) included_version: Version = Version(included_pyghidra.name.split('-')[1])
current_version: Version = Version(current_pyhidra_version) current_version: Version = Version(current_pyghidra_version)
if included_version > current_version: if included_version > current_version:
choice: str = input(f'Do you wish to upgrade Pyhidra {current_version} to {included_version} (y/n)? ') choice: str = input(f'Do you wish to upgrade PyGhidra {current_version} to {included_version} (y/n)? ')
if choice.lower() in ('y', 'yes'): if choice.lower() in ('y', 'yes'):
pip_args.append('-U') pip_args.append('-U')
subprocess.check_call(pip_args) subprocess.check_call(pip_args)
@@ -25,7 +25,7 @@ def upgrade(pip_args: List[str], dist_dir: Path, current_pyhidra_version: str) -
return False return False
def install(pip_args: List[str], dist_dir: Path) -> bool: def install(pip_args: List[str], dist_dir: Path) -> bool:
choice: str = input('Do you wish to install Pyhidra (y/n)? ') choice: str = input('Do you wish to install PyGhidra (y/n)? ')
if choice.lower() in ('y', 'yes'): if choice.lower() in ('y', 'yes'):
subprocess.check_call(pip_args) subprocess.check_call(pip_args)
return True return True
@@ -48,16 +48,16 @@ def main() -> None:
python_cmd: str = sys.executable python_cmd: str = sys.executable
install_dir: Path = Path(args.install_dir) install_dir: Path = Path(args.install_dir)
venv_dir: Path = install_dir / 'build' / 'venv' venv_dir: Path = install_dir / 'build' / 'venv'
pyhidra_dir: Path = install_dir / 'Ghidra' / 'Features' / 'Pyhidra' pyghidra_dir: Path = install_dir / 'Ghidra' / 'Features' / 'PyGhidra'
src_dir: Path = pyhidra_dir / 'src' / 'main' / 'py' src_dir: Path = pyghidra_dir / 'src' / 'main' / 'py'
dist_dir: Path = pyhidra_dir / 'pypkg' / 'dist' dist_dir: Path = pyghidra_dir / 'pypkg' / 'dist'
# If headless, force console mode # If headless, force console mode
if args.headless: if args.headless:
args.console = True args.console = True
if args.dev: if args.dev:
# If in dev mode, launch pyhidra from the source tree using the development virtual environment # If in dev mode, launch PyGhidra from the source tree using the development virtual environment
if not venv_dir.is_dir(): if not venv_dir.is_dir():
print('Virtual environment not found!') print('Virtual environment not found!')
print('Run "gradle prepdev" and try again.') print('Run "gradle prepdev" and try again.')
@@ -66,17 +66,17 @@ def main() -> None:
linux_python_cmd = str(venv_dir / 'bin' / 'python3') linux_python_cmd = str(venv_dir / 'bin' / 'python3')
python_cmd = win_python_cmd if os.name == 'nt' else linux_python_cmd python_cmd = win_python_cmd if os.name == 'nt' else linux_python_cmd
else: else:
# If in release mode, offer to install or upgrade pyhidra before launching from user-controlled environment # If in release mode, offer to install or upgrade PyGhidra before launching from user-controlled environment
pip_args: List[str] = [python_cmd, '-m', 'pip', 'install', '--no-index', '-f', str(dist_dir), 'pyhidra'] pip_args: List[str] = [python_cmd, '-m', 'pip', 'install', '--no-index', '-f', str(dist_dir), 'pyghidra']
try: try:
import pyhidra import pyghidra
upgrade(pip_args, dist_dir, pyhidra.__version__) upgrade(pip_args, dist_dir, pyghidra.__version__)
except ImportError: except ImportError:
if not install(pip_args, dist_dir): if not install(pip_args, dist_dir):
return return
# Launch Pyhidra # Launch PyGhidra
py_args: List[str] = [python_cmd, '-m', 'pyhidra.ghidra_launch', '--install-dir', str(install_dir)] py_args: List[str] = [python_cmd, '-m', 'pyghidra.ghidra_launch', '--install-dir', str(install_dir)]
if args.headless: if args.headless:
py_args += ['ghidra.app.util.headless.AnalyzeHeadless'] py_args += ['ghidra.app.util.headless.AnalyzeHeadless']
else: else:
@@ -86,6 +86,6 @@ def main() -> None:
else: else:
creation_flags = getattr(subprocess, 'CREATE_NO_WINDOW', 0) creation_flags = getattr(subprocess, 'CREATE_NO_WINDOW', 0)
subprocess.Popen(py_args + remaining, creationflags=creation_flags, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) subprocess.Popen(py_args + remaining, creationflags=creation_flags, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
if __name__ == "__main__": if __name__ == "__main__":
main() main()
@@ -3,7 +3,7 @@
<tocroot> <tocroot>
<tocref id="Ghidra Functionality"> <tocref id="Ghidra Functionality">
<tocref id="Scripting"> <tocref id="Scripting">
<tocdef id="Pyhidra Interpreter" sortgroup="z" text="Pyhidra Interpreter" target="help/topics/Pyhidra/interpreter.html" /> <tocdef id="PyGhidra Interpreter" sortgroup="z" text="PyGhidra Interpreter" target="help/topics/PyGhidra/interpreter.html" />
</tocref> </tocref>
</tocref> </tocref>
</tocroot> </tocroot>
@@ -2,15 +2,15 @@
<HTML> <HTML>
<HEAD> <HEAD>
<TITLE>Pyhidra Interpreter</TITLE> <TITLE>PyGhidra Interpreter</TITLE>
<LINK rel="stylesheet" type="text/css" href="help/shared/DefaultStyle.css"> <LINK rel="stylesheet" type="text/css" href="help/shared/DefaultStyle.css">
</HEAD> </HEAD>
<BODY lang="EN-US"> <BODY lang="EN-US">
<H1><A name="Pyhidra"></A>Pyhidra Interpreter</H1> <H1><A name="PyGhidra"></A>PyGhidra Interpreter</H1>
<P> <P>
The Ghidra <I>Pyhidra Interpreter</I> provides a full general-purpose Python interactive shell The Ghidra <I>PyGhidra Interpreter</I> provides a full general-purpose Python interactive shell
and allows you to interact with your current Ghidra session by exposing Ghidra's powerful Java and allows you to interact with your current Ghidra session by exposing Ghidra's powerful Java
API through the magic of Jpype. API through the magic of Jpype.
</P> </P>
@@ -18,7 +18,7 @@
<H2>Environment</H2> <H2>Environment</H2>
<BLOCKQUOTE> <BLOCKQUOTE>
<P> <P>
The Ghidra <I>Pyhidra Interpreter</I> is configured to run in a similar context as a Ghidra The Ghidra <I>PyGhidra Interpreter</I> is configured to run in a similar context as a Ghidra
script. Therefore, you immediately have access to variables such as <TT>currentProgram</TT>, script. Therefore, you immediately have access to variables such as <TT>currentProgram</TT>,
<TT>currentSelection</TT>, <TT>currentAddress</TT>, etc without needing to import them. <TT>currentSelection</TT>, <TT>currentAddress</TT>, etc without needing to import them.
These variables exist as Java objects behind the scenes, but Jpype allows you to interact with These variables exist as Java objects behind the scenes, but Jpype allows you to interact with
@@ -78,7 +78,7 @@
<H2>Keybindings</H2> <H2>Keybindings</H2>
<BLOCKQUOTE> <BLOCKQUOTE>
<P> <P>
The Ghidra <I>Pyhidra Interpreter</I> supports the following hard-coded keybindings: The Ghidra <I>PyGhidra Interpreter</I> supports the following hard-coded keybindings:
<UL> <UL>
<LI><B>(up):</B>&nbsp;&nbsp;Move backward in command stack</LI> <LI><B>(up):</B>&nbsp;&nbsp;Move backward in command stack</LI>
<LI><B>(down):</B>&nbsp;&nbsp;Move forward in command stack</LI> <LI><B>(down):</B>&nbsp;&nbsp;Move forward in command stack</LI>
@@ -100,7 +100,7 @@
<H2>Copy/Paste</H2> <H2>Copy/Paste</H2>
<BLOCKQUOTE> <BLOCKQUOTE>
<P> <P>
Copy and paste from within the Ghidra <I>Pyhidra Interpreter</I> should work as expected for Copy and paste from within the Ghidra <I>PyGhidra Interpreter</I> should work as expected for
your given environment: your given environment:
<UL> <UL>
<LI><B>Windows:</B>&nbsp;&nbsp;CTRL+C / CTRL+V</LI> <LI><B>Windows:</B>&nbsp;&nbsp;CTRL+C / CTRL+V</LI>
@@ -113,7 +113,7 @@
<H2>API Documentation</H2> <H2>API Documentation</H2>
<BLOCKQUOTE> <BLOCKQUOTE>
<P> <P>
The built-in <TT>help()</TT> Python function has been altered by the Ghidra <I>Pyhidra Interpreter</I> The built-in <TT>help()</TT> Python function has been altered by the Ghidra <I>PyGhidra Interpreter</I>
to add support for displaying Ghidra's Javadoc (where available) for a given Ghidra class, method, to add support for displaying Ghidra's Javadoc (where available) for a given Ghidra class, method,
or variable. For example, to see Ghidra's Javadoc on the <TT>state</TT> variable, simply do: or variable. For example, to see Ghidra's Javadoc on the <TT>state</TT> variable, simply do:
<PRE> <PRE>
@@ -156,7 +156,7 @@
</P> </P>
</BLOCKQUOTE> </BLOCKQUOTE>
<P align="left" class="providedbyplugin">Provided by: <I>PyhidraPlugin</I></P> <P align="left" class="providedbyplugin">Provided by: <I>PyGhidraPlugin</I></P>
<P>&nbsp;</P> <P>&nbsp;</P>
<BR> <BR>
@@ -1,11 +1,11 @@
package ghidra.pyhidra; package ghidra.pyghidra;
import java.util.function.Consumer; import java.util.function.Consumer;
import ghidra.app.CorePluginPackage; import ghidra.app.CorePluginPackage;
import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.PluginCategoryNames;
import ghidra.app.plugin.ProgramPlugin; import ghidra.app.plugin.ProgramPlugin;
import ghidra.app.plugin.core.interpreter.*; import ghidra.app.plugin.core.interpreter.InterpreterPanelService;
import ghidra.app.script.GhidraState; import ghidra.app.script.GhidraState;
import ghidra.framework.plugintool.PluginInfo; import ghidra.framework.plugintool.PluginInfo;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
@@ -13,8 +13,8 @@ import ghidra.framework.plugintool.util.PluginStatus;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
import ghidra.pyhidra.interpreter.InterpreterGhidraScript; import ghidra.pyghidra.interpreter.InterpreterGhidraScript;
import ghidra.pyhidra.interpreter.PyhidraInterpreter; import ghidra.pyghidra.interpreter.PyGhidraInterpreter;
import ghidra.util.exception.AssertException; import ghidra.util.exception.AssertException;
/** /**
@@ -25,20 +25,20 @@ import ghidra.util.exception.AssertException;
status = PluginStatus.RELEASED, status = PluginStatus.RELEASED,
packageName = CorePluginPackage.NAME, packageName = CorePluginPackage.NAME,
category = PluginCategoryNames.COMMON, category = PluginCategoryNames.COMMON,
shortDescription = "Pyhidra Interpreter", shortDescription = "PyGhidra Interpreter",
description = "Provides an interactive Python Interpreter that is tightly integrated with a loaded Ghidra program.", description = "Provides an interactive Python Interpreter that is tightly integrated with a loaded Ghidra program.",
servicesRequired = { InterpreterPanelService.class } servicesRequired = { InterpreterPanelService.class }
) )
//@formatter:on //@formatter:on
public class PyhidraPlugin extends ProgramPlugin { public class PyGhidraPlugin extends ProgramPlugin {
public static final String TITLE = "Pyhidra"; public static final String TITLE = "PyGhidra";
private static Consumer<PyhidraPlugin> initializer = null; private static Consumer<PyGhidraPlugin> initializer = null;
public final InterpreterGhidraScript script = new InterpreterGhidraScript(); public final InterpreterGhidraScript script = new InterpreterGhidraScript();
public PyhidraInterpreter interpreter; public PyGhidraInterpreter interpreter;
public PyhidraPlugin(PluginTool tool) { public PyGhidraPlugin(PluginTool tool) {
super(tool); super(tool);
GhidraState state = new GhidraState(tool, tool.getProject(), null, null, null, null); GhidraState state = new GhidraState(tool, tool.getProject(), null, null, null, null);
// use the copy constructor so this state doesn't fire plugin events // use the copy constructor so this state doesn't fire plugin events
@@ -54,16 +54,16 @@ public class PyhidraPlugin extends ProgramPlugin {
* @param initializer the Python side initializer * @param initializer the Python side initializer
* @throws AssertException if the code completer has already been set * @throws AssertException if the code completer has already been set
*/ */
public static void setInitializer(Consumer<PyhidraPlugin> initializer) { public static void setInitializer(Consumer<PyGhidraPlugin> initializer) {
if (PyhidraPlugin.initializer != null) { if (PyGhidraPlugin.initializer != null) {
throw new AssertException("PyhidraPlugin initializer has already been set"); throw new AssertException("PyGhidraPlugin initializer has already been set");
} }
PyhidraPlugin.initializer = initializer; PyGhidraPlugin.initializer = initializer;
} }
@Override @Override
public void init() { public void init() {
interpreter = new PyhidraInterpreter(this, PyhidraPlugin.initializer != null); interpreter = new PyGhidraInterpreter(this, PyGhidraPlugin.initializer != null);
if (initializer != null) { if (initializer != null) {
initializer.accept(this); initializer.accept(this);
} }
@@ -1,6 +1,6 @@
package ghidra.pyhidra; package ghidra.pyghidra;
import java.io.*; import java.io.PrintWriter;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.util.List; import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -12,15 +12,15 @@ import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
import ghidra.pyhidra.PythonFieldExposer.ExposedFields; import ghidra.pyghidra.PythonFieldExposer.ExposedFields;
import ghidra.util.exception.AssertException;
import ghidra.util.SystemUtilities; import ghidra.util.SystemUtilities;
import ghidra.util.exception.AssertException;
import ghidra.util.task.TaskMonitor; import ghidra.util.task.TaskMonitor;
/** /**
* {@link GhidraScript} provider for native python3 scripts * {@link GhidraScript} provider for native python3 scripts
*/ */
public final class PyhidraScriptProvider extends AbstractPythonScriptProvider { public final class PyGhidraScriptProvider extends AbstractPythonScriptProvider {
private static Consumer<GhidraScript> scriptRunner = null; private static Consumer<GhidraScript> scriptRunner = null;
@@ -34,37 +34,37 @@ public final class PyhidraScriptProvider extends AbstractPythonScriptProvider {
* @throws AssertException if the script runner has already been set * @throws AssertException if the script runner has already been set
*/ */
public static void setScriptRunner(Consumer<GhidraScript> scriptRunner) { public static void setScriptRunner(Consumer<GhidraScript> scriptRunner) {
if (PyhidraScriptProvider.scriptRunner != null) { if (PyGhidraScriptProvider.scriptRunner != null) {
throw new AssertException("scriptRunner has already been set"); throw new AssertException("scriptRunner has already been set");
} }
PyhidraScriptProvider.scriptRunner = scriptRunner; PyGhidraScriptProvider.scriptRunner = scriptRunner;
} }
@Override @Override
public String getDescription() { public String getDescription() {
return PyhidraPlugin.TITLE; return PyGhidraPlugin.TITLE;
} }
@Override @Override
public String getRuntimeEnvironmentName() { public String getRuntimeEnvironmentName() {
return PyhidraPlugin.TITLE; return PyGhidraPlugin.TITLE;
} }
@Override @Override
public GhidraScript getScriptInstance(ResourceFile sourceFile, PrintWriter writer) public GhidraScript getScriptInstance(ResourceFile sourceFile, PrintWriter writer)
throws GhidraScriptLoadException { throws GhidraScriptLoadException {
if (scriptRunner == null) { if (scriptRunner == null) {
String msg = "Ghidra was not started with pyhidra. Python is not available"; String msg = "Ghidra was not started with PyGhidra. Python is not available";
throw new GhidraScriptLoadException(msg); throw new GhidraScriptLoadException(msg);
} }
GhidraScript script = SystemUtilities.isInHeadlessMode() ? new PyhidraHeadlessScript() GhidraScript script = SystemUtilities.isInHeadlessMode() ? new PyGhidraHeadlessScript()
: new PyhidraGhidraScript(); : new PyGhidraGhidraScript();
script.setSourceFile(sourceFile); script.setSourceFile(sourceFile);
return script; return script;
} }
@ExposedFields( @ExposedFields(
exposer = PyhidraGhidraScript.ExposedField.class, exposer = PyGhidraGhidraScript.ExposedField.class,
names = { names = {
"currentAddress", "currentLocation", "currentSelection", "currentAddress", "currentLocation", "currentSelection",
"currentHighlight", "currentProgram", "monitor", "currentHighlight", "currentProgram", "monitor",
@@ -78,7 +78,7 @@ public final class PyhidraScriptProvider extends AbstractPythonScriptProvider {
ResourceFile.class, GhidraState.class, PrintWriter.class ResourceFile.class, GhidraState.class, PrintWriter.class
} }
) )
final static class PyhidraGhidraScript extends GhidraScript final static class PyGhidraGhidraScript extends GhidraScript
implements PythonFieldExposer { implements PythonFieldExposer {
@Override @Override
@@ -92,13 +92,13 @@ public final class PyhidraScriptProvider extends AbstractPythonScriptProvider {
*/ */
private static class ExposedField extends PythonFieldExposer.ExposedField { private static class ExposedField extends PythonFieldExposer.ExposedField {
public ExposedField(String name, Class<?> type) { public ExposedField(String name, Class<?> type) {
super(MethodHandles.lookup().in(PyhidraGhidraScript.class), name, type); super(MethodHandles.lookup().in(PyGhidraGhidraScript.class), name, type);
} }
} }
} }
@ExposedFields( @ExposedFields(
exposer = PyhidraHeadlessScript.ExposedField.class, exposer = PyGhidraHeadlessScript.ExposedField.class,
names = { names = {
"currentAddress", "currentLocation", "currentSelection", "currentAddress", "currentLocation", "currentSelection",
"currentHighlight", "currentProgram", "monitor", "currentHighlight", "currentProgram", "monitor",
@@ -112,7 +112,7 @@ public final class PyhidraScriptProvider extends AbstractPythonScriptProvider {
ResourceFile.class, GhidraState.class, PrintWriter.class ResourceFile.class, GhidraState.class, PrintWriter.class
} }
) )
final static class PyhidraHeadlessScript extends HeadlessScript final static class PyGhidraHeadlessScript extends HeadlessScript
implements PythonFieldExposer { implements PythonFieldExposer {
@Override @Override
@@ -126,7 +126,7 @@ public final class PyhidraScriptProvider extends AbstractPythonScriptProvider {
*/ */
private static class ExposedField extends PythonFieldExposer.ExposedField { private static class ExposedField extends PythonFieldExposer.ExposedField {
public ExposedField(String name, Class<?> type) { public ExposedField(String name, Class<?> type) {
super(MethodHandles.lookup().in(PyhidraHeadlessScript.class), name, type); super(MethodHandles.lookup().in(PyGhidraHeadlessScript.class), name, type);
} }
} }
} }
@@ -1,4 +1,4 @@
package ghidra.pyhidra; package ghidra.pyghidra;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
@@ -21,8 +21,8 @@ import ghidra.util.exception.AssertException;
* This interface is for <b>internal use only</b> and is only public so it can be * This interface is for <b>internal use only</b> and is only public so it can be
* visible to Python to apply the Jpype class customizations. * visible to Python to apply the Jpype class customizations.
*/ */
public sealed interface PythonFieldExposer permits PyhidraScriptProvider.PyhidraGhidraScript, public sealed interface PythonFieldExposer permits PyGhidraScriptProvider.PyGhidraGhidraScript,
PyhidraScriptProvider.PyhidraHeadlessScript { PyGhidraScriptProvider.PyGhidraHeadlessScript {
/** /**
* Gets a mapping of all the explicitly exposed fields of a class. * Gets a mapping of all the explicitly exposed fields of a class.
@@ -1,13 +1,13 @@
package ghidra.pyhidra.interpreter; package ghidra.pyghidra.interpreter;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import ghidra.pyhidra.PyhidraPlugin;
import docking.ActionContext; import docking.ActionContext;
import docking.action.KeyBindingData; import docking.action.KeyBindingData;
import docking.action.DockingAction; import docking.action.DockingAction;
import docking.action.ToolBarData; import docking.action.ToolBarData;
import ghidra.pyghidra.PyGhidraPlugin;
import ghidra.util.HelpLocation; import ghidra.util.HelpLocation;
import resources.ResourceManager; import resources.ResourceManager;
@@ -15,10 +15,10 @@ import static docking.DockingUtils.CONTROL_KEY_MODIFIER_MASK;
final class CancelAction extends DockingAction { final class CancelAction extends DockingAction {
private final PyhidraConsole console; private final PyGhidraConsole console;
CancelAction(PyhidraConsole console) { CancelAction(PyGhidraConsole console) {
super("Cancel", PyhidraPlugin.class.getSimpleName()); super("Cancel", PyGhidraPlugin.class.getSimpleName());
this.console = console; this.console = console;
setDescription("Interrupt the interpreter"); setDescription("Interrupt the interpreter");
ImageIcon image = ResourceManager.loadImage("images/dialog-cancel.png"); ImageIcon image = ResourceManager.loadImage("images/dialog-cancel.png");
@@ -26,7 +26,7 @@ final class CancelAction extends DockingAction {
setEnabled(true); setEnabled(true);
KeyBindingData key = new KeyBindingData(KeyEvent.VK_I, CONTROL_KEY_MODIFIER_MASK); KeyBindingData key = new KeyBindingData(KeyEvent.VK_I, CONTROL_KEY_MODIFIER_MASK);
setKeyBindingData(key); setKeyBindingData(key);
setHelpLocation(new HelpLocation(PyhidraPlugin.TITLE, "Interrupt_Interpreter")); setHelpLocation(new HelpLocation(PyGhidraPlugin.TITLE, "Interrupt_Interpreter"));
} }
@Override @Override
@@ -1,4 +1,4 @@
package ghidra.pyhidra.interpreter; package ghidra.pyghidra.interpreter;
import java.io.PrintWriter; import java.io.PrintWriter;
@@ -10,11 +10,11 @@ import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
/** /**
* Custom {@link GhidraScript} only for use with the pyhidra interpreter console * Custom {@link GhidraScript} only for use with the PyGhidra interpreter console
*/ */
public final class InterpreterGhidraScript extends GhidraScript { public final class InterpreterGhidraScript extends GhidraScript {
// public default constructor for use by PyhidraPlugin // public default constructor for use by PyGhidraPlugin
// the default constructor for FlatProgramAPI has protected visibility // the default constructor for FlatProgramAPI has protected visibility
public InterpreterGhidraScript() { public InterpreterGhidraScript() {
} }
@@ -1,4 +1,4 @@
package ghidra.pyhidra.interpreter; package ghidra.pyghidra.interpreter;
import java.io.PrintWriter; import java.io.PrintWriter;
@@ -14,6 +14,6 @@ final class InterpreterTaskMonitor extends TaskMonitorAdapter {
@Override @Override
public void setMessage(String message) { public void setMessage(String message) {
output.println("<pyhidra-interactive>: " + message); output.println("<pyghidra-interactive>: " + message);
} }
} }
@@ -1,4 +1,4 @@
package ghidra.pyhidra.interpreter; package ghidra.pyghidra.interpreter;
import java.util.List; import java.util.List;
@@ -12,10 +12,10 @@ import ghidra.util.Disposable;
* This interface is for <b>internal use only</b> and is only public so it can be * This interface is for <b>internal use only</b> and is only public so it can be
* implemented in Python. * implemented in Python.
*/ */
public interface PyhidraConsole extends Disposable { public interface PyGhidraConsole extends Disposable {
/** /**
* Generates code completions for the pyhidra interpreter * Generates code completions for the PyGhidra interpreter
* *
* @param cmd The command to get code completions for * @param cmd The command to get code completions for
* @param caretPos The position of the caret in the input string 'cmd'. * @param caretPos The position of the caret in the input string 'cmd'.
@@ -26,12 +26,12 @@ public interface PyhidraConsole extends Disposable {
List<CodeCompletion> getCompletions(String cmd, int caretPos); List<CodeCompletion> getCompletions(String cmd, int caretPos);
/** /**
* Restarts the pyhidra console * Restarts the PyGhidra console
*/ */
void restart(); void restart();
/** /**
* Interrupts the code running in the pyhidra console * Interrupts the code running in the PyGhidra console
*/ */
void interrupt(); void interrupt();
} }
@@ -1,4 +1,4 @@
package ghidra.pyhidra.interpreter; package ghidra.pyghidra.interpreter;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.List; import java.util.List;
@@ -8,20 +8,20 @@ import ghidra.app.plugin.core.console.CodeCompletion;
import ghidra.app.plugin.core.interpreter.InterpreterConnection; import ghidra.app.plugin.core.interpreter.InterpreterConnection;
import ghidra.app.plugin.core.interpreter.InterpreterConsole; import ghidra.app.plugin.core.interpreter.InterpreterConsole;
import ghidra.app.plugin.core.interpreter.InterpreterPanelService; import ghidra.app.plugin.core.interpreter.InterpreterPanelService;
import ghidra.pyhidra.PyhidraPlugin; import ghidra.pyghidra.PyGhidraPlugin;
import ghidra.util.Disposable; import ghidra.util.Disposable;
import ghidra.util.exception.AssertException; import ghidra.util.exception.AssertException;
import resources.ResourceManager; import resources.ResourceManager;
/** /**
* The pyhidra interpreter connection * The PyGhidra interpreter connection
*/ */
public final class PyhidraInterpreter implements Disposable, InterpreterConnection { public final class PyGhidraInterpreter implements Disposable, InterpreterConnection {
private PyhidraConsole pyhidraConsole = null; private PyGhidraConsole pyghidraConsole = null;
public final InterpreterConsole console; public final InterpreterConsole console;
public PyhidraInterpreter(PyhidraPlugin plugin, boolean isPythonAvailable) { public PyGhidraInterpreter(PyGhidraPlugin plugin, boolean isPythonAvailable) {
InterpreterPanelService service = InterpreterPanelService service =
plugin.getTool().getService(InterpreterPanelService.class); plugin.getTool().getService(InterpreterPanelService.class);
console = service.createInterpreterPanel(this, false); console = service.createInterpreterPanel(this, false);
@@ -32,8 +32,8 @@ public final class PyhidraInterpreter implements Disposable, InterpreterConnecti
@Override @Override
public void dispose() { public void dispose() {
if (pyhidraConsole != null) { if (pyghidraConsole != null) {
pyhidraConsole.dispose(); pyghidraConsole.dispose();
} }
console.dispose(); console.dispose();
} }
@@ -45,7 +45,7 @@ public final class PyhidraInterpreter implements Disposable, InterpreterConnecti
@Override @Override
public String getTitle() { public String getTitle() {
return PyhidraPlugin.TITLE; return PyGhidraPlugin.TITLE;
} }
@Override @Override
@@ -55,20 +55,20 @@ public final class PyhidraInterpreter implements Disposable, InterpreterConnecti
@Override @Override
public List<CodeCompletion> getCompletions(String cmd, int caretPos) { public List<CodeCompletion> getCompletions(String cmd, int caretPos) {
if (pyhidraConsole == null) { if (pyghidraConsole == null) {
return List.of(); return List.of();
} }
return pyhidraConsole.getCompletions(cmd, caretPos); return pyghidraConsole.getCompletions(cmd, caretPos);
} }
private void unavailableCallback() { private void unavailableCallback() {
console.setInputPermitted(false); console.setInputPermitted(false);
PrintWriter out = console.getOutWriter(); PrintWriter out = console.getOutWriter();
out.println("Ghidra was not started with pyhidra. Python is not available."); out.println("Ghidra was not started with PyGhidra. Python is not available.");
} }
/** /**
* Initializes the interpreter with the provided PyhidraConsole. * Initializes the interpreter with the provided PyGhidraConsole.
* *
* This method is for <b>internal use only</b> and is only public so it can be * This method is for <b>internal use only</b> and is only public so it can be
* called from Python. * called from Python.
@@ -76,13 +76,13 @@ public final class PyhidraInterpreter implements Disposable, InterpreterConnecti
* @param pythonSideConsole the python side console * @param pythonSideConsole the python side console
* @throws AssertException if the interpreter has already been initialized * @throws AssertException if the interpreter has already been initialized
*/ */
public void init(PyhidraConsole pythonSideConsole) { public void init(PyGhidraConsole pythonSideConsole) {
if (pyhidraConsole != null) { if (pyghidraConsole != null) {
throw new AssertException("the interpreter has already been initialized"); throw new AssertException("the interpreter has already been initialized");
} }
pyhidraConsole = pythonSideConsole; pyghidraConsole = pythonSideConsole;
console.addFirstActivationCallback(pyhidraConsole::restart); console.addFirstActivationCallback(pyghidraConsole::restart);
console.addAction(new CancelAction(pyhidraConsole)); console.addAction(new CancelAction(pyghidraConsole));
console.addAction(new ResetAction(pyhidraConsole)); console.addAction(new ResetAction(pyghidraConsole));
} }
} }
@@ -1,9 +1,9 @@
package ghidra.pyhidra.interpreter; package ghidra.pyghidra.interpreter;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import ghidra.pyhidra.PyhidraPlugin; import ghidra.pyghidra.PyGhidraPlugin;
import ghidra.util.HelpLocation; import ghidra.util.HelpLocation;
import docking.ActionContext; import docking.ActionContext;
import docking.action.DockingAction; import docking.action.DockingAction;
@@ -15,10 +15,10 @@ import static docking.DockingUtils.CONTROL_KEY_MODIFIER_MASK;
final class ResetAction extends DockingAction { final class ResetAction extends DockingAction {
private final PyhidraConsole console; private final PyGhidraConsole console;
ResetAction(PyhidraConsole console) { ResetAction(PyGhidraConsole console) {
super("Reset", PyhidraPlugin.class.getSimpleName()); super("Reset", PyGhidraPlugin.class.getSimpleName());
this.console = console; this.console = console;
setDescription("Reset the interpreter"); setDescription("Reset the interpreter");
ImageIcon image = ResourceManager.loadImage("images/reload3.png"); ImageIcon image = ResourceManager.loadImage("images/reload3.png");
@@ -26,7 +26,7 @@ final class ResetAction extends DockingAction {
setEnabled(true); setEnabled(true);
KeyBindingData key = new KeyBindingData(KeyEvent.VK_D, CONTROL_KEY_MODIFIER_MASK); KeyBindingData key = new KeyBindingData(KeyEvent.VK_D, CONTROL_KEY_MODIFIER_MASK);
setKeyBindingData(key); setKeyBindingData(key);
setHelpLocation(new HelpLocation(PyhidraPlugin.TITLE, "Reset_Interpreter")); setHelpLocation(new HelpLocation(PyGhidraPlugin.TITLE, "Reset_Interpreter"));
} }
@Override @Override
@@ -1,4 +1,4 @@
package ghidra.pyhidra.property; package ghidra.pyghidra.property;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
@@ -16,7 +16,7 @@ import java.lang.invoke.MethodHandle;
* } * }
* } * }
* *
* The pyhidra internals expects every {@link JavaProperty} to be an instance of this class. * The PyGhidra internals expects every {@link JavaProperty} to be an instance of this class.
* No checking is required or performed since the {@link JavaProperty} interface and this * No checking is required or performed since the {@link JavaProperty} interface and this
* class are sealed. * class are sealed.
*/ */
@@ -1,4 +1,4 @@
package ghidra.pyhidra.property; package ghidra.pyghidra.property;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
@@ -1,4 +1,4 @@
package ghidra.pyhidra.property; package ghidra.pyghidra.property;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
@@ -1,4 +1,4 @@
package ghidra.pyhidra.property; package ghidra.pyghidra.property;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
@@ -1,4 +1,4 @@
package ghidra.pyhidra.property; package ghidra.pyghidra.property;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
@@ -1,4 +1,4 @@
package ghidra.pyhidra.property; package ghidra.pyghidra.property;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
@@ -1,4 +1,4 @@
package ghidra.pyhidra.property; package ghidra.pyghidra.property;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
@@ -1,4 +1,4 @@
package ghidra.pyhidra.property; package ghidra.pyghidra.property;
/** /**
* Property interface for creating a Python property for getters and setters. * Property interface for creating a Python property for getters and setters.
@@ -1,4 +1,4 @@
package ghidra.pyhidra.property; package ghidra.pyghidra.property;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
@@ -1,4 +1,4 @@
package ghidra.pyhidra.property; package ghidra.pyghidra.property;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
@@ -1,4 +1,4 @@
package ghidra.pyhidra.property; package ghidra.pyghidra.property;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
@@ -1,4 +1,4 @@
package ghidra.pyhidra.property; package ghidra.pyghidra.property;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
@@ -1,4 +1,4 @@
package ghidra.pyhidra.property; package ghidra.pyghidra.property;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
@@ -1,9 +1,9 @@
# pyhidra # PyGhidra
Pyhidra is a Python library that provides direct access to the Ghidra API within a native CPython interpreter using [jpype](https://jpype.readthedocs.io/en/latest). As well, Pyhidra contains some conveniences for setting up analysis on a given sample and running a Ghidra script locally. It also contains a Ghidra plugin to allow the use of CPython from the Ghidra user interface. PyGhidra is a Python library that provides direct access to the Ghidra API within a native CPython interpreter using [jpype](https://jpype.readthedocs.io/en/latest). As well, PyGhidra contains some conveniences for setting up analysis on a given sample and running a Ghidra script locally. It also contains a Ghidra plugin to allow the use of CPython from the Ghidra user interface.
Pyhidra was initially developed for use with Dragodis and is designed to be installable without requiring Java or Ghidra. This allows other Python projects PyGhidra was initially developed for use with Dragodis and is designed to be installable without requiring Java or Ghidra. This allows other Python projects
have pyhidra as a dependency and provide optional Ghidra functionality without requiring all users to install Java and Ghidra. It is recommended to recommend that users set the `GHIDRA_INSTALL_DIR` environment variable to simplify locating Ghidra. have PyGhidra as a dependency and provide optional Ghidra functionality without requiring all users to install Java and Ghidra. It is recommended to recommend that users set the `GHIDRA_INSTALL_DIR` environment variable to simplify locating Ghidra.
## Usage ## Usage
@@ -18,8 +18,8 @@ which will allow you to directly import `ghidra` and `java`.
*NOTE: No projects or programs get setup in this mode.* *NOTE: No projects or programs get setup in this mode.*
```python ```python
import pyhidra import pyghidra
pyhidra.start() pyghidra.start()
import ghidra import ghidra
from ghidra.app.util.headless import HeadlessAnalyzer from ghidra.app.util.headless import HeadlessAnalyzer
@@ -32,12 +32,12 @@ from java.lang import String
### Customizing Java and Ghidra initialization ### Customizing Java and Ghidra initialization
JVM configuration for the classpath and vmargs may be done through a `PyhidraLauncher`. JVM configuration for the classpath and vmargs may be done through a `PyGhidraLauncher`.
```python ```python
from pyhidra.launcher import HeadlessPyhidraLauncher from pyghidra.launcher import HeadlessPyGhidraLauncher
launcher = HeadlessPyhidraLauncher() launcher = HeadlessPyGhidraLauncher()
launcher.add_classpaths("log4j-core-2.17.1.jar", "log4j-api-2.17.1.jar") launcher.add_classpaths("log4j-core-2.17.1.jar", "log4j-api-2.17.1.jar")
launcher.add_vmargs("-Dlog4j2.formatMsgNoLookups=true") launcher.add_vmargs("-Dlog4j2.formatMsgNoLookups=true")
launcher.start() launcher.start()
@@ -45,10 +45,10 @@ launcher.start()
### Registering an Entry Point ### Registering an Entry Point
The `PyhidraLauncher` can also be configured through the use of a registered entry point on your own python project. The `PyGhidraLauncher` can also be configured through the use of a registered entry point on your own python project.
This is useful for installing your own Ghidra plugin which uses pyhidra and self-compiles. This is useful for installing your own Ghidra plugin which uses PyGhidra and self-compiles.
First create an [entry_point](https://setuptools.pypa.io/en/latest/userguide/entry_point.html) for `pyhidra.setup` First create an [entry_point](https://setuptools.pypa.io/en/latest/userguide/entry_point.html) for `pyghidra.setup`
pointing to a single argument function which accepts the launcher instance. pointing to a single argument function which accepts the launcher instance.
```python ```python
@@ -58,7 +58,7 @@ from setuptools import setup
setup( setup(
# ..., # ...,
entry_points={ entry_points={
'pyhidra.setup': [ 'pyghidra.setup': [
'acme_plugin = acme.ghidra_plugin.install:setup', 'acme_plugin = acme.ghidra_plugin.install:setup',
] ]
} }
@@ -67,25 +67,25 @@ setup(
Then we create the target function. Then we create the target function.
This function will be called every time a user starts a pyhidra launcher. This function will be called every time a user starts a PyGhidra launcher.
In the same fashion, another entry point `pyhidra.pre_launch` may be registered and will be called after Ghidra and all In the same fashion, another entry point `pyghidra.pre_launch` may be registered and will be called after Ghidra and all
plugins have been loaded. plugins have been loaded.
```python ```python
# acme/ghidra_plugin/install.py # acme/ghidra_plugin/install.py
from pathlib import Path from pathlib import Path
import pyhidra import pyghidra
def setup(launcher): def setup(launcher):
""" """
Run by pyhidra launcher to install our plugin. Run by PyGhidra launcher to install our plugin.
""" """
launcher.add_classpaths("log4j-core-2.17.1.jar", "log4j-api-2.17.1.jar") launcher.add_classpaths("log4j-core-2.17.1.jar", "log4j-api-2.17.1.jar")
launcher.add_vmargs("-Dlog4j2.formatMsgNoLookups=true") launcher.add_vmargs("-Dlog4j2.formatMsgNoLookups=true")
# Install our plugin. # Install our plugin.
source_path = Path(__file__).parent / "java" / "plugin" # path to uncompiled .java code source_path = Path(__file__).parent / "java" / "plugin" # path to uncompiled .java code
details = pyhidra.ExtensionDetails( details = pyghidra.ExtensionDetails(
name="acme_plugin", name="acme_plugin",
description="My Cool Plugin", description="My Cool Plugin",
author="acme", author="acme",
@@ -97,15 +97,15 @@ def setup(launcher):
### Analyze a File ### Analyze a File
To have pyhidra setup a binary file for you, use the `open_program()` function. To have PyGhidra setup a binary file for you, use the `open_program()` function.
This will setup a Ghidra project and import the given binary file as a program for you. This will setup a Ghidra project and import the given binary file as a program for you.
Again, this will also allow you to import `ghidra` and `java` to perform more advanced processing. Again, this will also allow you to import `ghidra` and `java` to perform more advanced processing.
```python ```python
import pyhidra import pyghidra
with pyhidra.open_program("binary_file.exe") as flat_api: with pyghidra.open_program("binary_file.exe") as flat_api:
program = flat_api.getCurrentProgram() program = flat_api.getCurrentProgram()
listing = program.getListing() listing = program.getListing()
print(listing.getCodeUnitAt(flat_api.toAddr(0x1234))) print(listing.getCodeUnitAt(flat_api.toAddr(0x1234)))
@@ -117,12 +117,12 @@ with pyhidra.open_program("binary_file.exe") as flat_api:
decomp_api.dispose() decomp_api.dispose()
``` ```
By default, pyhidra will run analysis for you. If you would like to do this yourself, set `analyze` to `False`. By default, PyGhidra will run analysis for you. If you would like to do this yourself, set `analyze` to `False`.
```python ```python
import pyhidra import pyghidra
with pyhidra.open_program("binary_file.exe", analyze=False) as flat_api: with pyghidra.open_program("binary_file.exe", analyze=False) as flat_api:
from ghidra.program.util import GhidraProgramUtilities from ghidra.program.util import GhidraProgramUtilities
program = flat_api.getCurrentProgram() program = flat_api.getCurrentProgram()
@@ -135,16 +135,16 @@ The `open_program()` function can also accept optional arguments to control the
(Helpful for opening up a sample in an already existing project.) (Helpful for opening up a sample in an already existing project.)
```python ```python
import pyhidra import pyghidra
with pyhidra.open_program("binary_file.exe", project_name="EXAM_231", project_location=r"C:\exams\231") as flat_api: with pyghidra.open_program("binary_file.exe", project_name="EXAM_231", project_location=r"C:\exams\231") as flat_api:
... ...
``` ```
### Run a Script ### Run a Script
Pyhidra can also be used to run an existing Ghidra Python script directly in your native python interpreter PyGhidra can also be used to run an existing Ghidra Python script directly in your native python interpreter
using the `run_script()` command. using the `run_script()` command.
However, while you can technically run an existing Ghidra script unmodified, you may However, while you can technically run an existing Ghidra script unmodified, you may
run into issues due to differences between Jython 2 and CPython 3. run into issues due to differences between Jython 2 and CPython 3.
@@ -152,21 +152,21 @@ Therefore, some modification to the script may be needed.
```python ```python
import pyhidra import pyghidra
pyhidra.run_script(r"C:\input.exe", r"C:\some_ghidra_script.py") pyghidra.run_script(r"C:\input.exe", r"C:\some_ghidra_script.py")
``` ```
This can also be done on the command line using `pyhidra`. This can also be done on the command line using `pyghidra`.
```console ```console
> pyhidra C:\input.exe C:\some_ghidra_script.py <CLI ARGS PASSED TO SCRIPT> > pyghidra C:\input.exe C:\some_ghidra_script.py <CLI ARGS PASSED TO SCRIPT>
``` ```
### Handling Package Name Conflicts ### Handling Package Name Conflicts
There may be some Python modules and Java packages with the same import path. When this occurs the Python module takes precedence. There may be some Python modules and Java packages with the same import path. When this occurs the Python module takes precedence.
While jpype has its own mechanism for handling this situation, pyhidra automatically makes the Java package accessible by allowing While jpype has its own mechanism for handling this situation, PyGhidra automatically makes the Java package accessible by allowing
it to be imported with an underscore appended to the package name. it to be imported with an underscore appended to the package name.
```python ```python
@@ -3,7 +3,7 @@ requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta" build-backend = "setuptools.build_meta"
[project] [project]
name = "pyhidra" name = "pyghidra"
dynamic = ["version", "readme"] dynamic = ["version", "readme"]
description = "Native CPython for Ghidra" description = "Native CPython for Ghidra"
license = {text = "Apache-2.0"} license = {text = "Apache-2.0"}
@@ -39,16 +39,16 @@ testing = [
] ]
[project.scripts] [project.scripts]
pyhidra = "pyhidra.__main__:main" pyghidra = "pyghidra.__main__:main"
[project.gui-scripts] [project.gui-scripts]
pyhidraw = "pyhidra.gui:_gui" pyghidraw = "pyghidra.gui:_gui"
[project.urls] [project.urls]
Repository = "https://github.com/NationalSecurityAgency/ghidra" Repository = "https://github.com/NationalSecurityAgency/ghidra"
[tool.setuptools.dynamic] [tool.setuptools.dynamic]
version = {attr = "pyhidra.__version__"} version = {attr = "pyghidra.__version__"}
readme = {file = ["README.md"], content-type = "text/markdown"} readme = {file = ["README.md"], content-type = "text/markdown"}
[tool.pytest.ini_options] [tool.pytest.ini_options]
@@ -41,13 +41,13 @@ debug_callback = _debug_callback
# Expose API # Expose API
from .core import run_script, start, started, open_program from .core import run_script, start, started, open_program
from .launcher import DeferredPyhidraLauncher, GuiPyhidraLauncher, HeadlessPyhidraLauncher from .launcher import DeferredPyGhidraLauncher, GuiPyGhidraLauncher, HeadlessPyGhidraLauncher
from .script import get_current_interpreter from .script import get_current_interpreter
from .version import ApplicationInfo, ExtensionDetails from .version import ApplicationInfo, ExtensionDetails
__all__ = [ __all__ = [
"debug_callback", "get_current_interpreter", "open_program", "run_script", "start", "debug_callback", "get_current_interpreter", "open_program", "run_script", "start",
"started", "ApplicationInfo", "DeferredPyhidraLauncher", "ExtensionDetails", "started", "ApplicationInfo", "DeferredPyGhidraLauncher", "ExtensionDetails",
"GuiPyhidraLauncher", "HeadlessPyhidraLauncher" "GuiPyGhidraLauncher", "HeadlessPyGhidraLauncher"
] ]
@@ -5,13 +5,13 @@ import logging
import sys import sys
from pathlib import Path from pathlib import Path
import pyhidra import pyghidra
import pyhidra.core import pyghidra.core
import pyhidra.gui import pyghidra.gui
# NOTE: this must be "pyhidra" and not __name__ # NOTE: this must be "pyghidra" and not __name__
logger = logging.getLogger("pyhidra") logger = logging.getLogger("pyghidra")
def _interpreter(interpreter_globals: dict): def _interpreter(interpreter_globals: dict):
@@ -24,7 +24,7 @@ def _interpreter(interpreter_globals: dict):
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
class PyhidraArgs(argparse.Namespace): class PyGhidraArgs(argparse.Namespace):
""" """
Custom namespace for holding the command line arguments Custom namespace for holding the command line arguments
""" """
@@ -60,18 +60,18 @@ class PyhidraArgs(argparse.Namespace):
vmargs = self.jvm_args vmargs = self.jvm_args
if self.gui: if self.gui:
pyhidra.gui.gui(self.install_dir, vmargs) pyghidra.gui.gui(self.install_dir, vmargs)
return return
# not in gui mode so it is easier to start Ghidra now # not in gui mode so it is easier to start Ghidra now
launcher = pyhidra.HeadlessPyhidraLauncher( launcher = pyghidra.HeadlessPyGhidraLauncher(
verbose=self.verbose, install_dir=self.install_dir) verbose=self.verbose, install_dir=self.install_dir)
launcher.vm_args = vmargs + launcher.vm_args launcher.vm_args = vmargs + launcher.vm_args
launcher.start() launcher.start()
if self.script_path is not None: if self.script_path is not None:
try: try:
pyhidra.run_script( pyghidra.run_script(
self.binary_path, self.binary_path,
self.script_path, self.script_path,
project_location=self.project_path, project_location=self.project_path,
@@ -92,7 +92,7 @@ class PyhidraArgs(argparse.Namespace):
self.verbose, self.verbose,
not self.skip_analysis not self.skip_analysis
) )
with pyhidra.core._flat_api(*args, install_dir=self.install_dir) as api: with pyghidra.core._flat_api(*args, install_dir=self.install_dir) as api:
_interpreter(api) _interpreter(api)
else: else:
_interpreter(globals()) _interpreter(globals())
@@ -129,7 +129,7 @@ class PathAction(argparse.Action):
self.nargs = '*' self.nargs = '*'
self.type = str self.type = str
def __call__(self, parser, namespace: PyhidraArgs, values, option_string=None): def __call__(self, parser, namespace: PyGhidraArgs, values, option_string=None):
if not values: if not values:
return return
@@ -168,7 +168,7 @@ class PathAction(argparse.Action):
def _get_parser(): def _get_parser():
parser = argparse.ArgumentParser(prog="pyhidra") parser = argparse.ArgumentParser(prog="pyghidra")
parser.add_argument( parser.add_argument(
"-v", "-v",
"--verbose", "--verbose",
@@ -215,7 +215,7 @@ def _get_parser():
action=PathAction, action=PathAction,
help=( help=(
"Headless script path. The script must have a .py extension. " "Headless script path. The script must have a .py extension. "
"If a script is not provided, pyhidra will drop into a repl." "If a script is not provided, pyghidra will drop into a repl."
) )
) )
parser.add_argument( parser.add_argument(
@@ -258,7 +258,7 @@ def _get_parser():
def main(): def main():
""" """
pyhidra module main function pyghidra module main function
""" """
handler = logging.StreamHandler() handler = logging.StreamHandler()
formatter = logging.Formatter("%(filename)s:%(lineno)d %(message)s") formatter = logging.Formatter("%(filename)s:%(lineno)d %(message)s")
@@ -266,7 +266,7 @@ def main():
logger.addHandler(handler) logger.addHandler(handler)
parser = _get_parser() parser = _get_parser()
parser.parse_args(namespace=PyhidraArgs(parser)).func() parser.parse_args(namespace=PyGhidraArgs(parser)).func()
if __name__ == "__main__": if __name__ == "__main__":
@@ -2,18 +2,18 @@ import contextlib
from pathlib import Path from pathlib import Path
from typing import Union, TYPE_CHECKING, Tuple, ContextManager, List, Optional from typing import Union, TYPE_CHECKING, Tuple, ContextManager, List, Optional
from pyhidra.converters import * # pylint: disable=wildcard-import, unused-wildcard-import from pyghidra.converters import * # pylint: disable=wildcard-import, unused-wildcard-import
if TYPE_CHECKING: if TYPE_CHECKING:
from pyhidra.launcher import PyhidraLauncher from pyghidra.launcher import PyGhidraLauncher
from ghidra.base.project import GhidraProject from ghidra.base.project import GhidraProject
from ghidra.program.flatapi import FlatProgramAPI from ghidra.program.flatapi import FlatProgramAPI
from ghidra.program.model.lang import CompilerSpec, Language, LanguageService from ghidra.program.model.lang import CompilerSpec, Language, LanguageService
from ghidra.program.model.listing import Program from ghidra.program.model.listing import Program
def start(verbose=False, *, install_dir: Path = None) -> "PyhidraLauncher": def start(verbose=False, *, install_dir: Path = None) -> "PyGhidraLauncher":
""" """
Starts the JVM and fully initializes Ghidra in Headless mode. Starts the JVM and fully initializes Ghidra in Headless mode.
@@ -22,18 +22,18 @@ def start(verbose=False, *, install_dir: Path = None) -> "PyhidraLauncher":
(Defaults to the GHIDRA_INSTALL_DIR environment variable) (Defaults to the GHIDRA_INSTALL_DIR environment variable)
:return: The PhyidraLauncher used to start the JVM :return: The PhyidraLauncher used to start the JVM
""" """
from pyhidra.launcher import HeadlessPyhidraLauncher from pyghidra.launcher import HeadlessPyGhidraLauncher
launcher = HeadlessPyhidraLauncher(verbose=verbose, install_dir=install_dir) launcher = HeadlessPyGhidraLauncher(verbose=verbose, install_dir=install_dir)
launcher.start() launcher.start()
return launcher return launcher
def started() -> bool: def started() -> bool:
""" """
Whether the PyhidraLauncher has already started. Whether the PyGhidraLauncher has already started.
""" """
from pyhidra.launcher import PyhidraLauncher from pyghidra.launcher import PyGhidraLauncher
return PyhidraLauncher.has_launched() return PyGhidraLauncher.has_launched()
def _get_language(id: str) -> "Language": def _get_language(id: str) -> "Language":
@@ -137,7 +137,7 @@ def _setup_project(
def _setup_script(project: "GhidraProject", program: "Program"): def _setup_script(project: "GhidraProject", program: "Program"):
from pyhidra.script import PyGhidraScript from pyghidra.script import PyGhidraScript
from ghidra.app.script import GhidraState from ghidra.app.script import GhidraState
from ghidra.program.util import ProgramLocation from ghidra.program.util import ProgramLocation
from ghidra.util.task import TaskMonitor from ghidra.util.task import TaskMonitor
@@ -205,10 +205,10 @@ def open_program(
:raises TypeError: If the provided loader does not implement `ghidra.app.util.opinion.Loader`. :raises TypeError: If the provided loader does not implement `ghidra.app.util.opinion.Loader`.
""" """
from pyhidra.launcher import PyhidraLauncher, HeadlessPyhidraLauncher from pyghidra.launcher import PyGhidraLauncher, HeadlessPyGhidraLauncher
if not PyhidraLauncher.has_launched(): if not PyGhidraLauncher.has_launched():
HeadlessPyhidraLauncher().start() HeadlessPyGhidraLauncher().start()
from ghidra.app.script import GhidraScriptUtil from ghidra.app.script import GhidraScriptUtil
from ghidra.program.flatapi import FlatProgramAPI from ghidra.program.flatapi import FlatProgramAPI
@@ -273,10 +273,10 @@ def _flat_api(
:raises ValueError: If the provided language, compiler or loader is invalid. :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`. :raises TypeError: If the provided loader does not implement `ghidra.app.util.opinion.Loader`.
""" """
from pyhidra.launcher import PyhidraLauncher, HeadlessPyhidraLauncher from pyghidra.launcher import PyGhidraLauncher, HeadlessPyGhidraLauncher
if not PyhidraLauncher.has_launched(): if not PyGhidraLauncher.has_launched():
HeadlessPyhidraLauncher(verbose=verbose, install_dir=install_dir).start() HeadlessPyGhidraLauncher(verbose=verbose, install_dir=install_dir).start()
project, program = None, None project, program = None, None
if binary_path or project_location: if binary_path or project_location:
@@ -4,10 +4,10 @@ from pathlib import Path
import sys import sys
import threading import threading
from .launcher import PyhidraLauncher, _run_mac_app from .launcher import PyGhidraLauncher, _run_mac_app
class GhidraLauncher(PyhidraLauncher): class GhidraLauncher(PyGhidraLauncher):
def __init__(self, verbose=False, class_name=str, gui=False, *, install_dir: Path = None): def __init__(self, verbose=False, class_name=str, gui=False, *, install_dir: Path = None):
super().__init__(verbose=verbose, install_dir=install_dir) super().__init__(verbose=verbose, install_dir=install_dir)
@@ -50,14 +50,14 @@ class _Helper:
self.msg += " # Perform headless processing\n" self.msg += " # Perform headless processing\n"
self.msg += " headless.processLocal(...)\n\n" self.msg += " headless.processLocal(...)\n\n"
else: else:
# PyhidraPlugin scenario # PyGhidraPlugin scenario
self.msg = "Press 'F1' for usage instructions" self.msg = "Press 'F1' for usage instructions"
def __call__(self, param=None): def __call__(self, param=None):
def get_class_and_method(param): def get_class_and_method(param):
if param is None and not SystemUtilities.isInHeadlessMode(): if param is None and not SystemUtilities.isInHeadlessMode():
# Enable help() in PyhidraPlugin scenario to show help for GhidraScript # Enable help() in PyGhidraPlugin scenario to show help for GhidraScript
return "ghidra.app.script.GhidraScript", None return "ghidra.app.script.GhidraScript", None
class_name = None class_name = None
method_name = None method_name = None

Some files were not shown because too many files have changed in this diff Show More