GP-4489: Add psutil and protobuf to downloads, dist. Build py packages for dist.

This commit is contained in:
Dan 2024-04-26 23:34:30 -04:00 committed by ghidra1
parent 75d5737cce
commit fc17ca970c
24 changed files with 705 additions and 163 deletions

View File

@ -62,6 +62,11 @@ Build Javadoc:
gradle createJavadocs
```
Build Python3 packages for the Debugger:
```
gradle buildPyPackage
```
Build Ghidra to `build/dist` in an uncompressed form. This will be a distribution intended only to
run on the platform on which it was built.
```
@ -182,13 +187,18 @@ If you'd like some details of our fine tuning, take a look at [building_fid.txt]
## Debugger Development
We have recently changed the Debugger's back-end architecture.
We no longer user JNA to access native Debugger APIs.
We only use it for pseudo-terminal access.
Instead, we use Python3 and a protobuf-based TCP connection for back-end integration.
### Additional Dependencies
In addition to Ghidra's normal dependencies, you may want the following:
* WinDbg for Windows x64
* GDB 8.0 or later for Linux amd64/x86_64
* LLDB 13.0 for macOS
* GDB 13 or later for Linux
* LLDB 10 or later for macOS
The others (e.g., JNA) are handled by Gradle via Maven Central.
@ -199,121 +209,137 @@ These all currently reside in the `Ghidra/Debug` directory, but will likely be r
`Framework` and `Feature` directories later. Each project is listed "bottom up" with a brief
description and status.
* ProposedUtils - a collection of utilities proposed to be moved to other respective projects
* AnnotationValidator - an experimental annotation processor for database access objects
* ProposedUtils - a collection of utilities proposed to be moved to other respective projects.
* AnnotationValidator - an experimental annotation processor for database access objects.
* Framework-TraceModeling - a database schema and set of interfaces for storing machine state over
time
time.
* Framework-AsyncComm - a collection of utilities for asynchronous communication (packet formats
and completable-future conveniences).
* Framework-Debugging - specifies interfaces for debugger models and provides implementation
conveniences.
conveniences. This is mostly deprecated.
* Debugger - the collection of Ghidra plugins and services comprising the Debugger UI.
* Debugger-rmi-trace - the wire protocol, client, services, and UI components for Trace RMI, the new back-end architecture.
* Debugger-agent-dbgeng - the connector for WinDbg (via dbgeng.dll) on Windows x64.
* Debugger-agent-dbgmodel - an experimental connector for WinDbg Preview (with TTD, via
dbgmodel.dll) on Windows x64.
* Debugger-agent-dbgmodel-traceloader - an experimental "importer" for WinDbg trace files.
* Debugger-agent-gdb - the connector for GDB (8.0 or later recommended) on UNIX.
* Debugger-swig-lldb - the Java language bindings for LLDB's SBDebugger, also proposed upstream.
* Debugger-agent-lldb - the connector for LLDB (13.0 required) on macOS, UNIX, and Windows.
dbgmodel.dll) on Windows x64. This is deprecated, as most of these features are implemented in Debugger-agent-dbgeng for the new architecture.
* Debugger-agent-dbgmodel-traceloader - an experimental "importer" for WinDbg trace files. This is deprecated.
* Debugger-agent-gdb - the connector for GDB (13 or later recommended) on UNIX.
* Debugger-swig-lldb - the Java language bindings for LLDB's SBDebugger, also proposed upstream. This is deprecated. We now use the Python3 language bindings for LLDB.
* Debugger-agent-lldb - the connector for LLDB (10 or later recommended) on macOS, UNIX, and Windows.
* Debugger-gadp - the connector for our custom wire protocol the Ghidra Asynchronous Debugging
Protocol.
* Debugger-jpda - an in-development connector for Java and Dalvik debugging via JDI (i.e., JDWP).
Protocol. This is deprecated. It's replaced by Debugger-rmi-trace.
* Debugger-jpda - an in-development connector for Java and Dalvik debugging via JDI (i.e., JDWP). This is deprecated and not yet replaced.
The Trace Modeling schema records machine state and markup over time.
It rests on the same database framework as Programs, allowing trace recordings to be stored in a
Ghidra project and shared via a server, if desired. Trace "recording" is a de facto requirement for
displaying information in Ghidra's UI. However, only the machine state actually observed by the user
(or perhaps a script) is recorded. For most use cases, the Trace is small and ephemeral, serving
only to mediate between the UI components and the target's model. It supports many of the same
markup (e.g., disassembly, data types) as Programs, in addition to tracking active threads, loaded
modues, breakpoints, etc.
It rests on the same database framework as Programs, allowing trace recordings to be stored in a Ghidra project and shared via a server, if desired.
Trace "recording" is a de facto requirement for displaying information in Ghidra's UI.
The back-end connector has full discretion over what is recorded by using Trace RMI.
Typically, only the machine state actually observed by the user (or perhaps a script) is recorded.
For most use cases, the Trace is small and ephemeral, serving only to mediate between the UI components and the target's model.
It supports many of the same markup (e.g., disassembly, data types) as Programs, in addition to tracking active threads, loaded modues, breakpoints, etc.
Every model (or "adapter" or "connector" or "agent") implements the API specified in
Framework-Debugging. As a general rule in Ghidra, no component is allowed to access a native API and
reside in the same JVM as the Ghidra UI. This allows us to contain crashes, preventing data loss. To
accommodate this requirement -- given that debugging native applications is almost certainly going
to require access to native APIs -- we've developed the Ghidra Asynchronous Debugging Protocol. This
protocol is tightly coupled to Framework-Debugging, essentially exposing its methods via RMI. The
protocol is built using Google's Protobuf library, providing a potential path for agent
implementations in alternative languages. GADP provides both a server and a client implementation.
The server can accept any model which adheres to the specification and expose it via TCP; the client
does the converse. When a model is instantiated in this way, it is called an "agent," because it is
executing in its own JVM. The other connectors, which do not use native APIs, may reside in Ghidra's
JVM and typically implement alternative wire protocols, e.g., JDWP. In both cases, the
implementations inherit from the same interfaces.
Every back end (or "adapter" or "connector" or "agent") employs the Trace RMI client to populate a trace database.
As a general rule in Ghidra, no component is allowed to access a native API and reside in the same JVM as the Ghidra UI.
This allows us to contain crashes, preventing data loss.
To accommodate this requirement — given that debugging native applications is almost certainly going to require access to native APIs — we've developed the Trace RMI protocol.
This also allows us to better bridge the language gap between Java and Python, which is supported by most native debuggers.
This protocol is loosely coupled to Framework-TraceModeling, essentially exposing its methods via RMI, as well as some methods for controlling the UI.
The protocol is built using Google's Protobuf library, providing a potential path for back-end implementations in alternative languages.
We provide the Trace RMI server as a Ghidra component implemented in Java and the Trace RMI client as a Python3 package.
A back-end implementation may be a stand-alone executable or script that accesses the native debugger's API, or a script or plugin for the native debugger.
It then connects to Ghidra via Trace RMI to populate the trace database with information gleaned from that API.
It should provide a set of diagnostic commands to control and monitor that connection.
It should also use the native API to detect session and target changes so that Ghidra's UI consistently reflects the debugging session.
The Debugger services maintain a collection of active connections and inspect each model for
potential targets. When a target is found, the service inspects the target environment and attempts
to find a suitable opinion. Such an opinion, if found, instructs Ghidra how to map the objects,
addresses, registers, etc. from the target namespace into Ghidra's. The target is then handed to a
Trace Recorder which begins collecting information needed to populate the UI, e.g., the program
counter, stack pointer, and the bytes of memory they refer to.
The old system relied on a "recorder" to discover targets and map them to traces in the proper Ghidra language.
That responsibility is now delegated to the back end.
Typically, it examines the target's architecture and immediately creates a trace upon connection.
### Developing a new connector
So Ghidra does not yet support your favorite debugger?
It is tempting, exciting, but also daunting to develop your own connector.
Please finish reading this guide, and look carefully at the ones we have so far, and perhaps ask to
see if we are already developing one. Of course, in time you might also search the internet to see
if others are developing one. There are quite a few caveats and gotchas, the most notable being that
this interface is still in quite a bit of flux. When things go wrong, it could be because of,
without limitation: 1) a bug on your part, 2) a bug on our part, 3) a design flaw in the interfaces,
or 4) a bug in the debugger/API you're adapting. We are still in the process of writing up this
documentation. In the meantime, we recommend using the GDB and dbgeng.dll agents as examples.
We believe the new system is much less daunting than the previous.
Still, please finish reading this guide, and look carefully at the ones we have so far, and perhaps ask to see if we are already developing one.
Of course, in time you might also search the internet to see if others are developing one.
There are quite a few caveats and gotchas, the most notable being that this interface is still in some flux.
When things go wrong, it could be because of, without limitation:
You'll also need to provide launcher(s) so that Ghidra knows how to configure and start your
connector. Please provide launchers for your model in both configurations: as a connector in
Ghidra's JVM, and as a GADP agent. If your model requires native API access, you should only permit
launching it as a GADP agent, unless you give ample warning in the launcher's description. Look at
the existing launchers for examples. There are many model implementation requirements that cannot be
expressed in Java interfaces. Failing to adhere to those requirements may cause different behaviors
with and without GADP. Testing with GADP tends to reveal those implementation errors, but also
obscures the source of client method calls behind network messages. We've also codified (or
attempted to codify) these requirements in a suite of abstract test cases. See the `ghidra.dbg.test`
package of Framework-Debugging, and again, look at existing implementations.
1. A bug on your part
2. A bug on our part
3. A design flaw in the interfaces
4. A bug in the debugger/API you're adapting
We are still (yes, still) in the process of writing up this documentation.
In the meantime, we recommend using the GDB and dbgeng agents as examples.
Be sure to look at the Python code `src/main/py`!
The deprecated Java code `src/main/java` is still included as we transition.
You'll also need to provide launcher(s) so that Ghidra knows how to configure and start your connector.
These are just shell scripts.
We use bash scripts on Linux and macOS, and we use batch files on Windows.
Try to include as many common use cases as makes sense for the debugger.
This provides the most flexibility to users and examples to power users who might create derivative launchers.
Look at the existing launchers for examples.
For testing, please follow the examples for GDB.
We no longer provide abstract classes that prescribe requirements.
Instead, we just provide GDB as an example.
Usually, we split our tests into three categories:
* Commands
* Methods
* Hooks
The Commands tests check that the user CLI commands, conventionally implemented in `commands.py`, work correctly.
In general, do the minimum connection setup, execute the command, and check that it produces the expected output and causes the expected effects.
The Methods tests check that the remote methods, conventionally implemented in `methods.py`, work correctly.
Many methods are just wrappers around CLI commands, some provided by the native debugger and some provided by `commands.py`.
These work similarly to the commands test, except that they invoke methods instead of executing commands.
Again, check the return value (rarely applicable) and that it causes the expected effects.
The Hooks tests check that the back end is able to listen for session and target changes, e.g., knowing when the target stops.
*The test should not "cheat" by executing commands or invoking methods that should instead be triggered by the listener.*
It should execute the minimal commands to setup the test, then trigger an event.
It should then check that the event in turn triggered the expected effects, e.g., updating PC upon the target stopping.
Whenever you make a change to the Python code, you'll need to re-assemble the package's source.
```
gradle assemblePyPackage
```
This is required in case your package includes generated source, as is the case for Debugger-rmi-trace.
If you want to create a new Ghidra module for your connector (recommended) use an existing one's `build.gradle` as a template.
A key part is applying the `hasPythonPackage.gradle` script.
### Adding a new platform
If an existing connector exists for a suitable debugger on the desired platform, then adding it may
be very simple. For example, both the x86 and ARM platforms are supported by GDB, so even though
we're currently focused on x86 support, we've provided the opinions needed for Ghidra to debug ARM
platforms (and several others) via GDB. These opinions are kept in the "Debugger" project, not their
respective "agent" projects. We imagine there are a number of platforms that could be supported
almost out of the box, except that we haven't written the necessary opinions, yet. Take a look at
the existing ones for examples.
If a connector already exists for a suitable debugger on the desired platform, then adding it may be very simple.
For example, many platforms are supported by GDB, so even though we're currently focused on x86-64 (and to some extent arm64) support, we've provided the mappings for many.
These mappings are conventionally kept in each connector's `arch.py` file.
In general, to write a new opinion, you need to know: 1) What the platform is called (including
variant names) by the debugger, 2) What the processor language is called by Ghidra, 3) If
applicable, the mapping of target address spaces into Ghidra's address spaces, 4) If applicable, the
mapping of target register names to those in Ghidra's processor language. In most cases (3) and (4)
are already implemented by default mappers, so you can use those same mappers in your opinion. Once
you have the opinion written, you can try debugging and recording a target. If Ghidra finds your
opinion applicable to that target, it will attempt to record, and then you can work out the kinds
from there. Again, we have a bit of documentation to do regarding common pitfalls.
In general, to update `arch.py`, you need to know:
1. What the platform is called (including variant names) by the debugger
2. What the processor language is called by Ghidra
3. If applicable, the mapping of target address spaces into Ghidra's address spaces
4. If applicable, the mapping of target register names to those in Ghidra's processor language
In most cases (3) and (4) are already implemented by the included mappers.
Naturally, you'll want to test the special cases, preferably in automated tests.
### Emulation
The most obvious integration path for 3rd-party emulators is to write a "connector." However, p-code
emulation is now an integral feature of the Ghidra UI, and it has a fairly accessible API. Namely,
for interpolation between machines states recorded in a trace, and extrapolation into future machine
states. Integration of such emulators may still be useful to you, but we recommend trying the p-code
emulator to see if it suits your needs for emulation in Ghidra before pursuing integration of
another emulator.
The most obvious integration path for 3rd-party emulators is to write a "connector."
However, p-code emulation is an integral feature of the Ghidra UI, and it has a fairly accessible API.
Namely, for interpolation between machines states recorded in a trace, and extrapolation into future machine states.
Integration of such emulators may still be useful to you, but we recommend trying the p-code emulator to see if it suits your needs for emulation in Ghidra before pursuing integration of another emulator.
We also provide out-of-the-box QEMU integration via GDB.
### Contributing
Whether submitting help tickets and pull requests, please tag those related to the debugger with
"Debugger" so that we can triage them more quickly.
To set up your environment, in addition to the usual Gradle tasks, process the Protobuf
specification for GADP:
```bash
gradle generateProto
```
If you already have an environment set up in Eclipse, please re-run `gradle prepDev eclipse` and
import the new projects.
When submitting help tickets and pull requests, please tag those related to the debugger with "Debugger" so that we can triage them more quickly.
[java]: https://dev.java

