https://github.com/vswarte/broadsword
All the shit I didn't want to write twice
https://github.com/vswarte/broadsword
game-hacking memory-hacking
Last synced: 3 months ago
JSON representation
All the shit I didn't want to write twice
- Host: GitHub
- URL: https://github.com/vswarte/broadsword
- Owner: vswarte
- Created: 2023-02-13T07:59:24.000Z (about 3 years ago)
- Default Branch: master
- Last Pushed: 2024-04-04T03:44:04.000Z (about 2 years ago)
- Last Synced: 2024-04-05T01:27:19.584Z (about 2 years ago)
- Topics: game-hacking, memory-hacking
- Language: Rust
- Homepage:
- Size: 2.12 MB
- Stars: 2
- Watchers: 2
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Broadsword
A set of shitty memory hacking tools.
**What does this do?**
I wrote it to do some heavy lifting around common tasks like logging vftables and finding
byte signatures in process memory.
**How do I use this?**
You want to include this in a DLL that is then injected into a process (like a game or Excel). Then you can
utilize the function below to do whatever makes your edits to a process tick.
## DLL bootstrapping
Small macro to generate the DllMain. It automatically guards against invokes from thread creation and such:
```rust
use broadsword::dll;
#[dll::entrypoint]
pub fn entry(module_base: usize) -> bool {
// Usual DllMain DLL_PROCESS_ATTACH stuff
}
```
## Scanner
### Single-threaded scans
Example:
```rust
use broadsword::scanner::Pattern;
use broadsword::scanner::simple::scan;
let pattern = Pattern::from_pattern_str("B7 [?? CF D8 ??] 0A ?? 27").unwrap();
// Scannable is a &'static [u8] in which the pattern will be matched
let result = scan(scannable, &pattern).unwrap();
```
### Multi-threaded scans
Splits up the search array into N chunks, where N is the amount of available parallelism. It runs a simple scanner
per thread on the chunk assigned to the thread.
#### Default (automatic thread count)
Example:
```rust
use broadsword::scanner::Pattern;
use broadsword::scanner::threaded::scan;
let pattern = Pattern::from_pattern_str("B7 [?? CF D8 ??] 0A ?? 27").unwrap();
let result = scan(scannable, &pattern, None);
```
#### Manual thread count
Example:
```rust
use broadsword::scanner::Pattern;
use broadsword::scanner::threaded::scan;
let pattern = Pattern::from_pattern_str("B7 [?? CF D8 ??] 0A ?? 27").unwrap();
let result = scan(scannable, &pattern, Some(4));
```
### Multiple matches
You can also use the scanners to match all occurrences of a pattern:
```rust
use broadsword::scanner::Pattern;
use broadsword::scanner::simple::scan_all as simple_scan_all;
use broadsword::scanner::threaded::scan_all as threaded_scan_all;
let pattern = Pattern::from_pattern_str("B7 [?? CF D8 ??] 0A ?? 27").unwrap();
let simple_result = simple_scan_all(scannable, &pattern);
let threaded_result = threaded_scan_all(scannable, &pattern, None);
```
### Captures
Both scanners also have the ability of capturing bytes from the occurrences by using the `[00 00 00 00]` notation where
the square brackets indicate what should be captured.
```rust
use broadsword::scanner::Pattern;
use broadsword::scanner::threaded::scan;
let pattern = Pattern::from_pattern_str("B7 [?? CF D8 ??] 0A ?? 27").unwrap();
let result = scan(scannable, &pattern, Some(4));
assert_eq!(result.captures[0].location, 867777);
assert_eq!(result.captures[0].bytes, vec![0xc6, 0xcf, 0xd8, 0x11]);
```
## Windows Modules
### Finding a module
`get_module_handle` gives us the base for a module based on the module name.
```rust
use broadsword::runtime::get_module_handle;
let game_base: usize = get_module_handle("eldenring.exe");
```
### Finding a symbol in a module
`get_module_symbol` finds a function by examining the IAT.
```rust
use broadsword::runtime::get_module_symbol;
let create_file_w_ptr: usize = get_module_symbol("kernel32", "CreateFileW");
```
### Finding the module a pointer belongs to
`get_module_symbol` finds a function by examining the IAT.
```rust
use broadsword::runtime::Module;
use broadsword::runtime::get_module_pointer_belongs_to;
let some_module: Module = get_module_pointer_belongs_to(0x123456).unwrap();
let module_name: String = some_module.name;
let module_memory_range: Range = some_module.memory_range;
```
### Finding the range of a section within a module
`get_module_symbol` finds a function by examining the section table.
```rust
use broadsword::runtime::Module;
use broadsword::runtime::get_module_section_range;
let range: Range = get_module_section_range("eldenring.exe", ".text").unwrap();
```
## RTTI
### Instance class names
We use `get_rtti_instance_classname` to retrieve the RTTI classname from a class instance.
```rust
use broadsword::runtime::get_rtti_instance_classname;
let ptr: usize = 0x123456;
let class_name: Option = get_rtti_instance_classname(ptr);
```
### Vftable class names
`get_rtti_classname` will give use the name too, but it expects the vftable pointer directly
instead of a pointer to a class instance.
```rust
use broadsword::runtime::get_rtti_classname;
let ptr: usize = 0x123456;
let class_name: Option = get_rtti_classname(ptr);
```