1
0
mirror of https://github.com/hashcat/hashcat.git synced 2025-07-02 04:42:36 +00:00

The Assimilation Bridge (Additional Documents)

This commit is contained in:
Jens Steube 2025-05-29 15:10:09 +02:00
parent 0d8c8cba2f
commit c607910f1c
2 changed files with 277 additions and 0 deletions

View File

@ -0,0 +1,133 @@
## Developer Section
The following section is for plugin and bridge developers. It contains low-level implementation details. It's a first draft, expect more details to fill in soon.
---
## Plugin Integration and Bridge Registration
Plugins can opt in to bridge support by adding:
```c
static const u64 BRIDGE_TYPE = BRIDGE_TYPE_MATCH_TUNINGS
| BRIDGE_TYPE_LAUNCH_LOOP;
static const char *BRIDGE_NAME = "scrypt_jane";
```
* `BRIDGE_NAME` tells Hashcat which bridge to load (e.g., `bridge_scrypt_jane.so`).
* `BRIDGE_TYPE` indicates which backend kernel functions the bridge will override:
* `BRIDGE_TYPE_LAUNCH_LOOP`
* `BRIDGE_TYPE_LAUNCH_LOOP2`
Hashcat loads the bridge dynamically and uses it for any declared replacements. It's the developer's responsibility to ensure compatibility. That typically means the handling of the `tmps` variable relevant in the `kernel_loop` and how it changes over time. Hashcat will take care of copying the data from and to the compute backend (GPU) buffers.
---
## How Bridges Work
When Hashcat starts with a plugin that specifies a bridge, it loads the bridge and invokes its initialization function. The bridge must then discover its internal compute units, called *bridge units*. This is done manually by the bridge developer.
Each bridge unit maps to one virtual backend device, which allows asynchronous and independent parallel execution.
### Virtual Backend Devices
* Use `-Y` to define how many virtual backend devices to create.
* Use `-R` to bind these virtual devices to a physical backend host (new in v7).
This structure supports mixed-performance hardware without bottlenecks.
---
## Writing a Bridge
### File Layout
Bridges live in the `src/bridges/` directory and consist of a `.c` file and a `.mk` build rule:
```
src/bridges/bridge_scrypt_jane.c
src/bridges/bridge_scrypt_jane.mk
```
Example build rule:
```
bridges/bridge_scrypt_jane.so: src/bridges/bridge_scrypt_jane.c
```
Hashcat will automatically load this shared object based on the plugin's `BRIDGE_NAME`.
### Required Function Exports
```c
bridge_ctx->platform_init = platform_init;
bridge_ctx->platform_term = platform_term;
bridge_ctx->get_unit_count = get_unit_count;
bridge_ctx->get_unit_info = get_unit_info;
bridge_ctx->get_workitem_count = get_workitem_count;
bridge_ctx->thread_init = BRIDGE_DEFAULT;
bridge_ctx->thread_term = BRIDGE_DEFAULT;
bridge_ctx->salt_prepare = salt_prepare;
bridge_ctx->salt_destroy = salt_destroy;
bridge_ctx->launch_loop = launch_loop;
bridge_ctx->launch_loop2 = BRIDGE_DEFAULT;
bridge_ctx->st_update_hash = BRIDGE_DEFAULT;
bridge_ctx->st_update_pass = BRIDGE_DEFAULT;
```
> Use `BRIDGE_DEFAULT` when no function implementation is required.
### Mandatory Functions
The following functions must be defined:
```c
CHECK_MANDATORY (bridge_ctx->platform_init);
CHECK_MANDATORY (bridge_ctx->platform_term);
CHECK_MANDATORY (bridge_ctx->get_unit_count);
CHECK_MANDATORY (bridge_ctx->get_unit_info);
CHECK_MANDATORY (bridge_ctx->get_workitem_count);
```
### Function Roles
**platform\_init**
Called at startup. Responsible for initialization. This might include loading libraries, connecting to remote endpoints, or setting up hardware APIs. Returns a context pointer.
**platform\_term**
Final cleanup logic. Frees any context data allocated during initialization.
**get\_unit\_count**
Returns the number of available units. For example, return `2` if two FPGAs are detected.
**get\_unit\_info**
Returns a human-readable description of a unit, like "Python v3.13.3".
**get\_workitem\_count**
Returns the number of password candidates to process per invocation.
**thread\_init**
Optional. Use for per-thread setup, such as creating a new Python interpreter.
**thread\_term**
Optional. Use for per-thread cleanup.
**salt\_prepare**
Called once per salt. Useful for preprocessing or storing large salt/esalt buffers.
**salt\_destroy**
Optional cleanup routine for any salt-specific memory.
**launch\_loop**
Main compute function. Replaces the traditional `_loop` kernel.
**launch\_loop2**
Secondary compute function. Replaces `_loop2` if needed.
**st\_update\_hash**
Optionally override the module's default self-test hash.
**st\_update\_pass**
Optionally override the module's default self-test password.

