A windows dll injection library written in Rust.
| Injector Process | Target Process | Supported? |
| ---------------- | -------------- | ------------------------------------------ |
| 32-bit | 32-bit | Yes |
| 32-bit | 64-bit | No |
| 64-bit | 32-bit | Yes (requires feature into-x86-from-x64
) |
| 64-bit | 64-bit | Yes |
This crate allows you to inject and eject a DLL into a target process.
The example below will inject and then eject injection_payload.dll
into the process called "ExampleProcess".
```rust norun use dllsyringe::{Syringe, process::OwnedProcess};
// find target process by name let targetprocess = OwnedProcess::findfirstbyname("ExampleProcess").unwrap();
// create a new syringe for the target process let syringe = Syringe::forprocess(targetprocess);
// inject the payload into the target process let injectedpayload = syringe.inject("injectionpayload.dll").unwrap();
// do something else
// eject the payload from the target (optional) syringe.eject(injected_payload).unwrap(); ```
This crate supports two mechanisms for rpc. Both only work one-way for calling exported functions in the target process and are only intended for one-time initialization usage. For extended communication a dedicated rpc library should be used.
| | RemotePayloadProcedure
| RemoteRawProcedure
|
| ---------------- | ------------------------------ | ------------------------------------------ |
| Feature | rpc-payload
| rpc-raw
|
| Argument and Return Requirements | Serialize + DeserializeOwned
| Copy
, Argument size has to be smaller than usize
in target process |
| Function Definition | Using macro payload_procedure!
| Any extern "system"
or extern "C"
with #[no_mangle]
|
A rpc mechanism based on bincode
.
The target procedure must be defined using the payload_function!
macro (requires the payload-utils
feature).
The definition of an exported add
function could look like this:
rust
dll_syringe::payload_function! {
fn add(a: f64, b: f64) -> f64 {
a + b
}
}
The code of the injector/caller could looks like this: ```rust norun use dllsyringe::{Syringe, process::OwnedProcess};
// find target process by name let targetprocess = OwnedProcess::findfirstbyname("ExampleProcess").unwrap();
// create a new syringe for the target process let syringe = Syringe::forprocess(targetprocess);
// inject the payload into the target process let injectedpayload = syringe.inject("injectionpayload.dll").unwrap();
let remoteadd = syringe.getpayloadprocedure::
// eject the payload from the target (optional) syringe.eject(injected_payload).unwrap(); ```
This mechanism is based on dynamically generated assembly code.
The target procedure can be any exported function as long as it uses either the system
or C
calling convention.
This means that even Win32 functions can be called directly.
The definition of an exported add
function could look like this:
```rust
extern "system" fn add(a: f64, b: f64) -> f64 { a + b } ```
The code of the injector/caller could looks like this: ```rust norun use dllsyringe::{Syringe, process::OwnedProcess};
// find target process by name let targetprocess = OwnedProcess::findfirstbyname("ExampleProcess").unwrap();
// create a new syringe for the target process let syringe = Syringe::forprocess(targetprocess);
// inject the payload into the target process let injectedpayload = syringe.inject("injectionpayload.dll").unwrap();
let remoteadd = syringe.getrawprocedure::
// eject the payload from the target (optional) syringe.eject(injected_payload).unwrap(); ```
Licensed under MIT license (LICENSE or http://opensource.org/licenses/MIT)
Inspired by Reloaded.Injector from Sewer.