feat: add MSVC PIC support, update to Rust 2024

This commit is contained in:
safedv
2025-03-08 11:50:06 +01:00
parent 06d7f7dc96
commit 7e4d99503a
9 changed files with 138 additions and 55 deletions
+37
View File
@@ -0,0 +1,37 @@
# CHANGELOG
## **[0.1.2]** - 2025-08-03
### Features:
- **MSVC Support (PIC)**: RustiveDump can now be compiled using the MSVC toolchain as **Position Independent Code (PIC)**, allowing for more flexibility in cross-compilation scenarios.
- **Smaller Shellcode Size**: With the optimizations for MSVC, the shellcode size has been reduced to **14KB** when enabling features like **xor** and **remote**.
- **Updated to Rust 2024 Edition**: RustiveDump now supports the **Rust 2024 edition**.
---
## **[0.1.1]** - 2024-10-14
### Features:
- **Position Independent Code (PIC)**: RustiveDump can now be compiled as **Position Independent Code (PIC)**, making it possible to use the tool as **shellcode**. This flexibility allows RustiveDump to be embedded in other projects or used in memory-only payloads.
- **Refactored Code**: Significant code refactoring to improve the structure and efficiency of the tool.
- **Shellcode Size**: The shellcode, with the `xor` and `remote` features enabled, is **15KB** in size.
---
## **[0.1.0]** - 2024-10-06
### Initial Release:
- **Memory Dumping via NT System Calls**: RustiveDump uses only **NT system calls** to access the memory of **lsass.exe**.
- **Minimal Minidump Creation**: The tool creates a minimalistic minidump file containing only essential information, such as:
- **SystemInfo Stream**: Provides OS version and architecture details.
- **ModuleList Stream**: Lists the modules loaded in **lsass.exe**.
- **Memory64List Stream**: Contains the memory regions from **lsass.exe**.
- **XOR Encryption**: Option to encrypt the minidump file using XOR before saving or transmitting it.
- **Remote File Transmission**: The tool can send the dump file directly to a remote server using **Winsock** API calls, allowing remote exfiltration.
- **Debug Logging**: Optional debug mode to provide detailed logs of each step taken during the memory dump creation.
- **No-Std and CRT-Independent**: RustiveDump is built with the `no_std` feature in Rust, removing the dependency on the standard library. It is also independent of the **C Runtime (CRT)**.
---
Generated
+2 -2
View File
@@ -11,6 +11,6 @@ dependencies = [
[[package]]
name = "panic-halt"
version = "0.2.0"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812"
checksum = "a513e167849a384b7f9b746e517604398518590a9142f4846a32e3c2a4de7b11"
+2 -2
View File
@@ -1,11 +1,11 @@
[package]
name = "RustiveDump"
version = "0.1.1"
edition = "2021"
edition = "2024"
authors = ["safedv"]
[dependencies]
panic-halt = "0.2.0"
panic-halt = "1.0.0"
[profile.dev]
panic = "abort"
+48 -22
View File
@@ -2,54 +2,80 @@
skip_core_tasks = true
[env]
TARGET = "x86_64-pc-windows-gnu"
PIC_RUSTFLAGS = "-C link-arg=-nostdlib -C codegen-units=1 -C link-arg=-fno-ident -C link-arg=-fpack-struct=8 -C link-arg=-Wl,--gc-sections -C link-arg=-falign-jumps=1 -C link-arg=-w -C link-arg=-falign-labels=1 -C relocation-model=pic -C link-arg=-Wl,-T./Linker.ld,--build-id=none -C link-arg=-Wl,-s,--no-seh,--enable-stdcall-fixup -C link-arg=-Wl,--subsystem,console -C link-arg=-nostartfiles -C link-arg=-Wl,-e_start"
EXE_RUSTFLAGS = "-C link-arg=-nostdlib -C link-arg=-Wl,--gc-sections -C link-arg=-Wl,--subsystem,console -C link-arg=-nostartfiles -C link-arg=-Wl,-e_start"
FEATURES = ""
# Target platforms
TARGET_GNU = "x86_64-pc-windows-gnu"
TARGET_MSVC = "x86_64-pc-windows-msvc"
# Flags for GNU PIC and EXE builds
RUSTFLAGS_GNU_PIC = "-C link-arg=-nostdlib -C codegen-units=1 -C link-arg=-fno-ident -C link-arg=-fpack-struct=8 -C link-arg=-Wl,--gc-sections -C link-arg=-falign-jumps=1 -C link-arg=-w -C link-arg=-falign-labels=1 -C relocation-model=pic -C link-arg=-Wl,-T./Linker.ld,--build-id=none -C link-arg=-Wl,-s,--no-seh,--enable-stdcall-fixup -C link-arg=-Wl,--subsystem,console -C link-arg=-nostartfiles -C link-arg=-Wl,-e_start"
RUSTFLAGS_GNU_EXE = "-C link-arg=-nostdlib -C link-arg=-Wl,--gc-sections -C link-arg=-Wl,--subsystem,console -C link-arg=-nostartfiles -C link-arg=-Wl,-e_start"
# Flags for MSVC builds
RUSTFLAGS_MSVC_PIC = "-C codegen-units=1 -C strip=symbols -C opt-level=z -C link-arg=/NODEFAULTLIB -C link-arg=/ENTRY:_start -C link-arg=/SUBSYSTEM:CONSOLE -C link-arg=/OPT:REF,ICF -C link-arg=/SAFESEH:NO -C link-arg=/DEBUG:NONE -C link-arg=/FILEALIGN:512 -C link-arg=/ALIGN:16 -C link-arg=/SECTION:.bss,D -C link-arg=/SECTION:.edata,D -C link-arg=/SECTION:.idata,D -C link-arg=/SECTION:.pdata,D -C link-arg=/SECTION:.xdata,D"
[tasks.default]
description = "Default task that builds the project."
description = "Default build task: builds the project as a GNU executable."
dependencies = ["build"]
[tasks.build]
description = "Clean, Builds, strips, and objcopy."
description = "Builds the project as a GNU executable, strips unnecessary sections."
dependencies = ["clean", "cargo-build", "strip"]
[tasks.clean]
description = "Cleans the project and removes the binary file."
description = "Cleans the project directory, removing old binaries."
script = [
"cargo clean"
]
[tasks.cargo-build]
description = "Build the project using cargo with custom rustflags."
description = "Compiles the project for the GNU target (exe)."
command = "cargo"
args = ["build", "--release", "--target", "${TARGET}", "--features", "${FEATURES}"]
env = { "RUSTFLAGS" = "${EXE_RUSTFLAGS}" }
args = ["build", "--release", "--target", "${TARGET_GNU}", "--features", "${FEATURES}"]
env = { "RUSTFLAGS" = "${RUSTFLAGS_GNU_EXE}" }
[tasks.strip]
description = "Strips unnecessary sections from the binary."
description = "Strips unneeded sections from the GNU binary."
command = "strip"
args = ["-s", "--strip-unneeded", "-x", "-X", "target/x86_64-pc-windows-gnu/release/RustiveDump.exe"]
args = ["-s", "--strip-unneeded", "-x", "-X", "target/${TARGET_GNU}/release/RustiveDump.exe"]
[tasks.pic]
description = "Builds with PIC enabled."
dependencies = ["cleanpic", "cargo-build-pic", "strip", "objcopy"]
[tasks.pic-gnu]
description = "Builds the project as Shellcode (PIC) for the GNU target."
dependencies = ["cleanpic", "cargo-build-pic-gnu", "strip", "objcopy"]
[tasks.cleanpic]
description = "Cleans the project and removes the binary file."
description = "Cleans the project and removes the old PIC binary."
script = [
"cargo clean",
"rm -f RustiveDump.bin"
]
[tasks.cargo-build-pic]
description = "Build the project using cargo with PIC enabled."
[tasks.cargo-build-pic-gnu]
description = "Compiles the project as PIC for the GNU target."
command = "cargo"
args = ["build", "--release", "--target", "${TARGET}", "--features", "${FEATURES}"]
env = { "RUSTFLAGS" = "${PIC_RUSTFLAGS}" }
args = ["build", "--release", "--target", "${TARGET_GNU}", "--features", "${FEATURES}"]
env = { "RUSTFLAGS" = "${RUSTFLAGS_GNU_PIC}" }
[tasks.objcopy]
description = "Converts the binary to a .bin file using objcopy."
description = "Converts the GNU binary to a .bin file using objcopy."
command = "objcopy"
args = ["-O", "binary", "target/x86_64-pc-windows-gnu/release/RustiveDump.exe", "RustiveDump.bin"]
args = ["-O", "binary", "target/${TARGET_GNU}/release/RustiveDump.exe", "RustiveDump.bin"]
[tasks.pic-msvc]
description = "Builds the project as Shellcode (PIC) for the MSVC target."
dependencies = ["clean", "cargo-build-pic-msvc", "strip-msvc", "objcopy-msvc"]
[tasks.cargo-build-pic-msvc]
description = "Compiles the project as PIC for the MSVC target."
command = "cargo"
args = ["build", "--release", "--target", "${TARGET_MSVC}", "--features", "${FEATURES}"]
env = { "RUSTFLAGS" = "${RUSTFLAGS_MSVC_PIC}" }
[tasks.strip-msvc]
description = "Strips unneeded sections from the MSVC binary."
command = "strip"
args = ["-s", "--strip-unneeded", "-x", "-X", "target/${TARGET_MSVC}/release/RustiveDump.exe"]
[tasks.objcopy-msvc]
description = "Converts the MSVC binary to a .bin file using objcopy."
command = "objcopy"
args = ["-O", "binary", "target/${TARGET_MSVC}/release/RustiveDump.exe", "RustiveDump.bin"]
+37 -21
View File
@@ -1,37 +1,44 @@
## **RustiveDump**
**RustiveDump** is a Rust-based tool designed to dump the memory of the **lsass.exe** process using **only NT system calls**.
It creates a minimal minidump file from scratch, containing essential components like **SystemInfo**, **ModuleList**, and **Memory64List**, with support for **XOR encryption** and **remote transmission**.
Additionally, RustiveDump now implements the design of [Rustic64](https://github.com/safedv/Rustic64), allowing it to be compiled as **Position Independent Code (PIC)**, making it more versatile.
**RustiveDump** is a Rust-based tool designed to dump the memory of the **lsass.exe** process using **only NT system calls**. It creates a minimal minidump file from scratch, containing essential components like **SystemInfo**, **ModuleList**, and **Memory64List**, with support for **XOR encryption** and **remote transmission**.
This project is a personal learning experience, focusing on leveraging native Windows APIs for memory dumping and building a minimalistic minidump file entirely from the ground up.
###### Shellcode (PIC) - v.0.1.1
RustiveDump now implements the design of [Rustic64](https://github.com/safedv/Rustic64), allowing it to be compiled as **Position Independent Code (PIC)**, making it more versatile.
###### MSVC & Rust 2024 - v.0.1.2
The latest release of **RustiveDump** introduces support for **Position Independent Code (PIC)** compilation using the **MSVC toolchain**, along with updates to the **Rust 2024 edition**.
## **Key Features**
1. **NT System Calls for Everything**:
RustiveDump bypasses standard APIs and leverages NT system calls for all its operations.
2. **No-Std and CRT-Independent**:
RustiveDump is built using Rust's `no_std` feature, which removes reliance on Rust's standard library, and it's also **CRT library independent**. This resulting in a lean release build of only **18KB**.
3. **Position Independent Code (PIC)**:
1. **Position Independent Code (PIC)**:
RustiveDump now implements the design of Rustic64, allowing it to be compiled as `shellcode (PIC)`, making it more versatile.
4. **Indirect NT Syscalls**:
2. **Cross-Compilation Support**:
RustiveDump now supports both **GNU** and **MSVC** targets, enabling cross-compilation and compatibility across different environments.
3. **NT System Calls for Everything**:
RustiveDump bypasses standard APIs and leverages NT system calls for all its operations.
4. **No-Std and CRT-Independent**:
RustiveDump is built using Rust's `no_std` feature, which removes reliance on Rust's standard library, and it's also **CRT library independent**. This resulting in a lean release build of only **18KB**.
5. **Indirect NT Syscalls**:
The tool uses indirect syscalls, retrieving system service numbers (SSN) with techniques like **Hells Gate**, **Halo's Gate**, and **Tartarus' Gate**.
5. **Lean Memory Dump**:
6. **Lean Memory Dump**:
RustiveDump generates a focused memory dump, containing only essential data (i.e., **SystemInfo**, **ModuleList**, and **Memory64List**), ensuring no bloated files—just enough to feed your memory analysis tools like **Mimikatz** or **Pypykatz**.
6. **XOR Encryption**:
7. **XOR Encryption**:
RustiveDump can encrypt the dump file using XOR before saving or transmitting it, adding an extra layer of security to the dumped memory.
7. **Remote File Transmission**:
8. **Remote File Transmission**:
The dump file can be sent directly to a remote server using **winsock** APIs calls
8. **Debug Mode**:
9. **Debug Mode**:
The debug mode provides detailed logs of each step, which can be enabled during the build process.
## **How it works**
@@ -72,15 +79,22 @@ To build RustiveDump with different combinations of features, use the following
cargo make
```
- **Build with specific features**
- **Build as Portable Executable (PE) with specific features**
```bash
cargo make --env FEATURES=xor,remote,lsasrv,debug
```
- **Build as Shellcode (PIC)**
- **Build as Shellcode (PIC) for GNU target**
```bash
cargo make --env FEATURES=xor,remote pic
cargo make --env FEATURES=xor,remote pic-gnu
```
- **Build as Shellcode (PIC) for MSVC target**
```bash
cargo make --env FEATURES=xor,remote pic-msvc
```
## **Memory Dump File Structure**
@@ -107,4 +121,6 @@ Always follow ethical guidelines and legal frameworks when doing security resear
Contributions are welcome! If you want to help improve RustiveDump or report bugs, feel free to open an issue or a pull request in the repository.
---
## Changelog
See the full list of changes in the [Changelog](./CHANGELOG.md).
+8 -5
View File
@@ -8,7 +8,7 @@
///
/// # Returns
/// A pointer to the memory area `s`.
#[no_mangle]
#[unsafe(no_mangle)]
pub extern "C" fn memset(s: *mut u8, c: i32, n: usize) -> *mut u8 {
for i in 0..n {
unsafe { *s.add(i) = c as u8 };
@@ -26,7 +26,7 @@ pub extern "C" fn memset(s: *mut u8, c: i32, n: usize) -> *mut u8 {
///
/// # Returns
/// A pointer to the destination `dest`.
#[no_mangle]
#[unsafe(no_mangle)]
pub extern "C" fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 {
for i in 0..n {
unsafe {
@@ -46,7 +46,7 @@ pub extern "C" fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 {
///
/// # Returns
/// A pointer to the destination `dest`.
#[no_mangle]
#[unsafe(no_mangle)]
pub extern "C" fn memmove(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 {
if src < dest as *const u8 {
for i in (0..n).rev() {
@@ -74,7 +74,7 @@ pub extern "C" fn memmove(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 {
/// # Returns
/// An integer less than, equal to, or greater than zero if the first `n` bytes of `s1`
/// is found, respectively, to be less than, to match, or be greater than the first `n` bytes of `s2`.
#[no_mangle]
#[unsafe(no_mangle)]
pub extern "C" fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 {
for i in 0..n {
let a = unsafe { *s1.add(i) };
@@ -93,7 +93,7 @@ pub extern "C" fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 {
///
/// # Returns
/// The number of bytes in the string pointed to by `s`, excluding the terminating null byte.
#[no_mangle]
#[unsafe(no_mangle)]
pub extern "C" fn strlen(s: *const u8) -> usize {
let mut count = 0;
unsafe {
@@ -103,3 +103,6 @@ pub extern "C" fn strlen(s: *const u8) -> usize {
}
count
}
#[unsafe(no_mangle)]
pub extern "C" fn __chkstk() {}
+1
View File
@@ -1,5 +1,6 @@
#![no_std]
#![no_main]
#![allow(unsafe_op_in_unsafe_fn)]
extern crate alloc;
extern crate panic_halt;
+1 -1
View File
@@ -1,4 +1,4 @@
extern "C" {
unsafe extern "C" {
// Declaration of an external syscall function with a variadic argument list
pub fn isyscall(ssn: u16, addr: usize, n_args: u32, ...) -> i32;
}
+2 -2
View File
@@ -12,7 +12,7 @@ use crate::debug::k32::init_kernel32_funcs;
#[cfg(feature = "remote")]
use crate::remote::winsock::init_winsock_funcs;
#[no_mangle]
#[unsafe(no_mangle)]
pub extern "C" fn initialize() {
unsafe {
// Stack allocation of Instance
@@ -103,7 +103,7 @@ skip:
"#
);
extern "C" {
unsafe extern "C" {
pub fn _start();
}