View File

@ -0,0 +1,144 @@
# Hashcat Python Plugin Developer Guide
## Introduction
This guide walks you through building custom hash modes in **pure Python** using Hashcat v7's Python plugin from the new assimilation bridge. Whether you're experimenting with a new algorithm, supporting a proprietary format, hacking a prototype, or just writing hashing logic in a high-level language, this plugin interface makes it fast and easy.
No C required. No recompilation. Just write your logic in pure python code in `calc_hash()`.
You can use any python modules you want.
---
## Quick Start
Hashcat mode `73000` is preconfigured to load a generic Python plugin source file from `Python/generic_hash_mp.py`:
```
hashcat -m 73000 -b
```
You can edit the `Python/generic_hash_mp.py`, or override the plugin source file with:
```
hashcat -m 73000 --bridge-parameter1=my_hash.py hash.txt wordlist.txt ...
```
---
## Yescrypt in One Line
### Generate a Yescrypt Test Hash
```
echo password | mkpasswd -s -m yescrypt
```
Example output:
```
$y$j9T$uxVFACnNnGBakt9MLrpFf0$SmbSZAge5oa1BfHPBxYGq3mITgHeO/iG2Mdfgo93UN0
```
### Prepare Hash Line for Hashcat
```
$y$j9T$uxVFACnNnGBakt9MLrpFf0$SmbSZAge5oa1BfHPBxYGq3mITgHeO/iG2Mdfgo93UN0*$y$j9T$uxVFACnNnGBakt9MLrpFf0$
```
(Use the full hash before the `*`, and the salt portion after the `*`.)
### Plugin Code
Install the module:
```
pip install pyescrypt
```
Then in your plugin (either `generic_hash_mp.py` for -m 73000 or `generic_hash_sp.py` for -m 72000)
```python
from pyescrypt import Yescrypt,Mode
# Self-Test pair
ST_HASH = "$y$j9T$uxVFACnNnGBakt9MLrpFf0$SmbSZAge5oa1BfHPBxYGq3mITgHeO/iG2Mdfgo93UN0*$y$j9T$uxVFACnNnGBakt9MLrpFf0$"
ST_PASS = "password"
def calc_hash(password: bytes, salt: dict) -> str:
return Yescrypt(n=4096, r=32, p=1, mode=Mode.MCF).digest(password=password, settings=hcshared.get_salt_buf(salt)).decode('utf8')
```
That's it - full Yescrypt support in Hashcat with a single line of code.
### Run
```
hashcat -m 73000 yescrypt.hash wordlist.txt
```
---
## Debugging Without Hashcat
You can run your plugin as a standalone script:
```
python3 generic_hash.py
```
It reads passwords from stdin and prints the result of `calc_hash()`:
```
echo "password" | python3 generic_hash_mp.py
```
Note that you probably want to inline the correct salt value, see the `main` section in the code.
---
## Windows and Linux/macOS
There are significant differences between Windows and Linux/macOS when embedding Python as done here. It's a complex issue, and we hope future Python developments toward a fully GIL-free mode will resolve it. For now, we must work around platform-specific behavior.
### On Windows
The `multiprocessing` module is not fully supported in this embedded setup. As a result, only one thread can run effectively. While the `threading` module does work, most cryptographic functions like `sha256()` block the GIL. CPU-intensive algorithms such as 10,000 iterations of `sha256()` will monopolize the GIL, making the program effectively single-threaded.
### On Linux/macOS
The `multiprocessing` module works correctly, enabling full CPU utilization through parallel worker processes.
### Free-threaded Python (3.13+)
Python 3.13 introduces optional GIL-free support. This allows multithreading to work even in embedded Python, both on Linux and Windows. Hashcat leverages this through two modes:
- `-m 72000`: Uses free-threaded Python (no multiprocessing)
- `-m 73000`: Uses GIL-bound Python with multiprocessing
Multiprocessing (73000) supports most modules and is generally better for real-world workloads, but it works only on Linux. Developers may use `-m 73000` on Linux for performance and `-m 72000` on Windows for development, provided their code does not rely on modules that require `cffi` because this as of now lacks support for running with Python free-treaded ABI.
---
## Python 3.13 Requirement
The `-m 72000` mode requires Python 3.13 due to its reliance on the new free-threading feature. This feature is not available in earlier versions.
### Why Python 3.13 Isn't Preinstalled
Several Linux distributions, including Ubuntu 24.04, do not ship with Python 3.13 because it was released after the distros feature freeze. You will likely need to install it manually.
### Installing Python 3.13
**On Windows**: Use the official installer and ensure you check the "Install free-threaded" option - it's disabled by default.
**On Linux/macOS**: Use `pyenv`. It's the easiest way to install and manage Python versions:
```
pyenv install 3.13t
pyenv local 3.13t
```
This makes it easy to manage `pip` packages without global installs or virtual environments.