View File

@ -0,0 +1,5 @@
MODULE FILE LICENSE: pypkg/dist/capstone-5.0.1-py3-none-win_amd64.whl BSD-3-CAPSTONE
MODULE FILE LICENSE: pypkg/dist/comtypes-1.4.1-py3-none-any.whl MIT
MODULE FILE LICENSE: pypkg/dist/Pybag-2.2.10-py3-none-any.whl MIT
MODULE FILE LICENSE: pypkg/dist/pywin32-306-cp312-cp312-win_amd64.whl Python Software Foundation License

View File

@ -77,6 +77,11 @@ else {
}
}
distributePyDep("Pybag-2.2.10-py3-none-any.whl")
distributePyDep("capstone-5.0.1-py3-none-win_amd64.whl")
distributePyDep("comtypes-1.4.1-py3-none-any.whl")
distributePyDep("pywin32-306-cp312-cp312-win_amd64.whl")
tasks.nodepJar {
manifest {
attributes['Main-Class'] = 'agent.dbgeng.gadp.DbgEngGadpServer'

View File

@ -1,5 +1,6 @@
##VERSION: 2.0
##MODULE IP: Apache License 2.0
##MODULE IP: MIT
Module.manifest||GHIDRA||||END|
data/debugger-launchers/local-dbgeng.bat||GHIDRA||||END|
data/debugger-launchers/local-ttd.bat||GHIDRA||||END|

View File

@ -1,8 +1,3 @@
# Ghidra Trace RMI
Package for connecting dbgeng to Ghidra via Trace RMI.
This connector requires Pybag 2.2.8 or better:
https://pypi.org/project/Pybag
https://github.com/dshikashio/Pybag

View File

@ -1,6 +1,6 @@
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
[project]
name = "ghidradbg"

View File

@ -1,6 +1,6 @@
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
[project]
name = "ghidragdb"

View File

@ -1,6 +1,6 @@
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
[project]
name = "ghidralldb"

View File

@ -0,0 +1,4 @@
MODULE FILE LICENSE: pypkg/dist/protobuf-3.20.3-py2.py3-none-any.whl BSD-3-GOOGLE
MODULE FILE LICENSE: pypkg/dist/psutil-5.9.8.tar.gz BSD-3-PSUTIL
MODULE FILE LICENSE: pypkg/dist/setuptools-68.0.0-py3-none-any.whl MIT
MODULE FILE LICENSE: pypkg/dist/wheel-0.37.1-py2.py3-none-any.whl MIT

View File

@ -63,3 +63,8 @@ tasks.assemblePyPackage {
into "src/ghidratrace"
}
}
distributePyDep("protobuf-3.20.3-py2.py3-none-any.whl")
distributePyDep("psutil-5.9.8.tar.gz")
distributePyDep("setuptools-68.0.0-py3-none-any.whl")
distributePyDep("wheel-0.37.1-py2.py3-none-any.whl")

View File

@ -1,4 +1,6 @@
##VERSION: 2.0
##MODULE IP: BSD-3-GOOGLE
##MODULE IP: BSD-3-PSUTIL
DEVNOTES.txt||GHIDRA||||END|
Module.manifest||GHIDRA||||END|
data/ExtensionPoint.manifest||GHIDRA||||END|

View File

@ -1,10 +1,10 @@
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
[project]
name = "ghidratrace"
version = "10.4"
version = "11.1"
authors = [
{ name="Ghidra Development Team" },
]

View File

@ -327,6 +327,12 @@ tell Ghidra where it is, then in the launcher drop-down, select
<strong>Configure and Launch termmines using… → gdb</strong>. DO NOT
select <strong>Re-launch termmines using gdb</strong>, since this will
not allow you to correct the configuration.</p>
<p>If it looks like theres an error about importing python packages,
e.g., “google protobuf,” then you need to install some dependencies.
These are listed in the launchers description. For your convenience,
the correct versions are distributed with Ghidra. Search for files
ending in <code>.whl</code> (or <code>.tar.gz</code>) and install the
required ones using <code>python3 -m pip install</code>.</p>
</section>
<section id="the-dynamic-listing-is-empty" class="level3">
<h3>The Dynamic Listing is empty</h3>
@ -457,8 +463,9 @@ the systems copy of GDB. Probably, you can just click
<li>In the <strong>Model</strong> window (to the left), expand the
<em>Available</em> node.</li>
<li>In the filter box, type <code>termmines</code>.</li>
<li>Right click on the node and select <strong>Attach</strong>, or, if you prefer, note the PID, e.g. 1234, then in the <strong>Terminal</strong> type,
e.g., <code>attach 1234</code>.</li>
<li>Right click on the node and select <strong>Attach</strong>, or, if
you prefer, note the PID, e.g. 1234, then in the
<strong>Terminal</strong> type, e.g., <code>attach 1234</code>.</li>
</ol>
</section>
<section id="exercise-attach" class="level2">

View File

@ -130,6 +130,11 @@ If it is just missing, then install it and try again.
If you need to tell Ghidra where it is, then in the launcher drop-down, select **Configure and Launch termmines using... &rarr; gdb**.
DO NOT select **Re-launch termmines using gdb**, since this will not allow you to correct the configuration.
If it looks like there's an error about importing python packages, e.g., "google protobuf," then you need to install some dependencies.
These are listed in the launcher's description.
For your convenience, the correct versions are distributed with Ghidra.
Search for files ending in `.whl` (or `.tar.gz`) and install the required ones using `python3 -m pip install`.
### The Dynamic Listing is empty
Check for an actual connection.

View File

@ -210,24 +210,40 @@ the target environment. Notice that we are <em>not</em> using
<code>gdb</code> by forwarding Trace RMI over SSH. See the help (press
<strong><code>F1</code></strong> on the <strong>gdb via ssh</strong>
menu item for advantages and disadvantages of using this
vs. <code>gdbserver</code>.</p>
vs. <code>gdbserver</code>.)</p>
<ol type="1">
<li><p>First, prepare the target. This is more involved than using
<code>gdbserver</code>, since you will need to ensure <code>gdb</code>
and the Trace RMI plugin for it are installed. The packages, which
should be included with Ghidra, are <code>ghidratrace</code> and
<code>ghidragdb</code>. If you installed <code>gdb</code> and
<code>python3</code> from your distributions repositories, installation
of the Python packages should just be a matter of using
<code>pip</code>:</p>
<code>ghidragdb</code>, but you may need to build them first. If you
installed <code>gdb</code> and <code>python3</code> from your
distributions repositories, installation of the Python packages should
be straightfoward. Search the Ghidra installation for files ending in
<code>.whl</code>. If the <code>ghidratrace</code> and
<code>ghidragdb</code> packages are there, you can skip this build step
and just transfer them to the target. On the local system:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">python3</span> <span class="at">-m</span> pip install /path/to/ghidratrace....whl</span></code></pre></div>
<p>Chances are, GDB embeds the same Python, so they become importable
from <code>gdb</code>:</p>
class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">python3</span> <span class="at">-m</span> pip install build <span class="co"># unless you already have it</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="bu">cd</span> /path/to/ghidra/Ghidra/Debug/Debugger-rmi-trace/pypkg</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="ex">python3</span> <span class="at">-m</span> build</span></code></pre></div>
<p>This will output <code>.tar.gz</code> and <code>.whl</code> files
under <code>pypkg/dist</code>. Do the same for
<code>Debugger-agent-gdb/pypkg</code>. Transfer the resulting
<code>.whl</code> files to the target, then on the target system:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode gdb"><code class="sourceCode gdbsyntax"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>python import ghidragdb</span></code></pre></div>
<p>You can quit GDB, since that was just for verifying the
installation.</p></li>
class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ex">python3</span> <span class="at">-m</span> pip install /path/to/ghidratrace-<span class="pp">[</span><span class="ss">version</span><span class="pp">]</span>.whl /path/to/ghidragdb-<span class="pp">[</span><span class="ss">version</span><span class="pp">]</span>.whl</span></code></pre></div>
<p>If you are offline, the dependencies are included in the
<code>pypkg/dist</code> directory for each module. Transfer and install
them, too. You may try
<code>python -m pip install --no-index -f /path/to/packages ghidragdb</code>,
if all the packages and dependencies are in the one directory. Chances
are, GDB embeds the same Python, so they become importable from GDB.
Test using <code>gdb</code> on the target system:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode gdb"><code class="sourceCode gdbsyntax"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>python import ghidragdb</span></code></pre></div>
<p>No news is good news! You can quit GDB, since that was just for
verifying the installation.</p></li>
<li><p>From the launch menu, select <strong>gdb via ssh</strong>.</p>
<figure>
<img src="images/RemoteTargets_GdbViaSsh.png"
@ -247,38 +263,44 @@ local target.</p>
<h3>Troubleshooting</h3>
<section id="i-cant-find-the-python-packages-to-install" class="level4">
<h4>I cant find the Python packages to install</h4>
<p>These should be located in the Ghidra installation. Search for files
ending in <code>.whl</code>. Alternatively, you can build the packages
from source. The source is included with Ghidra. If you are able to do
local debugging with Ghidra and <code>gdb</code>, then the source is
definitely present and functioning.</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">python3</span> <span class="at">-m</span> pip install build</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="bu">cd</span> /path/to/ghidra/Ghidra/Debug/Debugger-rmi-trace/pypkg</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="ex">python3</span> <span class="at">-m</span> build</span></code></pre></div>
<p>This should output a <code>.whl</code> file. Send that over to the
target system and install it. If that doesnt work, then in the worst
case, copy the Python source over and add it to your
<code>PYTHONPATH</code>.</p>
<p>You may need to build them using the instructions above. The
dependencies are included in the Ghidra installation, but perhaps
something has gone missing. Search for files ending in <code>.whl</code>
or <code>.tar.gz</code>; they should be located in
<code>pypkg/dist</code> in various modules. If you are able to do local
debugging with Ghidra and <code>gdb</code>, then the source is
definitely present and functioning. To (re-)build the packages from
source:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">python3</span> <span class="at">-m</span> pip install build</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="bu">cd</span> /path/to/ghidra/Ghidra/Debug/Debugger-rmi-trace/pypkg</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="ex">python3</span> <span class="at">-m</span> build</span></code></pre></div>
<p>This should output a <code>.tar.gz</code> and a <code>.whl</code>
file under <code>pypkg/dist</code>. Send the <code>.whl</code> over to
the target system and <code>pip install</code> it. Do the same for
Debugger-agent-gdb. If that doesnt work, then in the worst case, copy
the Python source over and add it to your <code>PYTHONPATH</code>.</p>
</section>
<section id="the-python-import-ghidragdb-command-fails" class="level4">
<h4>The <code>python import ghidragdb</code> command fails</h4>
<p>Double-check that you have installed all the required packages and
their dependencies. A common forgotten or incorrectly-versioned
dependency is <code>protobuf</code>. We developed using
<code>protobuf==3.20.3</code>.</p>
<code>protobuf==3.20.3</code>. Its “sdist” package is distributed with
Ghidra under <code>Debugger-rmi-trace/pypkg/dist</code> for your
convenience.</p>
<p>It is also possible that <code>gdb</code> has embedded a different
version of the interpreter than the one that <code>python3</code>
provides. This can happen if you built GDB or Python yourself, or you
installed them from a non-standard repository. Check the actual path of
the Python library used by <code>gdb</code>:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="fu">ldd</span> <span class="va">$(</span><span class="fu">which</span> gdb<span class="va">)</span></span></code></pre></div>
<p>Or, inside <code>gdb</code>:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode gdb"><code class="sourceCode gdbsyntax"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>(gdb) python-interactive</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>&gt;&gt;&gt; import sys</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>&gt;&gt;&gt; sys.version</span></code></pre></div>
class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="fu">ldd</span> <span class="va">$(</span><span class="fu">which</span> gdb<span class="va">)</span></span></code></pre></div>
<p>Or, inside <code>gdb</code>:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode gdb"><code class="sourceCode gdbsyntax"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>(gdb) python-interactive</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>&gt;&gt;&gt; import sys</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>&gt;&gt;&gt; sys.version</span></code></pre></div>
<p>Suppose this identifies version 3.7. Retry the installation commands
using <code>python3.7 -m pip ...</code>. If you have multiple copies of
the same version in different locations, you may need to invoke
@ -296,8 +318,8 @@ the same version in different locations, you may need to invoke
<li><p>First, prepare the target. This time, you will need to start
<code>gdbserver</code> on the remote system manually. For demonstration,
we will listen on 10.0.0.1 port 12345:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ex">gdbserver</span> 10.0.0.1:12345 termmines</span></code></pre></div></li>
<div class="sourceCode" id="cb7"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ex">gdbserver</span> 10.0.0.1:12345 termmines</span></code></pre></div></li>
<li><p>From the launch menu, select <strong>remote
gdb</strong>.</p></li>
<li><p>Fill out the options appropriately. Notably, enter “10.0.0.1” for
@ -330,14 +352,14 @@ it.</p></li>
acceptors port number in the Connections window, e.g.,
“12345.”</p></li>
<li><p>Now, on the remote system, start <code>gdb</code> and type:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode gdb"><code class="sourceCode gdbsyntax"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>python import ghidragdb</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>file termmines</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a># set args, if you&#39;d like</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>ghidra trace connect 10.0.0.1:12345</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>ghidra trace start</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>ghidra trace sync-enable</span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>starti</span></code></pre></div></li>
<div class="sourceCode" id="cb8"><pre
class="sourceCode gdb"><code class="sourceCode gdbsyntax"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>python import ghidragdb</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>file termmines</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a># set args, if you&#39;d like</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>ghidra trace connect 10.0.0.1:12345</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>ghidra trace start</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>ghidra trace sync-enable</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>starti</span></code></pre></div></li>
</ol>
<p>At this point, most things will work the same as they would for a
local target. You may notice Ghidra has not given you a new terminal.

View File

@ -53,23 +53,41 @@ At this point, most things will work the same as they would for a local target.
In this configuration, Ghidra will be located in the user'ls local environment, while `gdb` and the specimen will be located in the target environment.
Notice that we are *not* using `gdbserver`.
We will connect the local Ghidra to the remote `gdb` by forwarding Trace RMI over SSH.
See the help (press **`F1`** on the **gdb via ssh** menu item for advantages and disadvantages of using this vs. `gdbserver`.
See the help (press **`F1`** on the **gdb via ssh** menu item for advantages and disadvantages of using this vs. `gdbserver`.)
1. First, prepare the target.
This is more involved than using `gdbserver`, since you will need to ensure `gdb` and the Trace RMI plugin for it are installed.
The packages, which should be included with Ghidra, are `ghidratrace` and `ghidragdb`.
If you installed `gdb` and `python3` from your distribution's repositories, installation of the Python packages should just be a matter of using `pip`:
The packages, which should be included with Ghidra, are `ghidratrace` and `ghidragdb`, but you may need to build them first.
If you installed `gdb` and `python3` from your distribution's repositories, installation of the Python packages should be straightfoward.
Search the Ghidra installation for files ending in `.whl`.
If the `ghidratrace` and `ghidragdb` packages are there, you can skip this build step and just transfer them to the target.
On the local system:
```bash
python3 -m pip install /path/to/ghidratrace....whl
python3 -m pip install build # unless you already have it
cd /path/to/ghidra/Ghidra/Debug/Debugger-rmi-trace/pypkg
python3 -m build
```
Chances are, GDB embeds the same Python, so they become importable from `gdb`:
This will output `.tar.gz` and `.whl` files under `pypkg/dist`.
Do the same for `Debugger-agent-gdb/pypkg`.
Transfer the resulting `.whl` files to the target, then on the target system:
```bash
python3 -m pip install /path/to/ghidratrace-[version].whl /path/to/ghidragdb-[version].whl
```
If you are offline, the dependencies are included in the `pypkg/dist` directory for each module.
Transfer and install them, too.
You may try `python -m pip install --no-index -f /path/to/packages ghidragdb`, if all the packages and dependencies are in the one directory.
Chances are, GDB embeds the same Python, so they become importable from GDB.
Test using `gdb` on the target system:
```gdb
python import ghidragdb
```
No news is good news!
You can quit GDB, since that was just for verifying the installation.
1. From the launch menu, select **gdb via ssh**.
@ -87,11 +105,11 @@ At this point, most things will work the same as they would for a local target.
#### I can't find the Python packages to install
These should be located in the Ghidra installation.
Search for files ending in `.whl`.
Alternatively, you can build the packages from source.
The source is included with Ghidra.
You may need to build them using the instructions above.
The dependencies are included in the Ghidra installation, but perhaps something has gone missing.
Search for files ending in `.whl` or `.tar.gz`; they should be located in `pypkg/dist` in various modules.
If you are able to do local debugging with Ghidra and `gdb`, then the source is definitely present and functioning.
To (re-)build the packages from source:
```bash
python3 -m pip install build
@ -99,8 +117,9 @@ cd /path/to/ghidra/Ghidra/Debug/Debugger-rmi-trace/pypkg
python3 -m build
```
This should output a `.whl` file.
Send that over to the target system and install it.
This should output a `.tar.gz` and a `.whl` file under `pypkg/dist`.
Send the `.whl` over to the target system and `pip install` it.
Do the same for Debugger-agent-gdb.
If that doesn't work, then in the worst case, copy the Python source over and add it to your `PYTHONPATH`.
#### The `python import ghidragdb` command fails
@ -108,6 +127,7 @@ If that doesn't work, then in the worst case, copy the Python source over and ad
Double-check that you have installed all the required packages and their dependencies.
A common forgotten or incorrectly-versioned dependency is `protobuf`.
We developed using `protobuf==3.20.3`.
Its "sdist" package is distributed with Ghidra under `Debugger-rmi-trace/pypkg/dist` for your convenience.
It is also possible that `gdb` has embedded a different version of the interpreter than the one that `python3` provides.
This can happen if you built GDB or Python yourself, or you installed them from a non-standard repository.

View File

@ -32,6 +32,7 @@ future releases.
</ul>
<li><a href="#Layout">Ghidra Installation Directory Layout</a></li>
<li><a href="#Build">Building Ghidra Native Components</a></li>
<li><a href="#DebuggerPython">Installing the Debuggers' Python Dependencies</a></li>
<li><a href="#Run">Running Ghidra</a></li>
<ul>
<li><a href="#RunGUI">GUI Mode</a></li>
@ -96,6 +97,10 @@ Ghidra team if you have a specific need.</p></blockquote>
</li>
</ul>
</ul>
<li>Python 3.9 or later (for Debugger support)</li>
<ul>
<li>This is available from <a href="https://python.org">Python.org</a> or most operating system's app stores or software repositories.</li>
</ul>
</ul>
<p>(<a href="#top">Back to Top</a>)</p>
@ -343,6 +348,19 @@ the relevant modules' <i>build/os/&lt;platform&gt;/</i> subdirectories, which wi
existing pre-built native binaries in the <i>os/&lt;platform&gt;/</i> subdirectories.</p>
<p>(<a href="#top">Back to Top</a>)</p>
<h2><a name="DebuggerPython"></a>Installing the Debugger's Python Dependencies</h2>
<p>The Debugger now uses Python to connect to the host platform's native debuggers. This requires
Python 3.9 or later and some additional packages. These packages are included in the distribution,
but you may still install them from PyPI if you prefer:</p>
<ul>
<li>psutil</li>
<li>protobuf==3.20.3</li>
<li>Pybag&gt;=2.2.10 (for WinDbg support)</li>
</ul>
<p>Different native debuggers have varying requirements, so you do not necessarily have to install
all of the above packages. Each connector will inform you of its specific requirements and where
they must be installed. In some cases, you may need to install packages on the target system.</p>
<h2><a name="Run"></a>Running Ghidra</h2>
<h3><a name="RunGUI"></a>GUI Mode</h3>
<ol>

View File

@ -48,6 +48,8 @@ To create the latest development build for your platform from this source reposi
##### Install build tools:
* [JDK 17 64-bit][jdk17]
* [Gradle 7.3+][gradle]
* [Python3][py3]
- [build][py3-build] module: `pip install build`
* make, gcc, and g++ (Linux/macOS-only)
* [Microsoft Visual Studio][vs] 2017+ or [Microsoft C++ Build Tools][vcbuildtools] with the
following components installed (Windows-only):
@ -128,6 +130,8 @@ source project.
[releases]: https://github.com/NationalSecurityAgency/ghidra/releases
[jdk17]: https://adoptium.net/temurin/releases
[gradle]: https://gradle.org/releases/
[py3]: https://www.python.org/downloads/
[py3-build]: https://pypi.org/project/build/
[vs]: https://visualstudio.microsoft.com/vs/community/
[vcbuildtools]: https://visualstudio.microsoft.com/visual-cpp-build-tools/
[eclipse]: https://www.eclipse.org/downloads/packages/

View File

@ -20,7 +20,7 @@ def checkPythonVersion(String pyCmd) {
exec {
commandLine pyCmd, "-c", "import sys; print('{0}.{1}'.format(*sys.version_info))"
standardOutput = stdout
standardError = null
errorOutput = OutputStream.nullOutputStream()
}
def version = "$stdout".strip()
return version
@ -33,7 +33,7 @@ def checkPythonVersion(String pyCmd) {
ext.SUPPORTED_PY_VERSIONS = ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12']
def findPython3() {
for (pyCmd in ['python3', 'python']) {
for (pyCmd in ['py', 'python3', 'python']) {
if (checkPythonVersion(pyCmd) in SUPPORTED_PY_VERSIONS) {
return pyCmd
}
@ -44,6 +44,19 @@ def findPython3() {
ext.PYTHON3 = findPython3()
ext.findPyDep = { name ->
File inDeps = file("${DEPS_DIR}/${project.name}/${name}")
File inRepo = file("${BIN_REPO}/${getGhidraRelativePath(project)}/${name}")
if (inDeps.exists()) {
return inDeps
}
if (inRepo.exists()) {
return inRepo
}
println("Warning: Could not find '${name}' for ${project.name}")
return inDeps
}
task assemblePyPackage(type: Copy) {
from "src/main/py"
into "build/pypkg/"
@ -51,25 +64,45 @@ task assemblePyPackage(type: Copy) {
rootProject.tasks.prepDev.dependsOn(assemblePyPackage)
task buildPyPackage(type: Exec) {
task buildPyPackage {
ext.dist = { file("build/pypkg/dist") }
inputs.files(assemblePyPackage)
outputs.dir(dist)
workingDir { "build/pypkg" }
commandLine PYTHON3, "-m", "build"
doLast {
File setuptools = project(":Debugger-rmi-trace").findPyDep(".")
exec {
workingDir { "build/pypkg" }
commandLine PYTHON3, "-m", "pip"
args "wheel", "-w", "dist/", "--no-index", "--no-deps"
args "-f", setuptools
args "."
}
}
}
// At the moment, any module with a python package also distributes it.
// We can separate this into `distributePythonPackage` later, if necessary.
rootProject.assembleDistribution {
dependsOn(buildPyPackage)
def p = this.project
def zipPath = getZipPath(p)
from (p.assemblePyPackage) {
exclude '**/*.pyc'
exclude '**/*.pyo'
exclude '**/__pycache__/**'
exclude 'dist/*.tar.gz'
into { zipPath + "/pypkg" }
}
}
ext.distributePyDep = { name ->
File dep = findPyDep(name)
def zipPath = getZipPath(project)
rootProject.assembleDistribution {
into ("${zipPath}/pypkg/dist") {
from dep
}
}
}

View File

@ -164,6 +164,54 @@ ext.deps = [
url: "https://github.com/NationalSecurityAgency/ghidra-data/raw/Ghidra_${RELEASE_VERSION}/FunctionID/vsOlder_x86.fidb",
sha256: "98605c6b6b9214a945d844e41c85860d54649a45bca7873ef6991c0e93720787",
destination: FID_DIR
],
[
name: "protobuf-3.20.3-py2.py3-none-any.whl",
url: "https://files.pythonhosted.org/packages/8d/14/619e24a4c70df2901e1f4dbc50a6291eb63a759172558df326347dce1f0d/protobuf-3.20.3-py2.py3-none-any.whl",
sha256: "a7ca6d488aa8ff7f329d4c545b2dbad8ac31464f1d8b1c87ad1346717731e4db",
destination: file("${DEPS_DIR}/Debugger-rmi-trace/")
],
[
name: "psutil-5.9.8.tar.gz",
url: "https://files.pythonhosted.org/packages/90/c7/6dc0a455d111f68ee43f27793971cf03fe29b6ef972042549db29eec39a2/psutil-5.9.8.tar.gz",
sha256: "6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c",
destination: file("${DEPS_DIR}/Debugger-rmi-trace/")
],
[
name: "setuptools-68.0.0-py3-none-any.whl",
url: "https://files.pythonhosted.org/packages/c7/42/be1c7bbdd83e1bfb160c94b9cafd8e25efc7400346cf7ccdbdb452c467fa/setuptools-68.0.0-py3-none-any.whl",
sha256: "11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f",
destination: file("${DEPS_DIR}/Debugger-rmi-trace/")
],
[
name: "wheel-0.37.1-py2.py3-none-any.whl",
url: "https://files.pythonhosted.org/packages/27/d6/003e593296a85fd6ed616ed962795b2f87709c3eee2bca4f6d0fe55c6d00/wheel-0.37.1-py2.py3-none-any.whl",
sha256: "4bdcd7d840138086126cd09254dc6195fb4fc6f01c050a1d7236f2630db1d22a",
destination: file("${DEPS_DIR}/Debugger-rmi-trace/")
],
[
name: "Pybag-2.2.10-py3-none-any.whl",
url: "https://files.pythonhosted.org/packages/2d/e0/f877c91e036fcaed2a827f80d6cbdf1d26cffc3333c9ebda31c55c45f050/Pybag-2.2.10-py3-none-any.whl",
sha256: "81cf1e33dd667dd217dc56a123326796e6799b8569f2c6efb78c16375caf9b2b",
destination: file("${DEPS_DIR}/Debugger-agent-dbgeng/")
],
[
name: "capstone-5.0.1-py3-none-win_amd64.whl",
url: "https://files.pythonhosted.org/packages/d0/dd/b28df50316ca193dd1275a4c47115a720796d9e1501c1888c4bfa5dc2260/capstone-5.0.1-py3-none-win_amd64.whl",
sha256: "1bfa5c81e6880caf41a31946cd6d2d069c048bcc22edf121254b501a048de675",
destination: file("${DEPS_DIR}/Debugger-agent-dbgeng/")
],
[
name: "comtypes-1.4.1-py3-none-any.whl",
url: "https://files.pythonhosted.org/packages/50/8f/518a37381e55a8857a638afa86143efa5508434613541402d20611a1b322/comtypes-1.4.1-py3-none-any.whl",
sha256: "a208a0e3ca1c0a5362735da0ff661822801dce87312b894d7d752add010a21b0",
destination: file("${DEPS_DIR}/Debugger-agent-dbgeng/")
],
[
name: "pywin32-306-cp312-cp312-win_amd64.whl",
url: "https://files.pythonhosted.org/packages/83/1c/25b79fc3ec99b19b0a0730cc47356f7e2959863bf9f3cd314332bddb4f68/pywin32-306-cp312-cp312-win_amd64.whl",
sha256: "37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e",
destination: file("${DEPS_DIR}/Debugger-agent-dbgeng/")
]
]

View File

@ -0,0 +1,31 @@
This is the software license for Capstone disassembly framework.
Capstone has been designed & implemented by Nguyen Anh Quynh <aquynh@gmail.com>
See http://www.capstone-engine.org for further information.
Copyright (c) 2013, COSEINC.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the developer(s) nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

29
licenses/BSD-3-PSUTIL.txt Normal file
View File

@ -0,0 +1,29 @@
BSD 3-Clause License
Copyright (c) 2009, Jay Loden, Dave Daeschler, Giampaolo Rodola
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the psutil authors nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,279 @@
A. HISTORY OF THE SOFTWARE
==========================
Python was created in the early 1990s by Guido van Rossum at Stichting
Mathematisch Centrum (CWI, see https://www.cwi.nl) in the Netherlands
as a successor of a language called ABC. Guido remains Python's
principal author, although it includes many contributions from others.
In 1995, Guido continued his work on Python at the Corporation for
National Research Initiatives (CNRI, see https://www.cnri.reston.va.us)
in Reston, Virginia where he released several versions of the
software.
In May 2000, Guido and the Python core development team moved to
BeOpen.com to form the BeOpen PythonLabs team. In October of the same
year, the PythonLabs team moved to Digital Creations, which became
Zope Corporation. In 2001, the Python Software Foundation (PSF, see
https://www.python.org/psf/) was formed, a non-profit organization
created specifically to own Python-related Intellectual Property.
Zope Corporation was a sponsoring member of the PSF.
All Python releases are Open Source (see https://opensource.org for
the Open Source Definition). Historically, most, but not all, Python
releases have also been GPL-compatible; the table below summarizes
the various releases.
Release Derived Year Owner GPL-
from compatible? (1)
0.9.0 thru 1.2 1991-1995 CWI yes
1.3 thru 1.5.2 1.2 1995-1999 CNRI yes
1.6 1.5.2 2000 CNRI no
2.0 1.6 2000 BeOpen.com no
1.6.1 1.6 2001 CNRI yes (2)
2.1 2.0+1.6.1 2001 PSF no
2.0.1 2.0+1.6.1 2001 PSF yes
2.1.1 2.1+2.0.1 2001 PSF yes
2.1.2 2.1.1 2002 PSF yes
2.1.3 2.1.2 2002 PSF yes
2.2 and above 2.1.1 2001-now PSF yes
Footnotes:
(1) GPL-compatible doesn't mean that we're distributing Python under
the GPL. All Python licenses, unlike the GPL, let you distribute
a modified version without making your changes open source. The
GPL-compatible licenses make it possible to combine Python with
other software that is released under the GPL; the others don't.
(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
because its license has a choice of law clause. According to
CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
is "not incompatible" with the GPL.
Thanks to the many outside volunteers who have worked under Guido's
direction to make these releases possible.
B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
===============================================================
Python software and documentation are licensed under the
Python Software Foundation License Version 2.
Starting with Python 3.8.6, examples, recipes, and other code in
the documentation are dual licensed under the PSF License Version 2
and the Zero-Clause BSD license.
Some software incorporated into Python is under different licenses.
The licenses are listed with code falling under that license.
PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
--------------------------------------------
1. This LICENSE AGREEMENT is between the Python Software Foundation
("PSF"), and the Individual or Organization ("Licensee") accessing and
otherwise using this software ("Python") in source or binary form and
its associated documentation.
2. Subject to the terms and conditions of this License Agreement, PSF hereby
grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
analyze, test, perform and/or display publicly, prepare derivative works,
distribute, and otherwise use Python alone or in any derivative version,
provided, however, that PSF's License Agreement and PSF's notice of copyright,
i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Python Software Foundation;
All Rights Reserved" are retained in Python alone or in any derivative version
prepared by Licensee.
3. In the event Licensee prepares a derivative work that is based on
or incorporates Python or any part thereof, and wants to make
the derivative work available to others as provided herein, then
Licensee hereby agrees to include in any such work a brief summary of
the changes made to Python.
4. PSF is making Python available to Licensee on an "AS IS"
basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
INFRINGE ANY THIRD PARTY RIGHTS.
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
6. This License Agreement will automatically terminate upon a material
breach of its terms and conditions.
7. Nothing in this License Agreement shall be deemed to create any
relationship of agency, partnership, or joint venture between PSF and
Licensee. This License Agreement does not grant permission to use PSF
trademarks or trade name in a trademark sense to endorse or promote
products or services of Licensee, or any third party.
8. By copying, installing or otherwise using Python, Licensee
agrees to be bound by the terms and conditions of this License
Agreement.
BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
-------------------------------------------
BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
Individual or Organization ("Licensee") accessing and otherwise using
this software in source or binary form and its associated
documentation ("the Software").
2. Subject to the terms and conditions of this BeOpen Python License
Agreement, BeOpen hereby grants Licensee a non-exclusive,
royalty-free, world-wide license to reproduce, analyze, test, perform
and/or display publicly, prepare derivative works, distribute, and
otherwise use the Software alone or in any derivative version,
provided, however, that the BeOpen Python License is retained in the
Software, alone or in any derivative version prepared by Licensee.
3. BeOpen is making the Software available to Licensee on an "AS IS"
basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
INFRINGE ANY THIRD PARTY RIGHTS.
4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
5. This License Agreement will automatically terminate upon a material
breach of its terms and conditions.
6. This License Agreement shall be governed by and interpreted in all
respects by the law of the State of California, excluding conflict of
law provisions. Nothing in this License Agreement shall be deemed to
create any relationship of agency, partnership, or joint venture
between BeOpen and Licensee. This License Agreement does not grant
permission to use BeOpen trademarks or trade names in a trademark
sense to endorse or promote products or services of Licensee, or any
third party. As an exception, the "BeOpen Python" logos available at
http://www.pythonlabs.com/logos.html may be used according to the
permissions granted on that web page.
7. By copying, installing or otherwise using the software, Licensee
agrees to be bound by the terms and conditions of this License
Agreement.
CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
---------------------------------------
1. This LICENSE AGREEMENT is between the Corporation for National
Research Initiatives, having an office at 1895 Preston White Drive,
Reston, VA 20191 ("CNRI"), and the Individual or Organization
("Licensee") accessing and otherwise using Python 1.6.1 software in
source or binary form and its associated documentation.
2. Subject to the terms and conditions of this License Agreement, CNRI
hereby grants Licensee a nonexclusive, royalty-free, world-wide
license to reproduce, analyze, test, perform and/or display publicly,
prepare derivative works, distribute, and otherwise use Python 1.6.1
alone or in any derivative version, provided, however, that CNRI's
License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
1995-2001 Corporation for National Research Initiatives; All Rights
Reserved" are retained in Python 1.6.1 alone or in any derivative
version prepared by Licensee. Alternately, in lieu of CNRI's License
Agreement, Licensee may substitute the following text (omitting the
quotes): "Python 1.6.1 is made available subject to the terms and
conditions in CNRI's License Agreement. This Agreement together with
Python 1.6.1 may be located on the internet using the following
unique, persistent identifier (known as a handle): 1895.22/1013. This
Agreement may also be obtained from a proxy server on the internet
using the following URL: http://hdl.handle.net/1895.22/1013".
3. In the event Licensee prepares a derivative work that is based on
or incorporates Python 1.6.1 or any part thereof, and wants to make
the derivative work available to others as provided herein, then
Licensee hereby agrees to include in any such work a brief summary of
the changes made to Python 1.6.1.
4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
INFRINGE ANY THIRD PARTY RIGHTS.
5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
6. This License Agreement will automatically terminate upon a material
breach of its terms and conditions.
7. This License Agreement shall be governed by the federal
intellectual property law of the United States, including without
limitation the federal copyright law, and, to the extent such
U.S. federal law does not apply, by the law of the Commonwealth of
Virginia, excluding Virginia's conflict of law provisions.
Notwithstanding the foregoing, with regard to derivative works based
on Python 1.6.1 that incorporate non-separable material that was
previously distributed under the GNU General Public License (GPL), the
law of the Commonwealth of Virginia shall govern this License
Agreement only as to issues arising under or with respect to
Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this
License Agreement shall be deemed to create any relationship of
agency, partnership, or joint venture between CNRI and Licensee. This
License Agreement does not grant permission to use CNRI trademarks or
trade name in a trademark sense to endorse or promote products or
services of Licensee, or any third party.
8. By clicking on the "ACCEPT" button where indicated, or by copying,
installing or otherwise using Python 1.6.1, Licensee agrees to be
bound by the terms and conditions of this License Agreement.
ACCEPT
CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
--------------------------------------------------
Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
The Netherlands. All rights reserved.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of Stichting Mathematisch
Centrum or CWI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ZERO-CLAUSE BSD LICENSE FOR CODE IN THE PYTHON DOCUMENTATION
----------------------------------------------------------------------
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

View File

@ -3,12 +3,14 @@ Apache_License_2.0.txt||LICENSE||||END|
Apache_License_2.0_with_LLVM_Exceptions.txt||LICENSE||||END|
BSD-2-ORACLE.txt||LICENSE||||END|
BSD-3-APPLE.txt||LICENSE||||END|
BSD-3-CAPSTONE.txt||LICENSE||||END|
BSD-3-GOOGLE.txt||LICENSE||||END|
BSD-3-GRUVER.txt||LICENSE||||END|
BSD-3-HAMCREST.txt||LICENSE||||END|
BSD-3-JUNG.txt||LICENSE||||END|
BSD-3-ORACLE.txt||LICENSE||||END|
BSD-3-PARR-HARWELL.txt||LICENSE||||END|
BSD-3-PSUTIL.txt||LICENSE||||END|
BSD.txt||LICENSE||||END|
Bouncy_Castle_License.txt||LICENSE||||END|
Creative_Commons_Attribution_2.5.html||LICENSE||||END|
@ -30,5 +32,6 @@ Oxygen_Icons_-_LGPL_3.0.txt||LICENSE||||END|
PostgresqlJDBC_License.txt||LICENSE||||END|
Postgresql_License.txt||LICENSE||||END|
Public_Domain.txt||LICENSE||||END|
Python_Software_Foundation_License.txt||LICENSE||||END|
Tango_Icons_-_Public_Domain.txt||LICENSE||||END|
zlib_License.txt||LICENSE||||END|